Skip to content

Commit

Permalink
🔢 Add enumeration options to common directives (#1477)
Browse files Browse the repository at this point in the history
Co-authored-by: Angus Hollands <[email protected]>
  • Loading branch information
rowanc1 and agoose77 authored Aug 22, 2024
1 parent da224b7 commit 88396dd
Show file tree
Hide file tree
Showing 18 changed files with 164 additions and 133 deletions.
8 changes: 8 additions & 0 deletions .changeset/seven-dogs-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"myst-directives": patch
"myst-transforms": patch
"myst-parser": patch
"mystmd": patch
---

Add enumerator and enumerated to directives
6 changes: 4 additions & 2 deletions docs/cross-references.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ Please see [this paragraph](#my-paragraph) and [these points](#my-points).

## Numbering

Frontmatter may specify `numbering` to customize how various components of the page are numbered. By default, numbering is enabled for figures, equations, tables, and code blocks; it is disabled for headings and other content types contained on the page.

Frontmatter may specify `numbering` to customize how various components of the page are numbered. By default, numbering is enabled for figures, equations, tables, math, and code blocks; it is disabled for headings and other content types contained on the page.
To enable numbering of all content, you may simply use:

```yaml
Expand All @@ -334,6 +333,7 @@ The `numbering` object allows you to be much more granular with enabling and dis
```yaml
numbering:
code: false
math: false
headings: true
```

Expand Down Expand Up @@ -371,3 +371,5 @@ Finally, under the `numbering` object, you may specify `enumerator`. For now, th
numbering:
enumerator: A1.%s
```

If you want to control the numbering for a specific figure, you can use the {myst:directive}`figure.enumerator` option. This will give the figure a specific enumerator, and will not increment the counting for other figures. This is helpful if you want to explicitly count figure `2a` and then carry on counting figures as normal; alternatively you can take control of numbering entirely by setting {myst:directive}`figure.enumerator` on every figure.
16 changes: 9 additions & 7 deletions docs/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,17 @@ If you are using Jupyter Book or Sphinx, there are the following limitations:
```
`````

### Disabling Numbering
## Customizing Numbering

TODO!
To change the reference format for math, you can use the frontmatter under the `numbering` field [see numbering](#numbering).
To override numbering for a specific equation you can use the {myst:directive}`math.enumerated` option on the math directive.

### Customizing Numbering

To change the reference format, you can use the frontmatter under the `xxx` field.

TODO!
```markdown
:::{math}
:enumerated: false
Ax = b
:::
```

(math-macros)=

Expand Down
7 changes: 3 additions & 4 deletions packages/myst-directives/src/admonition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Admonition } from 'myst-spec-ext';
import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common';
import { addCommonDirectiveOptions, commonDirectiveOptions } from './utils.js';

export const admonitionDirective: DirectiveSpec = {
name: 'admonition',
Expand All @@ -26,10 +27,7 @@ export const admonitionDirective: DirectiveSpec = {
doc: 'The optional title of the admonition, if not supplied the admonition kind will be used.\n\nNote that the argument parsing is different from Sphinx, which does not allow named admonitions to have custom titles.',
},
options: {
// label: {
// type: String,
// alias: ['name'],
// },
...commonDirectiveOptions('admonition'),
class: {
type: String,
doc: `CSS classes to add to your admonition. Special classes include:
Expand Down Expand Up @@ -77,6 +75,7 @@ export const admonitionDirective: DirectiveSpec = {
if (data.options?.icon === false) {
admonition.icon = false;
}
addCommonDirectiveOptions(data, admonition);
if (typeof data.options?.open === 'boolean') {
if (!admonition.class?.split(' ').includes('dropdown')) {
admonition.class = `${admonition.class ?? ''} dropdown`.trim();
Expand Down
12 changes: 4 additions & 8 deletions packages/myst-directives/src/aside.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common';
import type { Aside } from 'myst-spec-ext';
import type { FlowContent, ListContent, PhrasingContent } from 'myst-spec';
import { normalizeLabel } from 'myst-common';
import { addCommonDirectiveOptions, labelDirectiveOption } from './utils.js';

export const asideDirective: DirectiveSpec = {
name: 'aside',
Expand All @@ -11,10 +11,8 @@ export const asideDirective: DirectiveSpec = {
doc: 'An optional title',
},
options: {
label: {
type: String,
alias: ['name'],
},
...labelDirectiveOption('aside'),
// TODO: Add enumeration in future
class: {
type: String,
},
Expand All @@ -24,7 +22,6 @@ export const asideDirective: DirectiveSpec = {
required: true,
},
run(data: DirectiveData): GenericNode[] {
const { label, identifier } = normalizeLabel(data.options?.label as string | undefined) || {};
const children = [...(data.body as unknown as (FlowContent | ListContent | PhrasingContent)[])];
if (data.arg) {
children.unshift({
Expand All @@ -38,9 +35,8 @@ export const asideDirective: DirectiveSpec = {
data.name == 'aside' || data.name == 'margin' ? undefined : (data.name as Aside['kind']),
children,
class: data.options?.class as string | undefined,
label,
identifier,
};
addCommonDirectiveOptions(data, aside);
return [aside];
},
};
13 changes: 5 additions & 8 deletions packages/myst-directives/src/blockquote.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common';
import { normalizeLabel } from 'myst-common';
import type { Container } from 'myst-spec-ext';
import classNames from 'classnames';
import { addCommonDirectiveOptions, labelDirectiveOption } from './utils.js';

export const blockquoteDirective: DirectiveSpec = {
name: 'blockquote',
alias: ['epigraph', 'pull-quote'],
doc: 'Block quotes are used to indicate that the enclosed content forms an extended quotation. They may be followed by an inscription or attribution formed of a paragraph beginning with `--`, `---`, or an em-dash.',
options: {
label: {
type: String,
alias: ['name'],
},
...labelDirectiveOption('blockquote'),

// TODO: Add enumeration in future
class: {
type: String,
doc: `CSS classes to add to your blockquote. Special classes include:
Expand All @@ -29,13 +28,10 @@ export const blockquoteDirective: DirectiveSpec = {
if (data.body) {
children.push(...(data.body as GenericNode[]));
}
const { label, identifier } = normalizeLabel(data.options?.label as string | undefined) || {};
const className = data.options?.class as string;
const container: Container = {
type: 'container',
kind: 'quote',
label,
identifier,
class: classNames({ [className]: className, [data.name]: data.name !== 'blockquote' }),
children: [
{
Expand All @@ -45,6 +41,7 @@ export const blockquoteDirective: DirectiveSpec = {
},
],
};
addCommonDirectiveOptions(data, container);
return [container];
},
};
24 changes: 7 additions & 17 deletions packages/myst-directives/src/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import type { Code } from 'myst-spec-ext';
import { nanoid } from 'nanoid';
import yaml from 'js-yaml';
import type { DirectiveData, DirectiveSpec, GenericNode } from 'myst-common';
import { fileError, fileWarn, normalizeLabel, NotebookCell, RuleId } from 'myst-common';
import { fileError, fileWarn, NotebookCell, RuleId } from 'myst-common';
import type { VFile } from 'vfile';
import { select } from 'unist-util-select';
import { addCommonDirectiveOptions, commonDirectiveOptions } from './utils.js';

function parseEmphasizeLines(emphasizeLinesString?: string | undefined): number[] | undefined {
if (!emphasizeLinesString) return undefined;
Expand Down Expand Up @@ -140,10 +141,7 @@ export const codeDirective: DirectiveSpec = {
doc: 'Code language, for example `python` or `typescript`',
},
options: {
label: {
type: String,
alias: ['name'],
},
...commonDirectiveOptions('code'),
class: {
type: String,
// class_option: list of strings?
Expand All @@ -155,7 +153,6 @@ export const codeDirective: DirectiveSpec = {
doc: 'The raw code to display for the code block.',
},
run(data, vfile): GenericNode[] {
const { label, identifier } = normalizeLabel(data.options?.label as string | undefined) || {};
const opts = getCodeBlockOptions(data, vfile);
const code: Code = {
type: 'code',
Expand All @@ -165,8 +162,7 @@ export const codeDirective: DirectiveSpec = {
value: data.body as string,
};
if (!data.options?.caption) {
code.label = label;
code.identifier = identifier;
addCommonDirectiveOptions(data, code);
return [code];
}
const caption: Caption = {
Expand All @@ -181,10 +177,9 @@ export const codeDirective: DirectiveSpec = {
const container: Container = {
type: 'container',
kind: 'code' as any,
label,
identifier,
children: [code as any, caption],
};
addCommonDirectiveOptions(data, container);
return [container];
},
};
Expand All @@ -197,10 +192,7 @@ export const codeCellDirective: DirectiveSpec = {
doc: 'Language for execution and display, for example `python`. It will default to the language of the notebook or containing markdown file.',
},
options: {
label: {
type: String,
alias: ['name'],
},
...commonDirectiveOptions('code-cell'),
tags: {
type: String,
alias: ['tag'],
Expand All @@ -212,7 +204,6 @@ export const codeCellDirective: DirectiveSpec = {
doc: 'The code to be executed and displayed.',
},
run(data, vfile): GenericNode[] {
const { label, identifier } = normalizeLabel(data.options?.label as string | undefined) || {};
const code: Code = {
type: 'code',
lang: data.arg as string,
Expand All @@ -227,11 +218,10 @@ export const codeCellDirective: DirectiveSpec = {
const block: GenericNode = {
type: 'block',
kind: NotebookCell.code,
label,
identifier,
children: [code, output],
data: {},
};
addCommonDirectiveOptions(data, block);

const tags = parseTags(data.options?.tags, vfile, data.node);
if (tags) block.data.tags = tags;
Expand Down
14 changes: 5 additions & 9 deletions packages/myst-directives/src/div.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common';
import type { FlowContent, ListContent, PhrasingContent } from 'myst-spec';
import { normalizeLabel } from 'myst-common';
import { addCommonDirectiveOptions, labelDirectiveOption } from './utils.js';

export const divDirective: DirectiveSpec = {
name: 'div',
options: {
label: {
type: String,
alias: ['name'],
},
...labelDirectiveOption('div'),
// TODO: Add enumeration in future
class: {
type: String,
},
Expand All @@ -18,14 +16,12 @@ export const divDirective: DirectiveSpec = {
required: true,
},
run(data: DirectiveData): GenericNode[] {
const { label, identifier } = normalizeLabel(data.options?.label as string | undefined) || {};
const div: GenericNode = {
type: 'div',
children: data.body as unknown as (FlowContent | ListContent | PhrasingContent)[],
class: data.options?.class as string | undefined,
label,
identifier,
children: data.body as unknown as (FlowContent | ListContent | PhrasingContent)[],
};
addCommonDirectiveOptions(data, div);
return [div];
},
};
17 changes: 10 additions & 7 deletions packages/myst-directives/src/dropdown.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { DirectiveSpec, DirectiveData, GenericNode } from 'myst-common';
import { addCommonDirectiveOptions, labelDirectiveOption } from './utils.js';

export const dropdownDirective: DirectiveSpec = {
name: 'dropdown',
arg: {
type: 'myst',
},
options: {
...labelDirectiveOption('dropdown'),
// TODO: Add enumeration in future
open: {
type: Boolean,
doc: 'When true, the dropdown starts open.',
Expand All @@ -30,12 +33,12 @@ export const dropdownDirective: DirectiveSpec = {
children.push({ type: 'summary', children: data.arg as GenericNode[] });
}
children.push(...(data.body as GenericNode[]));
return [
{
type: 'details',
open: data.options?.open,
children,
},
];
const details = {
type: 'details',
open: data.options?.open,
children,
};
addCommonDirectiveOptions(data, details);
return [details];
},
};
11 changes: 3 additions & 8 deletions packages/myst-directives/src/figure.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Image } from 'myst-spec-ext';
import type { DirectiveSpec, GenericNode, GenericParent } from 'myst-common';
import { normalizeLabel } from 'myst-common';
import { addCommonDirectiveOptions, commonDirectiveOptions } from './utils.js';

export const figureDirective: DirectiveSpec = {
name: 'figure',
Expand All @@ -9,10 +9,7 @@ export const figureDirective: DirectiveSpec = {
doc: 'The filename of an image (e.g. `my-fig.png`), or an ID of a Jupyter Notebook cell (e.g. `#my-cell`).',
},
options: {
label: {
type: String,
alias: ['name'],
},
...commonDirectiveOptions('figure'),
class: {
type: String,
alias: ['figclass'],
Expand Down Expand Up @@ -102,15 +99,13 @@ export const figureDirective: DirectiveSpec = {
if (data.body) {
children.push(...(data.body as GenericNode[]));
}
const { label, identifier } = normalizeLabel(data.options?.label as string | undefined) || {};
const container: GenericParent = {
type: 'container',
kind: (data.options?.kind as string) || 'figure',
identifier,
label,
class: data.options?.class,
children,
};
addCommonDirectiveOptions(data, container);
if (data.options?.['no-subfigures']) {
container.noSubcontainers = true;
}
Expand Down
Loading

0 comments on commit 88396dd

Please sign in to comment.