From 6df84ed259f12eaf07142206abdaafcbb60ab0dc Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 23 Jun 2023 16:37:48 -0600 Subject: [PATCH 1/2] =?UTF-8?q?=E2=A4=B5=EF=B8=8F=20Add=20{download}=20rol?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See executablebooks/jupyterlab-myst#158, #189 --- .changeset/five-numbers-invent.md | 6 ++++++ docs/cross-references.md | 20 +++++++++++--------- packages/myst-roles/src/download.ts | 25 +++++++++++++++++++++++++ packages/myst-roles/src/index.ts | 3 +++ 4 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 .changeset/five-numbers-invent.md create mode 100644 packages/myst-roles/src/download.ts diff --git a/.changeset/five-numbers-invent.md b/.changeset/five-numbers-invent.md new file mode 100644 index 000000000..72aeeeb32 --- /dev/null +++ b/.changeset/five-numbers-invent.md @@ -0,0 +1,6 @@ +--- +'myst-roles': patch +'myst-cli': patch +--- + +Add download role diff --git a/docs/cross-references.md b/docs/cross-references.md index b32e5b381..ff8b1d0af 100644 --- a/docs/cross-references.md +++ b/docs/cross-references.md @@ -76,19 +76,19 @@ Cross-referencing content is accomplished with markdown link syntax (`[text](#ta : Link to documents using relative links from the markdown. - [](./citations.md) * - `[](./_toc.yml)` - : Link to static files that will be included in your built website. + : Link to static files that will be included in your built website. Similar to the [{download}](#download-role) role. - [](./_toc.yml) ``` % TODO: absolute links -```{seealso} +:::{seealso} Using roles for referencing :class: dropdown -# Using roles for referencing -If is also possible to use specific roles to reference content, including ([ref](#ref-role), [numref](#numref-role), [eq](#eq-role) or [doc](#doc-role)), depending on your use-case. + +It is also possible to use specific roles to reference content, including ([ref](#ref-role), [numref](#numref-role), [eq](#eq-role) or [doc](#doc-role)), depending on your use-case. These roles are supported to have compatibility with Sphinx. However, it is recommended to use markdown link syntax for referencing content, as it is more portable, is more concise, and has improved features such as inline formatting in the text links. -``` +::: (targeting-headers)= @@ -233,14 +233,13 @@ Please see [this paragraph](#my-paragraph) and [these points](#my-points). ## Referencing using Roles -```{warning} -# Coming from Sphinx? +:::{warning} Coming from Sphinx? The following sections are to support users who are coming from using Sphinx as a parsing engine, which has many different ways to reference and label content. These ways of referencing content are not recommended, as they have certain drawbacks and are not consistent. See [{name}](#link-references) for ways to use markdown link, `[](#target)` syntax to reference your content. -``` +::: (ref-role)= @@ -263,4 +262,7 @@ eq doc : The `` {doc}`./my-file.md` `` syntax creates a link to the document, which is equivalent to `[](./my-file.md)`. -% TODO: mystjs - doc role (or just leave unhandled until we can do multi doc) +(download-role)= + +download +: The `` {download}`./my-file.zip` `` syntax creates a download to a document, which is equivalent to `[](./my-file.zip)`. diff --git a/packages/myst-roles/src/download.ts b/packages/myst-roles/src/download.ts new file mode 100644 index 000000000..2a1cfd4d2 --- /dev/null +++ b/packages/myst-roles/src/download.ts @@ -0,0 +1,25 @@ +import type { RoleSpec } from 'myst-common'; +import { ParseTypesEnum } from 'myst-common'; + +const REF_PATTERN = /^(.+?)<([^<>]+)>$/; // e.g. 'Labeled Download ' + +export const downloadRole: RoleSpec = { + name: 'download', + body: { + type: ParseTypesEnum.string, + required: true, + }, + run(data) { + const body = data.body as string; + const match = REF_PATTERN.exec(body); + const [, modified, rawLabel] = match ?? []; + const url = rawLabel ?? body; + return [ + { + type: 'link', + url, + children: modified ? [{ type: 'text', value: modified.trim() }] : undefined, + }, + ]; + }, +}; diff --git a/packages/myst-roles/src/index.ts b/packages/myst-roles/src/index.ts index 37c750ab2..f120e42fe 100644 --- a/packages/myst-roles/src/index.ts +++ b/packages/myst-roles/src/index.ts @@ -5,6 +5,7 @@ import { deleteRole } from './delete.js'; import { mathRole } from './math.js'; import { refRole } from './reference.js'; import { docRole } from './doc.js'; +import { downloadRole } from './download.js'; import { termRole } from './term.js'; import { siRole } from './si.js'; import { evalRole } from './inlineExpression.js'; @@ -21,6 +22,7 @@ export const defaultRoles = [ mathRole, refRole, docRole, + downloadRole, termRole, siRole, evalRole, @@ -36,6 +38,7 @@ export { deleteRole } from './delete.js'; export { mathRole } from './math.js'; export { refRole } from './reference.js'; export { docRole } from './doc.js'; +export { downloadRole } from './download.js'; export { termRole } from './term.js'; export { siRole } from './si.js'; export { smallcapsRole } from './smallcaps.js'; From 70cd8c0966b75ec6f47e970246721f5bc009d437 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Fri, 23 Jun 2023 16:46:05 -0600 Subject: [PATCH 2/2] Change to static link --- packages/myst-cli/src/transforms/links.ts | 1 + packages/myst-roles/src/download.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/myst-cli/src/transforms/links.ts b/packages/myst-cli/src/transforms/links.ts index 97fb79942..53ec322e2 100644 --- a/packages/myst-cli/src/transforms/links.ts +++ b/packages/myst-cli/src/transforms/links.ts @@ -117,6 +117,7 @@ export class StaticFileTransformer implements LinkTransformer { this.session = session; this.filePath = filePath; } + test(url?: string) { if (!url) return false; const linkFileWithTarget = fileFromRelativePath(url, this.filePath); diff --git a/packages/myst-roles/src/download.ts b/packages/myst-roles/src/download.ts index 2a1cfd4d2..f7fbad246 100644 --- a/packages/myst-roles/src/download.ts +++ b/packages/myst-roles/src/download.ts @@ -19,6 +19,7 @@ export const downloadRole: RoleSpec = { type: 'link', url, children: modified ? [{ type: 'text', value: modified.trim() }] : undefined, + static: true, // Indicate that this should be treated as a static download }, ]; },