Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃摉 Document roles #1019

Merged
merged 2 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/little-garlics-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"myst-common": patch
---

Add `doc` to the myst-role spec.
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ parts:
- file: commonmark
- file: syntax-overview
- file: directives
- file: roles
- file: frontmatter
- file: document-parts
- file: settings
Expand Down
2 changes: 1 addition & 1 deletion docs/directives.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Directives
description: Code and code-blocks can be used to show programming languages.
description: A full list of the directives included in MyST Markdown by default.
---

:::{myst:directive} admonition
Expand Down
72 changes: 70 additions & 2 deletions docs/directives.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { u } from 'unist-builder';
import { mystParse } from 'myst-parser';
import { defaultDirectives } from 'myst-directives';
import { defaultRoles } from 'myst-roles';
import { fileError } from 'myst-common';

/**
Expand Down Expand Up @@ -116,6 +117,49 @@ const mystDirective = {
},
};

/**
* Create a documentation section for a directive
*
* @type {import('myst-common').DirectiveSpec}
*/
const mystRole = {
name: 'myst:role',
arg: {
type: String,
required: true,
},
run(data, vfile) {
const name = data.arg;
const role = defaultRoles.find((d) => d.name === name);
if (!role) {
fileError(vfile, `myst:role: Unknown myst role "${name}"`);
return [];
}
const heading = u('heading', { depth: 2, identifier: `role-${name}` }, [
u('inlineCode', name),
u('text', ' role'),
]);
const doc = role.doc ? mystParse(role.doc).children : [];
let alias = [];
if (role.alias && role.alias.length > 0) {
alias = [
u('paragraph', [
u('strong', [u('text', 'Alias')]),
u('text', ': '),
...role.alias
.map((a, i) => {
const c = [u('inlineCode', a)];
if (i < role.alias.length - 1) c.push(u('text', ', '));
return c;
})
.flat(),
]),
];
}
return [heading, u('div', [...doc, ...alias])];
},
};

const REF_PATTERN = /^(.+?)<([^<>]+)>$/; // e.g. 'Labeled Reference <ref>'

/**
Expand Down Expand Up @@ -144,15 +188,39 @@ const mystDirectiveRole = {
},
};

/**
* Create a documentation section for a directive
*
* @type {import('myst-common').RoleSpec}
*/
const mystRoleRole = {
name: 'myst:role',
body: {
type: String,
required: true,
},
run(data) {
const match = REF_PATTERN.exec(data.body);
const [, modified, rawLabel] = match ?? [];
const label = rawLabel ?? data.body;
const [name, opt] = label?.split('.') ?? [];
const role = defaultRoles.find((d) => d.name === name || d.alias?.includes(name));
const identifier = opt ? `role-${role?.name ?? name}-${opt}` : `role-${role?.name ?? name}`;
return [
u('crossReference', { identifier }, [u('inlineCode', modified?.trim() || opt || name)]),
];
},
};

/**
* @type {import('myst-common').MystPlugin}
*/
const plugin = {
name: 'MyST Documentation Plugins',
author: 'Rowan Cockett',
license: 'MIT',
directives: [mystDirective],
roles: [mystDirectiveRole],
directives: [mystDirective, mystRole],
roles: [mystDirectiveRole, mystRoleRole],
};

export default plugin;
52 changes: 52 additions & 0 deletions docs/roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Roles
description: A full list of the roles included in MyST Markdown by default.
---

:::{myst:role} abbreviation
:::

:::{myst:role} chemicalFormula
:::

:::{myst:role} cite
:::

:::{myst:role} delete
:::

:::{myst:role} math
:::

:::{myst:role} ref
:::

:::{myst:role} doc
:::

:::{myst:role} download
:::

:::{myst:role} term
:::

:::{myst:role} si
:::

:::{myst:role} eval
:::

:::{myst:role} smallcaps
:::

:::{myst:role} subscript
:::

:::{myst:role} superscript
:::

:::{myst:role} underline
:::

:::{myst:role} keyboard
:::
14 changes: 6 additions & 8 deletions docs/typography.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,35 +81,33 @@ You can use GitHub Flavoured Markdown to create task lists, these may be read on

For inline typography for subscript and superscript formatting, it is best practice to use a text-based representation over resorting to math exponents, i.e. `4$^{th}$`.
This is required in some journal submissions, and using these roles ensure that the output in HTML and $\LaTeX$ is correct.
The two roles for subscript and superscript are `sub` and `sup`[^long-names], respectively.
The two roles for subscript and superscript are {myst:role}`sub` and {myst:role}`sup`[^long-names], respectively.

```{myst}
H{sub}`2`O, and 4{sup}`th` of July
```

[^long-names]: These two roles are also accessible through `subscript` and `superscript`.
[^long-names]: These two roles are also accessible through {myst:role}`subscript` and {myst:role}`superscript`.

% For chemicals you can use the {chem}`H2O`

(keyboard-input)=

## Keyboard Input

To denote textual _user_ input from a keyboard, such as {kbd}`Ctrl` + {kbd}`Space`, you can use the `kbd`[^long-names-kbd] role, e.g.
To denote textual _user_ input from a keyboard, such as {kbd}`Ctrl` + {kbd}`Space`, you can use the {myst:role}`kbd` role[^long-names-kbd].

[^long-names-kbd]: This role is also accessible through {myst:role}`keyboard`.

```{myst}
{kbd}`Ctrl` + {kbd}`Space`
```

[^long-names-kbd]: This role is also accessible through `keyboard`.



(abbr-role)=

## Abbreviations

To create an abbreviation, you can use the `abbr` role, in HTML this will ensure that the title of the acronym or abbreviation appears in the title when you hover over the element. In the role, follow the syntax `HR (Heart Rate)` with the abbreviation first followed by the expanded title in parenthesis.
To create an abbreviation, you can use the {myst:role}`abbr` role, in HTML this will ensure that the title of the acronym or abbreviation appears in the title when you hover over the element. In the role, follow the syntax `HR (Heart Rate)` with the abbreviation first followed by the expanded title in parenthesis.

```{myst}
Well {abbr}`MyST (Markedly Structured Text)` is cool!
Expand Down
1 change: 1 addition & 0 deletions packages/myst-common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export type DirectiveSpec = {
export type RoleSpec = {
name: string;
alias?: string[];
doc?: string;
body?: BodyDefinition;
validate?: (data: RoleData, vfile: VFile) => RoleData;
run: (data: RoleData, vfile: VFile) => GenericNode[];
Expand Down
2 changes: 2 additions & 0 deletions packages/myst-directives/src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import type { Embed } from 'myst-spec-ext';

export const embedDirective: DirectiveSpec = {
name: 'embed',
doc: 'The embed directive allows you to duplicate content from another part of your project. This can also be done through the figure directive.',
arg: {
type: String,
doc: 'The label of the node that you are embedding.',
required: true,
},
options: {
Expand Down
1 change: 1 addition & 0 deletions packages/myst-roles/src/keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { GenericNode, RoleSpec } from 'myst-common';

export const keyboardRole: RoleSpec = {
name: 'keyboard',
doc: 'The keyboard role denote textual user input from a keyboard, such as "Ctrl" + "Space".',
alias: ['kbd'],
body: {
type: String,
Expand Down