diff --git a/README.md b/README.md index f9e8c0d..1cf8fb2 100644 --- a/README.md +++ b/README.md @@ -97,9 +97,11 @@ All directives have a fallback renderer, but the the following are specifically - Tables: - `list-table` - HTML: - - `sub`: Subscript - - `sup`: Superscript - - `abbr`: Abbreviation + - `sub`: Subscript + - `sup`: Superscript + - `abbr`: Abbreviation +- Other: + - `math` ## CSS Styling diff --git a/docs/index.html b/docs/index.html index 3b8ea89..78cacfe 100644 --- a/docs/index.html +++ b/docs/index.html @@ -98,6 +98,13 @@

markdown-it-docutils

* H{sub}`2`O * 4{sup}`th` of July * {abbr}`CSS (Cascading Style Sheets)` + +Math: + +```{math} +:label: math_label +w_{t+1} = (1 + r_{t+1}) s(w_t) + y_{t+1} +```
diff --git a/src/directives/admonitions.ts b/src/directives/admonitions.ts index aae001a..825e632 100644 --- a/src/directives/admonitions.ts +++ b/src/directives/admonitions.ts @@ -18,7 +18,7 @@ class BaseAdmonition extends Directive { name: unchanged } public title = "" - run(data: IDirectiveData): Token[] { + run(data: IDirectiveData): Token[] { const newTokens: Token[] = [] // we create an overall container, then individual containers for the title and body diff --git a/src/directives/code.ts b/src/directives/code.ts index d3672b1..8195b6c 100644 --- a/src/directives/code.ts +++ b/src/directives/code.ts @@ -29,7 +29,7 @@ export class Code extends Directive { name: unchanged, class: class_option } - run(data: IDirectiveData): Token[] { + run(data: IDirectiveData): Token[] { // TODO handle options this.assert_has_content(data) const token = this.createToken("fence", "code", 0, { @@ -68,7 +68,7 @@ export class CodeBlock extends Directive { name: unchanged, class: class_option } - run(data: IDirectiveData): Token[] { + run(data: IDirectiveData): Token[] { // TODO handle options this.assert_has_content(data) const token = this.createToken("fence", "code", 0, { @@ -89,7 +89,7 @@ export class CodeCell extends Directive { public has_content = true public rawOptions = true - run(data: IDirectiveData): Token[] { + run(data: IDirectiveData): Token[] { // TODO store options and the fact that this is a code cell rather than a fence? const token = this.createToken("fence", "code", 0, { info: data.args ? data.args[0] : "", diff --git a/src/directives/images.ts b/src/directives/images.ts index a914966..c07f851 100644 --- a/src/directives/images.ts +++ b/src/directives/images.ts @@ -38,7 +38,7 @@ export class Image extends Directive { ...shared_option_spec, align: create_choice(["left", "center", "right", "top", "middle", "bottom"]) } - create_image(data: IDirectiveData): Token { + create_image(data: IDirectiveData): Token { // get URI const src = uri(data.args[0] || "") @@ -89,7 +89,7 @@ export class Figure extends Image { figclass: class_option } public has_content = true - run(data: IDirectiveData): Token[] { + run(data: IDirectiveData): Token[] { const openToken = this.createToken("figure_open", "figure", 1, { map: data.map }) if (data.options.figclass) { openToken.attrJoin("class", data.options.figclass.join(" ")) diff --git a/src/directives/main.ts b/src/directives/main.ts index 837a297..59d5076 100644 --- a/src/directives/main.ts +++ b/src/directives/main.ts @@ -65,9 +65,7 @@ export interface IDirectiveSpec { /** if body content is allowed */ has_content?: boolean /** mapping known option names to conversion functions */ - option_spec?: { - [key: string]: OptionSpecConverter - } + option_spec?: Record /** If true, do not attempt to validate/convert options. */ rawOptions?: boolean } @@ -153,10 +151,10 @@ export class Directive implements IDirectiveSpec { } /** Data structure of a directive */ -export interface IDirectiveData { +export interface IDirectiveData { map: [number, number] args: string[] - options: { [key: string]: any } + options: Record body: string bodyMap: [number, number] } diff --git a/src/directives/math.ts b/src/directives/math.ts new file mode 100644 index 0000000..b573a6c --- /dev/null +++ b/src/directives/math.ts @@ -0,0 +1,35 @@ +/** Admonitions to visualise programming codes */ +import type Token from "markdown-it/lib/token" +import { Directive, IDirectiveData } from "./main" +import { unchanged } from "./options" + +/** Math directive with a label + */ +export class Math extends Directive { + public required_arguments = 0 + public optional_arguments = 0 + public final_argument_whitespace = false + public has_content = true + public option_spec = { + label: unchanged + } + run(data: IDirectiveData): Token[] { + // TODO handle options + this.assert_has_content(data) + const token = this.createToken("math_block", "div", 0, { + content: data.body, + map: data.bodyMap, + block: true + }) + token.attrSet("class", "math block") + if (data.options.label) { + token.info = data.options.label + token.meta = { label: data.options.label, numbered: true } + } + return [token] + } +} + +export const math = { + math: Math +} diff --git a/src/index.ts b/src/index.ts index a5852c7..2c990f5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,8 @@ import { roles } from "./roles/main" import { html } from "./roles/html" import rolePlugin from "./roles/plugin" import type { IOptions as IRoleOptions } from "./roles/types" -import { math } from "./roles/math" +import { math as mathRole } from "./roles/math" +import { math as mathDirective } from "./directives/math" /** Allowed options for docutils plugin */ export interface IOptions extends IDirectiveOptions, IRoleOptions { @@ -22,8 +23,8 @@ const OptionDefaults: IOptions = { replaceFences: true, rolesAfter: "inline", directivesAfter: "block", - directives: { ...admonitions, ...images, ...code, ...tables }, - roles: { ...roles, ...html, ...math } + directives: { ...admonitions, ...images, ...code, ...tables, ...mathDirective }, + roles: { ...roles, ...html, ...mathRole } } /** diff --git a/tests/fixtures/directives.math.md b/tests/fixtures/directives.math.md new file mode 100644 index 0000000..1ed0fe1 --- /dev/null +++ b/tests/fixtures/directives.math.md @@ -0,0 +1,23 @@ +math directive +. +```{math} +w_{t+1} = (1 + r_{t+1}) s(w_t) + y_{t+1} +``` +. +
+w_{t+1} = (1 + r_{t+1}) s(w_t) + y_{t+1} +
+. + +math directive with label +. +```{math} +:label: my_label +w_{t+1} = (1 + r_{t+1}) s(w_t) + y_{t+1} +``` +. +
+w_{t+1} = (1 + r_{t+1}) s(w_t) + y_{t+1} +
+. +