Skip to content

Commit dd96a30

Browse files
committed
fix counts
1 parent 2e3cbed commit dd96a30

File tree

16 files changed

+562
-105
lines changed

16 files changed

+562
-105
lines changed

packages/processor/src/input-to-markdown/mdast-transforms/add-frontmatter.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ export function addFrontmatter(ctx: Context) {
4242
ctx.frontmatter['reference-location'];
4343
}
4444

45-
const { theorems } = ctx.frontmatter;
46-
const theoremsYaml = theoremsToFrontmatter(theorems);
45+
const theoremsYaml = theoremsToFrontmatter(ctx);
4746
if (Object.keys(theoremsYaml).length > 0) {
4847
toExport.theorems = theoremsYaml;
4948
}

packages/processor/src/markdown-to-mdx/context.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ export type Frontmatter = {
2828
date: string;
2929
author: Author | Author[];
3030
abstract: string;
31+
documentClass?: string;
32+
hasPart?: boolean;
3133
theorems: RefObjectsYaml;
3234
'reference-location': string;
3335
};
@@ -41,6 +43,8 @@ export type Context = {
4143
theorems: RefObjectsYaml;
4244
refMap: Record<string, Reference>;
4345
referenceLocation: string;
46+
documentClass?: string;
47+
hasPart?: boolean;
4448
};
4549
hasSideNotes: boolean;
4650
};

packages/processor/src/markdown-to-mdx/hast-transforms/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import { footNotesToSideNotes } from '../../plugins/footnotes/footnotes-to-siden
1212
import { replaceFootnoteRefDefs } from '../../plugins/footnotes/replace-ref-def';
1313
import { addDefaultAltText } from '../../plugins/images/default-image-alt';
1414
import { addMathsRefsAndCount } from '../../plugins/maths/add-maths-refs-and-count';
15+
import { mathTagToRefLabel } from '../../plugins/maths/math-tag-to-ref-label';
1516
import { missingMathsImageToSvg } from '../../plugins/missing-maths/missing-maths-img-to-svg';
16-
import atReferenceToLink from '../../plugins/refs-and-counts/at-reference-to-link';
17+
import { atReferenceToLink } from '../../plugins/refs-and-counts/at-reference-to-link';
1718
import { addCounts } from '../../plugins/refs-and-counts/hast-add-counts';
1819
import { Context } from '../context';
1920
import { Options } from '../options';
@@ -85,6 +86,7 @@ function createRehypeFragmentPlugins(
8586
// ],
8687

8788
// should be last
89+
[mathTagToRefLabel, ctx],
8890
[addCounts, ctx],
8991
[atReferenceToLink, ctx], // depends on addCounts
9092

packages/processor/src/markdown-to-mdx/mdast-transforms/extract-frontmatter.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Root } from 'mdast';
33
import { visit } from 'unist-util-visit';
44
import { parse } from 'yaml';
55

6+
import { createHeadingDepths } from '../../plugins/headings/heading-depths';
67
import {
78
RefObjectsYaml,
89
createDefaultObjectsYaml,
@@ -39,6 +40,15 @@ export function extractFrontmatter(ctx: Context) {
3940
if (fm.abstract) {
4041
ctx.frontmatter.abstract = fm.abstract;
4142
}
43+
44+
if (fm.documentClass) {
45+
ctx.frontmatter.documentClass = fm.documentClass;
46+
}
47+
48+
if (fm.hasPart) {
49+
ctx.frontmatter.hasPart = fm.hasPart;
50+
}
51+
4252
if (fm.theorems) {
4353
const { custom = [], ...theorems } = fm.theorems;
4454
const customObj = custom.reduce(
@@ -48,6 +58,21 @@ export function extractFrontmatter(ctx: Context) {
4858
},
4959
{},
5060
);
61+
62+
// convert section to heading in theorem.numberWithin
63+
const { documentClass, hasPart } = ctx.frontmatter;
64+
const depths = createHeadingDepths(documentClass, hasPart);
65+
Object.entries(ctx.frontmatter.theorems).forEach(
66+
([name, theorem]) => {
67+
if (!Array.isArray(theorem)) {
68+
if (theorem.numberWithin) {
69+
const thm = ctx.frontmatter.theorems[name];
70+
thm.numberWithin = depths[theorem.numberWithin];
71+
}
72+
}
73+
},
74+
);
75+
5176
ctx.frontmatter.theorems = merge(
5277
ctx.frontmatter.theorems,
5378
theorems || {},

packages/processor/src/plugins/headings/adjust-heading-depth.ts

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Root } from 'hast';
22
import { visit } from 'unist-util-visit';
33

44
import { Context } from '../../input-to-markdown/context';
5+
import { createHeadingDepths } from './heading-depths';
56

67
export function adjustHeadingDepth(ctx: Context) {
78
return (tree: Root) => {
@@ -31,16 +32,6 @@ export function adjustHeadingDepth(ctx: Context) {
3132
}
3233
}
3334
});
34-
35-
// swap sections to headings in theorem definitions
36-
Object.entries(ctx.frontmatter.theorems).forEach(([name, theorem]) => {
37-
if (!Array.isArray(theorem)) {
38-
if (theorem.numberWithin) {
39-
const thm = ctx.frontmatter.theorems[name];
40-
thm.numberWithin = ctx.sectionToHeading[theorem.numberWithin];
41-
}
42-
}
43-
});
4435
};
4536
}
4637

@@ -64,39 +55,3 @@ function hasPartHeading(tree: Root) {
6455
});
6556
return hasPart;
6657
}
67-
68-
function createHeadingDepths(
69-
documentClass: string,
70-
hasPart: boolean,
71-
): Context['sectionToHeading'] {
72-
if (['report', 'book'].includes(documentClass)) {
73-
if (hasPart) {
74-
return {
75-
title: 'h1',
76-
part: 'h2',
77-
chapter: 'h3',
78-
section: 'h4',
79-
subsection: 'h5',
80-
subsubsection: 'h6',
81-
};
82-
} else {
83-
return {
84-
title: 'h1',
85-
chapter: 'h2',
86-
section: 'h3',
87-
subsection: 'h4',
88-
subsubsection: 'h5',
89-
paragraph: 'h6',
90-
};
91-
}
92-
} else {
93-
return {
94-
title: 'h1',
95-
section: 'h2',
96-
subsection: 'h3',
97-
subsubsection: 'h4',
98-
paragraph: 'h5',
99-
subparagraph: 'h6',
100-
};
101-
}
102-
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Context } from '../../input-to-markdown/context';
2+
3+
export function createHeadingDepths(
4+
documentClass?: string,
5+
hasPart?: boolean,
6+
): Context['sectionToHeading'] {
7+
if (['report', 'book'].includes(documentClass || '')) {
8+
if (hasPart) {
9+
return {
10+
title: 'h1',
11+
part: 'h2',
12+
chapter: 'h3',
13+
section: 'h4',
14+
subsection: 'h5',
15+
subsubsection: 'h6',
16+
};
17+
} else {
18+
return {
19+
title: 'h1',
20+
chapter: 'h2',
21+
section: 'h3',
22+
subsection: 'h4',
23+
subsubsection: 'h5',
24+
paragraph: 'h6',
25+
};
26+
}
27+
} else {
28+
return {
29+
title: 'h1',
30+
section: 'h2',
31+
subsection: 'h3',
32+
subsubsection: 'h4',
33+
paragraph: 'h5',
34+
subparagraph: 'h6',
35+
};
36+
}
37+
}

packages/processor/src/plugins/maths/__test__/maths.test.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,82 @@ test('expand newcommand inside newcommand', async () => {
358358
// const quartoHtml = await markdownToQuartoHtml(markdown);
359359
// console.log(quartoHtml);
360360
});
361+
362+
test('maths equations with labels and tags', async () => {
363+
const latex = String.raw`
364+
\documentclass{article}
365+
\usepackage{amsmath}
366+
\usepackage[noabbrev, capitalise, nameinlink]{cleveref}
367+
\begin{document}
368+
369+
\begin{equation}\label{eq:einstein1}
370+
E=mc^2
371+
\end{equation}
372+
373+
Hello, \cref{eq:einstein1}.
374+
375+
\begin{equation}\label{eq:einstein2}
376+
E=mc^2\tag{hello $E$}
377+
\end{equation}
378+
379+
Hello, \cref{eq:einstein2}.
380+
381+
\begin{equation}\label{eq:einstein3}
382+
E=mc^2
383+
\end{equation}
384+
385+
Hello, \cref{eq:einstein3}.
386+
387+
\end{document}
388+
`;
389+
390+
const markdown = await testProcessor.latex(latex);
391+
// console.log(markdown);
392+
393+
const expectedMarkdown = unindentStringAndTrim(String.raw`
394+
$$
395+
\begin{equation}E=mc^{2}\end{equation}
396+
$$ {#eq-einstein-1}
397+
398+
Hello, @eq-einstein-1.
399+
400+
$$
401+
\begin{equation}E=mc^{2}\tag{hello $E$}\end{equation}
402+
$$ {#eq-einstein-2}
403+
404+
Hello, @eq-einstein-2.
405+
406+
$$
407+
\begin{equation}E=mc^{2}\end{equation}
408+
$$ {#eq-einstein-3}
409+
410+
Hello, @eq-einstein-3.
411+
`);
412+
413+
expect(markdown).toBe(expectedMarkdown);
414+
415+
const html = await testProcessor.md(markdown, {
416+
// state: {
417+
// maths: {
418+
// mathsAsTex: false,
419+
// mathsFontName: 'computerModern',
420+
// syntaxHighlight: false,
421+
// },
422+
// },
423+
});
424+
// console.log(html);
425+
426+
const expectedHtml = unindentStringAndTrim(String.raw`
427+
<p id="eq-einstein-1" class="maths env-equation"><code class="latex">\begin{equation}E=mc^{2}\end{equation}</code><span class="eq-count">(1)</span></p>
428+
<p>Hello, <a href="#eq-einstein-1" class="ref">Equation 1</a>.</p>
429+
<p id="eq-einstein-2" class="maths env-equation"><code class="latex">\begin{equation}E=mc^{2}\end{equation}</code><span class="eq-count"><span class="eq-count">(hello <code class="latex">E</code>)</span></span></p>
430+
<p>Hello, <a href="#eq-einstein-2" class="ref">Equation (hello <code class="latex">E</code>)</a>.</p>
431+
<p id="eq-einstein-3" class="maths env-equation"><code class="latex">\begin{equation}E=mc^{2}\end{equation}</code><span class="eq-count">(2)</span></p>
432+
<p>Hello, <a href="#eq-einstein-3" class="ref">Equation 2</a>.</p>
433+
`);
434+
435+
expect(html).toBe(expectedHtml);
436+
437+
// const quartoHtml = await markdownToQuartoHtml(markdown);
438+
// console.log(quartoHtml);
439+
});

packages/processor/src/plugins/maths/equation-label-to-id.ts

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,47 @@ import { getArgsContent } from '@unified-latex/unified-latex-util-arguments';
33
import { visit } from '@unified-latex/unified-latex-util-visit';
44
import kebabCase from 'lodash.kebabcase';
55

6-
import { printRaw } from '../../../../../unified-latex-forks/unified-latex-util-print-raw/libs/print-raw';
6+
import { printRaw } from '@isos/unified-latex-util-print-raw';
77

88
export function equationLabelToId() {
99
return (tree: Ast.Root) => {
1010
visit(tree, (node) => {
1111
if (node.type === 'mathenv') {
1212
const env = (node.env || {}) as Ast.Node;
13-
const label = extractLabel(node);
13+
const id = extractMacro(node, 'label');
1414

1515
if (
1616
env.type === 'string' &&
1717
['equation', 'align'].includes(env.content)
1818
) {
19-
if (label) {
20-
Object.assign(node, {
21-
data: {
22-
id: extractLabelText(label),
23-
},
24-
});
19+
const data: Record<string, string> = {};
20+
if (id) {
21+
data.id = kebabCase(extractText(id));
2522
}
23+
Object.assign(node, { data });
2624
}
2725
}
2826
});
2927
};
3028
}
3129

32-
function extractLabel(mathEnv: Ast.Node): Ast.Macro | null {
33-
let label = null;
30+
function extractMacro(mathEnv: Ast.Node, name: string): Ast.Macro | null {
31+
let macro = null;
3432
visit(mathEnv, (node, info) => {
35-
if (node.type === 'macro' && node.content === 'label') {
36-
label = node;
33+
if (node.type === 'macro' && node.content === name) {
34+
macro = node;
3735

38-
// remove label
36+
// remove macro
3937
const parent = info.parents[0];
4038
if (parent && parent.type === 'mathenv') {
4139
parent.content.splice(info.index || 0, 1);
4240
}
4341
}
4442
});
45-
return label;
43+
return macro;
4644
}
4745

48-
function extractLabelText(label: Ast.Macro) {
49-
const args = getArgsContent(label);
50-
const text = printRaw(args[args.length - 1] || []).trim();
51-
return kebabCase(text);
46+
function extractText(macro: Ast.Macro) {
47+
const args = getArgsContent(macro);
48+
return printRaw(args[args.length - 1] || []).trim();
5249
}

packages/processor/src/plugins/maths/math-meta-to-id.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ export function mathMetaToId() {
1414
const attr = parseAttr(meta).prop;
1515

1616
if (attr) {
17+
const properties = {
18+
'data-id': attr.id,
19+
};
20+
1721
node.data = {
1822
...(node.data || {}),
1923
hProperties: {
2024
...(node.data?.hProperties || {}),
21-
'data-id': attr.id,
25+
...properties,
2226
},
2327
};
2428
}

0 commit comments

Comments
 (0)