From 3a85c9887c4a892266f29228fb5edb3457e852a7 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Sat, 25 May 2024 00:16:46 -0400 Subject: [PATCH 01/62] added math mode macro report function and test file --- .../libs/report-math-mode-macros.ts | 31 +++++++++++++++++++ .../tests/unified-latex-report-macro.test.ts | 24 ++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts create mode 100644 packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts diff --git a/packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts b/packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts new file mode 100644 index 00000000..8357f9dd --- /dev/null +++ b/packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts @@ -0,0 +1,31 @@ +import * as Ast from "@unified-latex/unified-latex-types"; +import {createMacroExpander, expandMacros } from "@unified-latex/unified-latex-util-macros" +import { anyMacro } from "@unified-latex/unified-latex-util-match"; +import { visit } from "@unified-latex/unified-latex-util-visit"; +import KATEX_SUPPORT_LIST from "./katex-support.json" + +// return list of unsupported macros? +export function parse_macros(ast: Ast.Ast): string[] { + let unsupported: string[]; + + // visit all nodes + visit(ast, (node, info) => { + // macro in math mode (need both?) + if (anyMacro(node) && (info.context.hasMathModeAncestor || info.context.inMathMode)) { + // check if user-defined + // *see if there are more user-defined commands + if (node.content === "newcommand" || node.content === "renewcommand") { + return; // For now + } + + // check if supported from katex + + } + }); +} + +// might not need this depending on macros package capabilities +export function expand_user_macros(node: Ast.Macro): { + +} + diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts new file mode 100644 index 00000000..2a61bba2 --- /dev/null +++ b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts @@ -0,0 +1,24 @@ +import { describe, it, expect } from "vitest"; +import Prettier from "prettier"; +import util from "util"; +import { getParser } from "@unified-latex/unified-latex-util-parse"; +import { parse_macros } from "../libs/report-math-mode-macros"; + +// Make console.log pretty-print by default +const origLog = console.log; +console.log = (...args) => { + origLog(...args.map((x) => util.inspect(x, false, 10, true))); +}; + +describe("unified-latex-to-pretext:unified-latex-report-macro", () => { + let value: string | undefined; + + it("can reported unsupported macros", () => { + value = String.raw`$\\mathbb{R} \\fakemacro{X}$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(parse_macros(ast)).toEqual(["fakemacro"]); + }); +}); From 0c1971a4ea200599937a31ce33d5e0df29c40d15 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Sun, 26 May 2024 00:19:08 -0400 Subject: [PATCH 02/62] updated report unsupported katex and expand command files --- .../libs/report-and-expand-macros.ts | 34 +++++++++++++++++++ .../libs/report-math-mode-macros.ts | 31 ----------------- .../tests/unified-latex-report-macro.test.ts | 10 +++--- 3 files changed, 39 insertions(+), 36 deletions(-) create mode 100644 packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts delete mode 100644 packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts diff --git a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts new file mode 100644 index 00000000..8efcf58c --- /dev/null +++ b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts @@ -0,0 +1,34 @@ +import * as Ast from "@unified-latex/unified-latex-types"; +import { newcommandMacroToSubstitutionAst } from "@unified-latex/unified-latex-util-macros/libs/newcommand"; +import { newcommandMatcher } from "@unified-latex/unified-latex-util-macros/libs/list-newcommands" +import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; +import { visit } from "@unified-latex/unified-latex-util-visit"; +import { katexSpecificMacroReplacements } from "./pre-conversion-subs/katex-subs"; + +// return list of unsupported macros? +export function report_macros(ast: Ast.Ast): string[] { + let unsupported: string[] = []; + + // match a macro supported by Katex + const isKatexMacro = match.createMacroMatcher(katexSpecificMacroReplacements); + + // visit all nodes + visit(ast, (node, info) => { + // macro in math mode + if (anyMacro(node) && info.context.hasMathModeAncestor) { + const macro_name = node.content; + + // check if not supported by katex + if (!isKatexMacro(node)) { + unsupported.push(macro_name); + } + } + }); + + return unsupported; +} + +export function expand_user_macros(node: Ast.Macro): Ast.Node[] { + return newcommandMacroToSubstitutionAst(node); +} + diff --git a/packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts b/packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts deleted file mode 100644 index 8357f9dd..00000000 --- a/packages/unified-latex-to-pretext/libs/report-math-mode-macros.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as Ast from "@unified-latex/unified-latex-types"; -import {createMacroExpander, expandMacros } from "@unified-latex/unified-latex-util-macros" -import { anyMacro } from "@unified-latex/unified-latex-util-match"; -import { visit } from "@unified-latex/unified-latex-util-visit"; -import KATEX_SUPPORT_LIST from "./katex-support.json" - -// return list of unsupported macros? -export function parse_macros(ast: Ast.Ast): string[] { - let unsupported: string[]; - - // visit all nodes - visit(ast, (node, info) => { - // macro in math mode (need both?) - if (anyMacro(node) && (info.context.hasMathModeAncestor || info.context.inMathMode)) { - // check if user-defined - // *see if there are more user-defined commands - if (node.content === "newcommand" || node.content === "renewcommand") { - return; // For now - } - - // check if supported from katex - - } - }); -} - -// might not need this depending on macros package capabilities -export function expand_user_macros(node: Ast.Macro): { - -} - diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts index 2a61bba2..71e67711 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import Prettier from "prettier"; import util from "util"; import { getParser } from "@unified-latex/unified-latex-util-parse"; -import { parse_macros } from "../libs/report-math-mode-macros"; +import { report_macros, expand_user_macros } from "../libs/report-and-expand-macros"; // Make console.log pretty-print by default const origLog = console.log; @@ -11,14 +11,14 @@ console.log = (...args) => { }; describe("unified-latex-to-pretext:unified-latex-report-macro", () => { - let value: string | undefined; + let value: string; it("can reported unsupported macros", () => { value = String.raw`$\\mathbb{R} \\fakemacro{X}$`; const parser = getParser(); const ast = parser.parse(value); - - expect(parse_macros(ast)).toEqual(["fakemacro"]); + + expect(report_macros(ast)).toEqual(["fakemacro"]); }); -}); +}); \ No newline at end of file From a140ea36b55246041438e55913e1c3985802ea7c Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Sun, 26 May 2024 19:30:00 -0400 Subject: [PATCH 03/62] added more tests to be implemented --- .../libs/report-and-expand-macros.ts | 2 +- .../tests/unified-latex-report-macro.test.ts | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts index 8efcf58c..5972c203 100644 --- a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts +++ b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts @@ -5,7 +5,7 @@ import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; import { katexSpecificMacroReplacements } from "./pre-conversion-subs/katex-subs"; -// return list of unsupported macros? +// return list of unsupported macros export function report_macros(ast: Ast.Ast): string[] { let unsupported: string[] = []; diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts index 71e67711..e9d0ba69 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts @@ -10,7 +10,7 @@ console.log = (...args) => { origLog(...args.map((x) => util.inspect(x, false, 10, true))); }; -describe("unified-latex-to-pretext:unified-latex-report-macro", () => { +describe("unified-latex-to-pretext:report-and-expand-macro", () => { let value: string; it("can reported unsupported macros", () => { @@ -21,4 +21,26 @@ describe("unified-latex-to-pretext:unified-latex-report-macro", () => { expect(report_macros(ast)).toEqual(["fakemacro"]); }); + + it("can report no unsupported macros", () => { + value = String.raw`$\\mathbb{R} \\frac{1}{2} \\cup$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(report_macros(ast)).toEqual([]); + }); + + it("can expand newcommand", () => { + // value = String.raw`\\newcommand{\\foo}{\\bar{#1}}`; + + // const parser = getParser(); + // const ast = parser.parse(value); + + // expect(expand_user_macros(ast)).toEqual([]); // want \bar{#1} + }); + + it("can expand renewcommand", () => { + + }); }); \ No newline at end of file From 575141def030003ea2a04fa6d96112057b52bf74 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Tue, 28 May 2024 00:04:41 -0400 Subject: [PATCH 04/62] implemented expand macros tests and function --- .../libs/report-and-expand-macros.ts | 30 ++++++-- .../tests/unified-latex-macro.test.ts | 76 +++++++++++++++++++ .../tests/unified-latex-report-macro.test.ts | 46 ----------- 3 files changed, 98 insertions(+), 54 deletions(-) create mode 100644 packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts delete mode 100644 packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts diff --git a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts index 5972c203..a5d83b88 100644 --- a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts +++ b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts @@ -1,25 +1,32 @@ import * as Ast from "@unified-latex/unified-latex-types"; -import { newcommandMacroToSubstitutionAst } from "@unified-latex/unified-latex-util-macros/libs/newcommand"; -import { newcommandMatcher } from "@unified-latex/unified-latex-util-macros/libs/list-newcommands" +import { newcommandMatcher,listNewcommands, newcommandMacroToSubstitutionAst, expandMacrosExcludingDefinitions, expandMacros } from "@unified-latex/unified-latex-util-macros"; import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; -import { katexSpecificMacroReplacements } from "./pre-conversion-subs/katex-subs"; +import { attachNeededRenderInfo, katexSpecificMacroReplacements, KATEX_SUPPORT } from "./pre-conversion-subs/katex-subs"; +import { attachMacroArgs } from "@unified-latex/unified-latex-util-arguments"; +import { replaceNode } from "@unified-latex/unified-latex-util-replace"; -// return list of unsupported macros +/** + * Return list of macros unsupported by Katex + */ export function report_macros(ast: Ast.Ast): string[] { let unsupported: string[] = []; + //attachNeededRenderInfo(ast); // match a macro supported by Katex - const isKatexMacro = match.createMacroMatcher(katexSpecificMacroReplacements); + // const isKatexMacro = match.createMacroMatcher(katexSpecificMacroReplacements); // visit all nodes visit(ast, (node, info) => { // macro in math mode if (anyMacro(node) && info.context.hasMathModeAncestor) { const macro_name = node.content; + //console.log(node); + //console.log(katexSpecificMacroReplacements[node.content]); // check if not supported by katex - if (!isKatexMacro(node)) { + // if (!isKatexMacro(node)) { + if (!KATEX_SUPPORT.macros.includes(macro_name)) { unsupported.push(macro_name); } } @@ -28,7 +35,14 @@ export function report_macros(ast: Ast.Ast): string[] { return unsupported; } -export function expand_user_macros(node: Ast.Macro): Ast.Node[] { - return newcommandMacroToSubstitutionAst(node); +/** + * Expands user-defined macros + */ +export function expand_user_macros(ast: Ast.Ast): void { + replaceNode(ast, (node) => { + if (anyMacro(node) && newcommandMatcher(node)) { + return newcommandMacroToSubstitutionAst(node); + } + }); } diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts new file mode 100644 index 00000000..e4d9461c --- /dev/null +++ b/packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts @@ -0,0 +1,76 @@ +import { describe, it, expect } from "vitest"; +import Prettier from "prettier"; +import util from "util"; +import { getParser } from "@unified-latex/unified-latex-util-parse"; +import { report_macros, expand_user_macros } from "../libs/report-and-expand-macros"; +import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; + +// Make console.log pretty-print by default +const origLog = console.log; +console.log = (...args) => { + origLog(...args.map((x) => util.inspect(x, false, 10, true))); +}; + +describe("unified-latex-to-pretext:report-and-expand-macro", () => { + let value: string; + + it("can reported unsupported macros", () => { + value = String.raw`$\mathbb{R} \fakemacro{X}$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(report_macros(ast)).toEqual(["fakemacro"]); + }); + + it("can report no unsupported macros in mathmode", () => { + value = String.raw`$\mathbb{R} \frac{1}{2} \cup$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(report_macros(ast)).toEqual([]); + }); + + it("can report no unsupported macros not in mathmode", () => { + value = String.raw`\underline{text} \textbf{bold} \subsection{section}`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(report_macros(ast)).toEqual([]); + }); + + it("can expand newcommand", () => { + value = String.raw`\newcommand{\foo}{\bar{#1}}`; + + const parser = getParser(); + const ast = parser.parse(value); + + expand_user_macros(ast) + + expect(printRaw(ast)).toEqual("\\bar{#1}"); + }); + + it("can expand renewcommand", () => { + value = String.raw`\renewcommand{\mathbb{N}}{\N}`; + + const parser = getParser(); + const ast = parser.parse(value); + + expand_user_macros(ast) + + expect(printRaw(ast)).toEqual("\\N"); + }); + + it("can expand multiple user-defined commands", () => { + value = String.raw`\newcommand{\join}{\vee} \renewcommand{\vee}{\foo}`; + + const parser = getParser(); + const ast = parser.parse(value); + + expand_user_macros(ast) + + expect(printRaw(ast)).toEqual("\\vee \\foo"); + }); +}); \ No newline at end of file diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts deleted file mode 100644 index e9d0ba69..00000000 --- a/packages/unified-latex-to-pretext/tests/unified-latex-report-macro.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { describe, it, expect } from "vitest"; -import Prettier from "prettier"; -import util from "util"; -import { getParser } from "@unified-latex/unified-latex-util-parse"; -import { report_macros, expand_user_macros } from "../libs/report-and-expand-macros"; - -// Make console.log pretty-print by default -const origLog = console.log; -console.log = (...args) => { - origLog(...args.map((x) => util.inspect(x, false, 10, true))); -}; - -describe("unified-latex-to-pretext:report-and-expand-macro", () => { - let value: string; - - it("can reported unsupported macros", () => { - value = String.raw`$\\mathbb{R} \\fakemacro{X}$`; - - const parser = getParser(); - const ast = parser.parse(value); - - expect(report_macros(ast)).toEqual(["fakemacro"]); - }); - - it("can report no unsupported macros", () => { - value = String.raw`$\\mathbb{R} \\frac{1}{2} \\cup$`; - - const parser = getParser(); - const ast = parser.parse(value); - - expect(report_macros(ast)).toEqual([]); - }); - - it("can expand newcommand", () => { - // value = String.raw`\\newcommand{\\foo}{\\bar{#1}}`; - - // const parser = getParser(); - // const ast = parser.parse(value); - - // expect(expand_user_macros(ast)).toEqual([]); // want \bar{#1} - }); - - it("can expand renewcommand", () => { - - }); -}); \ No newline at end of file From 27117651914aafacd8d66fb2ffa3c4fdd7ecc8ce Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Wed, 29 May 2024 13:40:59 -0400 Subject: [PATCH 05/62] formatted code --- .../libs/report-and-expand-macros.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts index a5d83b88..958cf16d 100644 --- a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts +++ b/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts @@ -1,9 +1,8 @@ import * as Ast from "@unified-latex/unified-latex-types"; -import { newcommandMatcher,listNewcommands, newcommandMacroToSubstitutionAst, expandMacrosExcludingDefinitions, expandMacros } from "@unified-latex/unified-latex-util-macros"; +import { newcommandMatcher, newcommandMacroToSubstitutionAst } from "@unified-latex/unified-latex-util-macros"; import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; -import { attachNeededRenderInfo, katexSpecificMacroReplacements, KATEX_SUPPORT } from "./pre-conversion-subs/katex-subs"; -import { attachMacroArgs } from "@unified-latex/unified-latex-util-arguments"; +import { KATEX_SUPPORT } from "./pre-conversion-subs/katex-subs"; import { replaceNode } from "@unified-latex/unified-latex-util-replace"; /** @@ -11,22 +10,18 @@ import { replaceNode } from "@unified-latex/unified-latex-util-replace"; */ export function report_macros(ast: Ast.Ast): string[] { let unsupported: string[] = []; - //attachNeededRenderInfo(ast); // match a macro supported by Katex - // const isKatexMacro = match.createMacroMatcher(katexSpecificMacroReplacements); + const isSupported = match.createMacroMatcher(KATEX_SUPPORT.macros); // visit all nodes visit(ast, (node, info) => { // macro in math mode if (anyMacro(node) && info.context.hasMathModeAncestor) { const macro_name = node.content; - //console.log(node); - //console.log(katexSpecificMacroReplacements[node.content]); // check if not supported by katex - // if (!isKatexMacro(node)) { - if (!KATEX_SUPPORT.macros.includes(macro_name)) { + if (!isSupported(node)) { unsupported.push(macro_name); } } @@ -38,11 +33,10 @@ export function report_macros(ast: Ast.Ast): string[] { /** * Expands user-defined macros */ -export function expand_user_macros(ast: Ast.Ast): void { +export function expand_user_macros(ast: Ast.Ast): void { replaceNode(ast, (node) => { if (anyMacro(node) && newcommandMatcher(node)) { return newcommandMacroToSubstitutionAst(node); } }); -} - +} \ No newline at end of file From a450ac12434367e4eb58045d94b3a89f82d4a0ba Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Wed, 29 May 2024 23:41:22 -0400 Subject: [PATCH 06/62] addressed some katex related comments --- .../libs/expand-user-defined-macros.ts | 18 ++++++++ ...s.ts => report-unsupported-macro-katex.ts} | 17 +------- ....ts => expand-user-defined-macros.test.ts} | 38 +++-------------- .../report-unsupported-macro-katex.test.ts | 42 +++++++++++++++++++ 4 files changed, 67 insertions(+), 48 deletions(-) create mode 100644 packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts rename packages/unified-latex-to-pretext/libs/{report-and-expand-macros.ts => report-unsupported-macro-katex.ts} (60%) rename packages/unified-latex-to-pretext/tests/{unified-latex-macro.test.ts => expand-user-defined-macros.test.ts} (54%) create mode 100644 packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts diff --git a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts new file mode 100644 index 00000000..33209cd6 --- /dev/null +++ b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts @@ -0,0 +1,18 @@ +import * as Ast from "@unified-latex/unified-latex-types"; +import { anyMacro } from "@unified-latex/unified-latex-util-match"; +import { replaceNode } from "@unified-latex/unified-latex-util-replace"; +import { + newcommandMatcher, + newcommandMacroToSubstitutionAst, +} from "@unified-latex/unified-latex-util-macros"; + +/** + * Expands user-defined macros + */ +export function ExpandUserDefinedMacros(ast: Ast.Ast): void { + replaceNode(ast, (node) => { + if (anyMacro(node) && newcommandMatcher(node)) { + return newcommandMacroToSubstitutionAst(node); + } + }); +} diff --git a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts b/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts similarity index 60% rename from packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts rename to packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts index 958cf16d..9db351c7 100644 --- a/packages/unified-latex-to-pretext/libs/report-and-expand-macros.ts +++ b/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts @@ -1,15 +1,13 @@ import * as Ast from "@unified-latex/unified-latex-types"; -import { newcommandMatcher, newcommandMacroToSubstitutionAst } from "@unified-latex/unified-latex-util-macros"; import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; import { KATEX_SUPPORT } from "./pre-conversion-subs/katex-subs"; -import { replaceNode } from "@unified-latex/unified-latex-util-replace"; /** * Return list of macros unsupported by Katex */ -export function report_macros(ast: Ast.Ast): string[] { - let unsupported: string[] = []; +export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): string[] { + const unsupported: string[] = []; // match a macro supported by Katex const isSupported = match.createMacroMatcher(KATEX_SUPPORT.macros); @@ -29,14 +27,3 @@ export function report_macros(ast: Ast.Ast): string[] { return unsupported; } - -/** - * Expands user-defined macros - */ -export function expand_user_macros(ast: Ast.Ast): void { - replaceNode(ast, (node) => { - if (anyMacro(node) && newcommandMatcher(node)) { - return newcommandMacroToSubstitutionAst(node); - } - }); -} \ No newline at end of file diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts similarity index 54% rename from packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts rename to packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index e4d9461c..dbe4411e 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-macro.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -1,9 +1,8 @@ import { describe, it, expect } from "vitest"; -import Prettier from "prettier"; import util from "util"; import { getParser } from "@unified-latex/unified-latex-util-parse"; -import { report_macros, expand_user_macros } from "../libs/report-and-expand-macros"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; +import { ExpandUserDefinedMacros } from "@unified-latex/unified-latex-to-pretext/libs/expand-user-defined-macros"; // Make console.log pretty-print by default const origLog = console.log; @@ -14,40 +13,13 @@ console.log = (...args) => { describe("unified-latex-to-pretext:report-and-expand-macro", () => { let value: string; - it("can reported unsupported macros", () => { - value = String.raw`$\mathbb{R} \fakemacro{X}$`; - - const parser = getParser(); - const ast = parser.parse(value); - - expect(report_macros(ast)).toEqual(["fakemacro"]); - }); - - it("can report no unsupported macros in mathmode", () => { - value = String.raw`$\mathbb{R} \frac{1}{2} \cup$`; - - const parser = getParser(); - const ast = parser.parse(value); - - expect(report_macros(ast)).toEqual([]); - }); - - it("can report no unsupported macros not in mathmode", () => { - value = String.raw`\underline{text} \textbf{bold} \subsection{section}`; - - const parser = getParser(); - const ast = parser.parse(value); - - expect(report_macros(ast)).toEqual([]); - }); - it("can expand newcommand", () => { value = String.raw`\newcommand{\foo}{\bar{#1}}`; const parser = getParser(); const ast = parser.parse(value); - expand_user_macros(ast) + ExpandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual("\\bar{#1}"); }); @@ -58,7 +30,7 @@ describe("unified-latex-to-pretext:report-and-expand-macro", () => { const parser = getParser(); const ast = parser.parse(value); - expand_user_macros(ast) + ExpandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual("\\N"); }); @@ -69,8 +41,8 @@ describe("unified-latex-to-pretext:report-and-expand-macro", () => { const parser = getParser(); const ast = parser.parse(value); - expand_user_macros(ast) + ExpandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual("\\vee \\foo"); }); -}); \ No newline at end of file +}); diff --git a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts new file mode 100644 index 00000000..d49a4f4e --- /dev/null +++ b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts @@ -0,0 +1,42 @@ +import { describe, it, expect } from "vitest"; +import util from "util"; +import { getParser } from "@unified-latex/unified-latex-util-parse"; +import { reportMacrosUnsupportedByKatex } from "@unified-latex/unified-latex-to-pretext/libs/report-unsupported-macro-katex"; + +// Make console.log pretty-print by default +const origLog = console.log; +console.log = (...args) => { + origLog(...args.map((x) => util.inspect(x, false, 10, true))); +}; + +describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { + let value: string; + + it("can reported unsupported macros", () => { + value = String.raw`$\mathbb{R} \fakemacro{X}$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["fakemacro"]); + }); + + it("can report no unsupported macros in mathmode", () => { + value = String.raw`$\mathbb{R} \frac{1}{2} \cup$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); + }); + + // change to Unsupported macros outside of math mode. + it("can report no unsupported macros not in mathmode", () => { + value = String.raw`\underline{text} \textbf{bold} \subsection{section}`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); + }); +}); From bd2f4d5346b60fced6f0bd5e960f96c01a59cbe6 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan Date: Fri, 31 May 2024 00:44:16 -0400 Subject: [PATCH 07/62] added more tests --- .../libs/expand-user-defined-macros.ts | 21 ++++++++++-------- .../tests/expand-user-defined-macros.test.ts | 22 +++++++++++++------ .../report-unsupported-macro-katex.test.ts | 14 +++++++++--- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts index 33209cd6..f95ac028 100644 --- a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts +++ b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts @@ -1,18 +1,21 @@ import * as Ast from "@unified-latex/unified-latex-types"; -import { anyMacro } from "@unified-latex/unified-latex-util-match"; -import { replaceNode } from "@unified-latex/unified-latex-util-replace"; import { - newcommandMatcher, - newcommandMacroToSubstitutionAst, + expandMacrosExcludingDefinitions, + listNewcommands, } from "@unified-latex/unified-latex-util-macros"; +import { attachMacroArgs } from "@unified-latex/unified-latex-util-arguments"; /** * Expands user-defined macros */ export function ExpandUserDefinedMacros(ast: Ast.Ast): void { - replaceNode(ast, (node) => { - if (anyMacro(node) && newcommandMatcher(node)) { - return newcommandMacroToSubstitutionAst(node); - } - }); + const newcommands = listNewcommands(ast); + + const macroInfo = Object.fromEntries( + newcommands.map((m) => [m.name, { signature: m.signature }]) + ); + + // attach the arguments to each macro before prcoessing it + attachMacroArgs(ast, macroInfo); + expandMacrosExcludingDefinitions(ast, newcommands); } diff --git a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index dbe4411e..35ff3dae 100644 --- a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -10,39 +10,47 @@ console.log = (...args) => { origLog(...args.map((x) => util.inspect(x, false, 10, true))); }; -describe("unified-latex-to-pretext:report-and-expand-macro", () => { +describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { let value: string; it("can expand newcommand", () => { - value = String.raw`\newcommand{\foo}{\bar{#1}}`; + value = String.raw`\newcommand{\foo}{\bar} \foo`; const parser = getParser(); const ast = parser.parse(value); ExpandUserDefinedMacros(ast); - expect(printRaw(ast)).toEqual("\\bar{#1}"); + expect(printRaw(ast)).toEqual(String.raw`\newcommand{\foo}{\bar} \bar`); }); it("can expand renewcommand", () => { - value = String.raw`\renewcommand{\mathbb{N}}{\N}`; + value = String.raw`\renewcommand{\N}{\mathbb{N}} \mathbb{N}`; // not subbing at all const parser = getParser(); const ast = parser.parse(value); ExpandUserDefinedMacros(ast); - expect(printRaw(ast)).toEqual("\\N"); + expect(printRaw(ast)).toEqual( + String.raw`\renewcommand{\N}{\mathbb{N}} \N` + ); }); it("can expand multiple user-defined commands", () => { - value = String.raw`\newcommand{\join}{\vee} \renewcommand{\vee}{\foo}`; + value = String.raw`\newcommand{\join}{\vee} + \join + \renewcommand{\vee}{\foo} + \join`; const parser = getParser(); const ast = parser.parse(value); ExpandUserDefinedMacros(ast); - expect(printRaw(ast)).toEqual("\\vee \\foo"); + expect(printRaw(ast)).toEqual(String.raw`\newcommand{\join}{\vee} + \vee + \renewcommand{\vee}{\foo} + \foo`); }); }); diff --git a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts index d49a4f4e..d4bcc545 100644 --- a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts +++ b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts @@ -30,13 +30,21 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); }); - // change to Unsupported macros outside of math mode. - it("can report no unsupported macros not in mathmode", () => { - value = String.raw`\underline{text} \textbf{bold} \subsection{section}`; + it("can not report any unsupported macros outside of math mode", () => { + value = String.raw`\fakemacro`; const parser = getParser(); const ast = parser.parse(value); expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); }); + + it("can report unsupported macros in text mode with a math anscestor", () => { + value = String.raw`$\frac{1}{\text{ hi \unsupported}}$`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["unsupported"]); + }); }); From 76352c5eb258193daff906fa82e480815ef7c4a9 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 4 Jun 2024 18:25:18 -0400 Subject: [PATCH 08/62] removed uneeded variable --- .../libs/expand-user-defined-macros.ts | 2 +- .../libs/report-unsupported-macro-katex.ts | 4 +--- .../tests/expand-user-defined-macros.test.ts | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts index f95ac028..307befc5 100644 --- a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts +++ b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts @@ -15,7 +15,7 @@ export function ExpandUserDefinedMacros(ast: Ast.Ast): void { newcommands.map((m) => [m.name, { signature: m.signature }]) ); - // attach the arguments to each macro before prcoessing it + // attach the arguments to each macro before processing it attachMacroArgs(ast, macroInfo); expandMacrosExcludingDefinitions(ast, newcommands); } diff --git a/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts b/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts index 9db351c7..9bfbf178 100644 --- a/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts +++ b/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts @@ -16,11 +16,9 @@ export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): string[] { visit(ast, (node, info) => { // macro in math mode if (anyMacro(node) && info.context.hasMathModeAncestor) { - const macro_name = node.content; - // check if not supported by katex if (!isSupported(node)) { - unsupported.push(macro_name); + unsupported.push((node as Ast.Macro).content); } } }); diff --git a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index 35ff3dae..60e8899e 100644 --- a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -25,7 +25,7 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { }); it("can expand renewcommand", () => { - value = String.raw`\renewcommand{\N}{\mathbb{N}} \mathbb{N}`; // not subbing at all + value = String.raw`\renewcommand{\O}{\mathcal{O}} \mathcal{O}`; // not subbing at all const parser = getParser(); const ast = parser.parse(value); @@ -33,7 +33,7 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { ExpandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual( - String.raw`\renewcommand{\N}{\mathbb{N}} \N` + String.raw`\renewcommand{\O}{\mathcal{O}} \O` ); }); From 6f6221ad2a48245c7e082a0b9ba0b246c88a13fc Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 5 Jun 2024 12:25:10 -0400 Subject: [PATCH 09/62] revised tests --- .../tests/report-unsupported-macro-katex.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts index d4bcc545..cb1740eb 100644 --- a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts +++ b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts @@ -12,7 +12,7 @@ console.log = (...args) => { describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { let value: string; - it("can reported unsupported macros", () => { + it("can reported unsupported macros in mathmode", () => { value = String.raw`$\mathbb{R} \fakemacro{X}$`; const parser = getParser(); @@ -30,7 +30,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); }); - it("can not report any unsupported macros outside of math mode", () => { + it("can report no unsupported macros outside of math mode", () => { value = String.raw`\fakemacro`; const parser = getParser(); From b55e08c848514a979148641c318fb64f53b298ff Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:21:22 -0400 Subject: [PATCH 10/62] revised some test descriptions --- .../tests/expand-user-defined-macros.test.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index 60e8899e..ac5af9a6 100644 --- a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -25,7 +25,7 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { }); it("can expand renewcommand", () => { - value = String.raw`\renewcommand{\O}{\mathcal{O}} \mathcal{O}`; // not subbing at all + value = String.raw`\renewcommand{\O}{\mathcal{O}} \O`; // not subbing at all const parser = getParser(); const ast = parser.parse(value); @@ -33,24 +33,22 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { ExpandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual( - String.raw`\renewcommand{\O}{\mathcal{O}} \O` + String.raw`\renewcommand{\O}{\mathcal{O}} \mathcal{O}` ); }); - it("can expand multiple user-defined commands", () => { + it("can recursively expand multiple user-defined commands", () => { value = String.raw`\newcommand{\join}{\vee} \join \renewcommand{\vee}{\foo} - \join`; + \vee`; const parser = getParser(); const ast = parser.parse(value); ExpandUserDefinedMacros(ast); - expect(printRaw(ast)).toEqual(String.raw`\newcommand{\join}{\vee} - \vee - \renewcommand{\vee}{\foo} - \foo`); + expect(printRaw(ast)).toEqual(String.raw`\newcommand{\join}{\vee} `+ + String.raw`\foo \renewcommand{\vee}{\foo} \foo`); }); }); From 49e25bcce01141693c314e1159f192fceb6100d2 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:21:50 -0400 Subject: [PATCH 11/62] fixed expand userdefined macros --- .../libs/expand-user-defined-macros.ts | 52 ++++++++++++++++++- .../tests/expand-user-defined-macros.test.ts | 17 +++--- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts index 307befc5..0e0c25a4 100644 --- a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts +++ b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts @@ -1,9 +1,13 @@ import * as Ast from "@unified-latex/unified-latex-types"; import { expandMacrosExcludingDefinitions, - listNewcommands, + listNewcommands, newcommandMacroToName } from "@unified-latex/unified-latex-util-macros"; import { attachMacroArgs } from "@unified-latex/unified-latex-util-arguments"; +import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; +import { EXIT, visit } from "@unified-latex/unified-latex-util-visit"; + +type NewCommandSpec = ReturnType[number]; /** * Expands user-defined macros @@ -11,11 +15,57 @@ import { attachMacroArgs } from "@unified-latex/unified-latex-util-arguments"; export function ExpandUserDefinedMacros(ast: Ast.Ast): void { const newcommands = listNewcommands(ast); + // get a list of all macros to be expanded + const macros_to_expand = getToBeExpandedMacros(newcommands); + const macroInfo = Object.fromEntries( newcommands.map((m) => [m.name, { signature: m.signature }]) ); + // recursively expand at most 100 times + for (let i = 0; i < 100; i++) { + // check if any macros still need expanding + if (needToExpand(ast, macros_to_expand)) { + ExpandUseDefinedMacrosOnce(ast, newcommands, macroInfo); + } + } +} + +function getToBeExpandedMacros(newcommands: NewCommandSpec[]): string[] { + const macros = []; + + // loop through each new command + for (const command of newcommands) { + macros.push(command.name) + } + + return macros +} + +function needToExpand(ast: Ast.Ast, macros: string[]): boolean { + let needExpand = false; + + visit(ast, (node) => { + if (anyMacro(node) && macros.includes(node.content)) { + needExpand = true; + EXIT; + } + }) + + return needExpand; +} + +function ExpandUseDefinedMacrosOnce( + ast: Ast.Ast, + newcommands: NewCommandSpec[], + macroInfo: { + [k: string]: { + signature: string; + }; + } +): void { // attach the arguments to each macro before processing it attachMacroArgs(ast, macroInfo); expandMacrosExcludingDefinitions(ast, newcommands); } + diff --git a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index ac5af9a6..11505ef0 100644 --- a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -38,17 +38,22 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { }); it("can recursively expand multiple user-defined commands", () => { - value = String.raw`\newcommand{\join}{\vee} - \join - \renewcommand{\vee}{\foo} - \vee`; + value = + String.raw`\newcommand{\join}{\vee}` + + String.raw`\join` + + String.raw`\renewcommand{\vee}{\foo}` + + String.raw`\vee`; const parser = getParser(); const ast = parser.parse(value); ExpandUserDefinedMacros(ast); - expect(printRaw(ast)).toEqual(String.raw`\newcommand{\join}{\vee} `+ - String.raw`\foo \renewcommand{\vee}{\foo} \foo`); + expect(printRaw(ast)).toEqual( + String.raw`\newcommand{\join}{\vee}` + + String.raw`\foo` + + String.raw`\renewcommand{\vee}{\foo}` + + String.raw`\foo` + ); }); }); From 577d1be5ba5a86eda961ae52a6bad833ec89a228 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sat, 8 Jun 2024 00:24:14 -0400 Subject: [PATCH 12/62] addressed more PR comments --- .../libs/expand-user-defined-macros.ts | 48 +++++-------------- .../tests/expand-user-defined-macros.test.ts | 31 ++++++++---- .../report-unsupported-macro-katex.test.ts | 24 ++++++++-- 3 files changed, 57 insertions(+), 46 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts index 0e0c25a4..2c241d01 100644 --- a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts +++ b/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts @@ -1,10 +1,10 @@ import * as Ast from "@unified-latex/unified-latex-types"; import { expandMacrosExcludingDefinitions, - listNewcommands, newcommandMacroToName + listNewcommands, } from "@unified-latex/unified-latex-util-macros"; import { attachMacroArgs } from "@unified-latex/unified-latex-util-arguments"; -import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; +import { anyMacro } from "@unified-latex/unified-latex-util-match"; import { EXIT, visit } from "@unified-latex/unified-latex-util-visit"; type NewCommandSpec = ReturnType[number]; @@ -12,11 +12,11 @@ type NewCommandSpec = ReturnType[number]; /** * Expands user-defined macros */ -export function ExpandUserDefinedMacros(ast: Ast.Ast): void { +export function expandUserDefinedMacros(ast: Ast.Ast): void { const newcommands = listNewcommands(ast); - // get a list of all macros to be expanded - const macros_to_expand = getToBeExpandedMacros(newcommands); + // get a set of all macros to be expanded + const macrosToExpand = new Set(newcommands.map((command) => command.name)); const macroInfo = Object.fromEntries( newcommands.map((m) => [m.name, { signature: m.signature }]) @@ -25,47 +25,25 @@ export function ExpandUserDefinedMacros(ast: Ast.Ast): void { // recursively expand at most 100 times for (let i = 0; i < 100; i++) { // check if any macros still need expanding - if (needToExpand(ast, macros_to_expand)) { - ExpandUseDefinedMacrosOnce(ast, newcommands, macroInfo); + if (!needToExpand(ast, macrosToExpand)) { + break; } - } -} -function getToBeExpandedMacros(newcommands: NewCommandSpec[]): string[] { - const macros = []; - - // loop through each new command - for (const command of newcommands) { - macros.push(command.name) + // attach the arguments to each macro before processing it + attachMacroArgs(ast, macroInfo); + expandMacrosExcludingDefinitions(ast, newcommands); } - - return macros } -function needToExpand(ast: Ast.Ast, macros: string[]): boolean { +function needToExpand(ast: Ast.Ast, macros: Set): boolean { let needExpand = false; visit(ast, (node) => { - if (anyMacro(node) && macros.includes(node.content)) { + if (anyMacro(node) && macros.has(node.content)) { needExpand = true; EXIT; } - }) + }); return needExpand; } - -function ExpandUseDefinedMacrosOnce( - ast: Ast.Ast, - newcommands: NewCommandSpec[], - macroInfo: { - [k: string]: { - signature: string; - }; - } -): void { - // attach the arguments to each macro before processing it - attachMacroArgs(ast, macroInfo); - expandMacrosExcludingDefinitions(ast, newcommands); -} - diff --git a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index 11505ef0..8f9501ff 100644 --- a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import util from "util"; import { getParser } from "@unified-latex/unified-latex-util-parse"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; -import { ExpandUserDefinedMacros } from "@unified-latex/unified-latex-to-pretext/libs/expand-user-defined-macros"; +import { expandUserDefinedMacros } from "@unified-latex/unified-latex-to-pretext/libs/expand-user-defined-macros"; // Make console.log pretty-print by default const origLog = console.log; @@ -19,18 +19,18 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { const parser = getParser(); const ast = parser.parse(value); - ExpandUserDefinedMacros(ast); + expandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual(String.raw`\newcommand{\foo}{\bar} \bar`); }); it("can expand renewcommand", () => { - value = String.raw`\renewcommand{\O}{\mathcal{O}} \O`; // not subbing at all + value = String.raw`\renewcommand{\O}{\mathcal{O}} \O`; const parser = getParser(); const ast = parser.parse(value); - ExpandUserDefinedMacros(ast); + expandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual( String.raw`\renewcommand{\O}{\mathcal{O}} \mathcal{O}` @@ -42,18 +42,33 @@ describe("unified-latex-to-pretext:expand-user-deifned-macros", () => { String.raw`\newcommand{\join}{\vee}` + String.raw`\join` + String.raw`\renewcommand{\vee}{\foo}` + - String.raw`\vee`; + String.raw`\vee` + + String.raw`\renewcommand{\foo}{\bar}` + + String.raw`\foo`; const parser = getParser(); const ast = parser.parse(value); - ExpandUserDefinedMacros(ast); + expandUserDefinedMacros(ast); expect(printRaw(ast)).toEqual( String.raw`\newcommand{\join}{\vee}` + - String.raw`\foo` + + String.raw`\bar` + String.raw`\renewcommand{\vee}{\foo}` + - String.raw`\foo` + String.raw`\bar` + + String.raw`\renewcommand{\foo}{\bar}` + + String.raw`\bar` ); }); + + it("can expand providecommand", () => { + value = String.raw`\providecommand{\bar}{\b} \bar`; + + const parser = getParser(); + const ast = parser.parse(value); + + expandUserDefinedMacros(ast); + + expect(printRaw(ast)).toEqual(String.raw`\providecommand{\bar}{\b} \b`); + }); }); diff --git a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts index cb1740eb..5659ed85 100644 --- a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts +++ b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts @@ -12,7 +12,7 @@ console.log = (...args) => { describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { let value: string; - it("can reported unsupported macros in mathmode", () => { + it("can report unsupported macros in inline mathmode", () => { value = String.raw`$\mathbb{R} \fakemacro{X}$`; const parser = getParser(); @@ -30,7 +30,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); }); - it("can report no unsupported macros outside of math mode", () => { + it("doesn't report unsupported macros outside of math mode", () => { value = String.raw`\fakemacro`; const parser = getParser(); @@ -39,7 +39,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); }); - it("can report unsupported macros in text mode with a math anscestor", () => { + it("reports unsupported macros in text mode with a math anscestor", () => { value = String.raw`$\frac{1}{\text{ hi \unsupported}}$`; const parser = getParser(); @@ -47,4 +47,22 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["unsupported"]); }); + + it("can report unsupported macros in display mathmode", () => { + value = String.raw`\[ \frac{a}{b} \fake \text{bar \baz}\] \bang`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["fake", "baz"]); + }); + + it("can report unsupported macros in equation environment", () => { + value = String.raw`\unsupported \begin{equation} \mathbb{N} \unsupported \text{\baz}\end{equation}`; + + const parser = getParser(); + const ast = parser.parse(value); + + expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["unsupported", "baz"]); + }); }); From 7648bc73fb8484a8265496e9d89b453a32774cfe Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sat, 8 Jun 2024 23:36:58 -0400 Subject: [PATCH 13/62] moved files to pre-conversion-subs --- .../expand-user-defined-macros.ts | 0 .../report-unsupported-macro-katex.ts | 2 +- .../tests/expand-user-defined-macros.test.ts | 2 +- .../tests/report-unsupported-macro-katex.test.ts | 7 +++++-- 4 files changed, 7 insertions(+), 4 deletions(-) rename packages/unified-latex-to-pretext/libs/{ => pre-conversion-subs}/expand-user-defined-macros.ts (100%) rename packages/unified-latex-to-pretext/libs/{ => pre-conversion-subs}/report-unsupported-macro-katex.ts (92%) diff --git a/packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/expand-user-defined-macros.ts similarity index 100% rename from packages/unified-latex-to-pretext/libs/expand-user-defined-macros.ts rename to packages/unified-latex-to-pretext/libs/pre-conversion-subs/expand-user-defined-macros.ts diff --git a/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts similarity index 92% rename from packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts rename to packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts index 9bfbf178..a98b4756 100644 --- a/packages/unified-latex-to-pretext/libs/report-unsupported-macro-katex.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts @@ -1,7 +1,7 @@ import * as Ast from "@unified-latex/unified-latex-types"; import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; -import { KATEX_SUPPORT } from "./pre-conversion-subs/katex-subs"; +import { KATEX_SUPPORT } from "./katex-subs"; /** * Return list of macros unsupported by Katex diff --git a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts index 8f9501ff..6a31b1b7 100644 --- a/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts +++ b/packages/unified-latex-to-pretext/tests/expand-user-defined-macros.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import util from "util"; import { getParser } from "@unified-latex/unified-latex-util-parse"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; -import { expandUserDefinedMacros } from "@unified-latex/unified-latex-to-pretext/libs/expand-user-defined-macros"; +import { expandUserDefinedMacros } from "@unified-latex/unified-latex-to-pretext/libs/pre-conversion-subs/expand-user-defined-macros"; // Make console.log pretty-print by default const origLog = console.log; diff --git a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts index 5659ed85..be40a3d8 100644 --- a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts +++ b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from "vitest"; import util from "util"; import { getParser } from "@unified-latex/unified-latex-util-parse"; -import { reportMacrosUnsupportedByKatex } from "@unified-latex/unified-latex-to-pretext/libs/report-unsupported-macro-katex"; +import { reportMacrosUnsupportedByKatex } from "@unified-latex/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex"; // Make console.log pretty-print by default const origLog = console.log; @@ -63,6 +63,9 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["unsupported", "baz"]); + expect(reportMacrosUnsupportedByKatex(ast)).toEqual([ + "unsupported", + "baz", + ]); }); }); From 80fce28afd8119f468f21c51ed2ab2b20cd06a91 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:32:38 -0400 Subject: [PATCH 14/62] edited docstrings --- .../libs/pre-conversion-subs/report-unsupported-macro-katex.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts index a98b4756..38651036 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts @@ -4,7 +4,7 @@ import { visit } from "@unified-latex/unified-latex-util-visit"; import { KATEX_SUPPORT } from "./katex-subs"; /** - * Return list of macros unsupported by Katex + * Return a list of macros used in ast that are unsupported by KaTeX */ export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): string[] { const unsupported: string[] = []; From 34214da33243c96e8a12488057c2aad4eeb4af1e Mon Sep 17 00:00:00 2001 From: Jason Siefken Date: Wed, 12 Jun 2024 16:34:07 -0400 Subject: [PATCH 15/62] Add pretext to tested branches --- .github/workflows/on-pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml index 6b263a4f..7a41557a 100644 --- a/.github/workflows/on-pull-request.yml +++ b/.github/workflows/on-pull-request.yml @@ -2,9 +2,9 @@ name: Node.js CI on: push: - branches: ["main"] + branches: ["main", "pretext"] pull_request: - branches: ["main"] + branches: ["main", "pretext"] jobs: build: From a0439b64b6ed9ae9e07fd69b83d6bed41e43d0df Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 3 Jul 2024 19:24:49 -0400 Subject: [PATCH 16/62] modified some test cases --- .../tests/unified-latex-to-pretext.test.ts | 100 ++++++++++++------ 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index d1e8f59d..2e6f1297 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -35,7 +35,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { it.skip("wrap pars and streaming commands", () => { html = process("a\n\nb"); - expect(html).toEqual("

a

b

"); + expect(html).toEqual("

a

b

"); // CORRECT html = process("\\bfseries a\n\nb"); expect(html).toEqual( @@ -66,23 +66,27 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(String.raw`a \emph{different} word`); expect(normalizeHtml(html)).toEqual( + // CORRECT but error if not wrapped around something else like

normalizeHtml(`a different word`) ); }); it.skip("Can replace headings", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

My Chapter

`) + // normalizeHtml(`

My Chapter

`) + normalizeHtml(`My Chapter`) ); html = process(String.raw`\section{My Section}`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`My Section`) + // normalizeHtml(`My Section`) + normalizeHtml(`
My Section
`) ); html = process(String.raw`\section*{My Section}`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`My Section`) + // normalizeHtml(`My Section`) + normalizeHtml(`
My Section
`) ); }); @@ -103,12 +107,14 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { it.skip("Wraps URLs", () => { html = process(`a\\url{foo.com}b`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`afoo.comb`) + // normalizeHtml(`afoo.comb`) + normalizeHtml(`ab`) // ** or in between tags? (errored for me) ); html = process(`a\\href{foo.com}{FOO}b`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`aFOOb`) + // normalizeHtml(`aFOOb`) + normalizeHtml(`ab`) ); }); @@ -116,7 +122,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(`\\begin{enumerate}\\item a\\item b\\end{enumerate}`); expect(normalizeHtml(html)).toEqual( normalizeHtml( - `
  1. a

  2. b

` + // don't need

tag for first two test cases + `

  1. a

  2. b

` // correct, without class ) ); @@ -126,7 +133,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); expect(normalizeHtml(html)).toEqual( normalizeHtml( - `
  1. a

  2. b

` + `
  1. a

  2. b

` // correct, without class ) ); @@ -135,10 +142,16 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `\\begin{enumerate}before content\\item[x)] a\\item[] b\\end{enumerate}` ); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`
    -
  1. a

  2. -
  3. b

  4. -
`) + // normalizeHtml(`
    + //
  1. a

  2. + //
  3. b

  4. + //
`) + normalizeHtml( + `
+
  • x)

    a

  • +
  • b

  • +
    ` // markers are bolded and list is centered though + ) ); }); it.skip("Converts itemize environments", () => { @@ -164,29 +177,49 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `\\begin{itemize}before content\\item[x)] a\\item[] b\\end{itemize}` ); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`
      -
    • a

    • -
    • b

    • -
    `) + // normalizeHtml(`
      + //
    • a

    • + //
    • b

    • + //
    `) + normalizeHtml( + `
    +
  • x)

    a

  • +
  • b

  • +
    ` // markers are bolded and list is centered though + ) ); }); it.skip("Converts tabular environment", () => { html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( + // normalizeHtml( + // ` + // + // + // + // + // + // + // + // + // + // + //
    ab
    cd
    ` + // ) + + // centered tho normalizeHtml( - ` - - - - - - - - - - -
    ab
    cd
    ` + ` + + a + b + + + c + d + + ` ) ); }); @@ -228,7 +261,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // Custom labels are handled ast = process(`\\[a\\\\b\\]`); expect(normalizeHtml(ast)).toEqual( - normalizeHtml(`
    a\\\\b
    `) + // normalizeHtml(`
    a\\\\b
    `) + normalizeHtml(`a\\\\b`) // needs to be wrapped by

    ); }); @@ -238,7 +272,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // Custom labels are handled ast = process(`$a\\text{\\#}b$`); expect(normalizeHtml(ast)).toEqual( - normalizeHtml(`a\\text{\\#}b`) + // normalizeHtml(`a\\text{\\#}b`) + normalizeHtml(`a\\text{#}b`) // needs to be wrapped by

    ); }); @@ -247,8 +282,11 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`x\n\ny\\[a\\\\b\\]z`); expect(normalizeHtml(ast)).toEqual( + // normalizeHtml( + // `

    x

    y

    a\\\\b

    z

    ` + // ) normalizeHtml( - `

    x

    y

    a\\\\b

    z

    ` + `

    x

    y

    a\\\\b

    z

    ` ) ); }); From 97f3b2bb55ca7519b3f120b5be6ef0759108bea0 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 3 Jul 2024 20:43:10 -0400 Subject: [PATCH 17/62] fixed a failed test case --- .../tests/unified-latex-to-pretext.test.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 2e6f1297..ecc57f9a 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -35,7 +35,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { it.skip("wrap pars and streaming commands", () => { html = process("a\n\nb"); - expect(html).toEqual("

    a

    b

    "); // CORRECT + expect(html).toEqual("

    a

    b

    "); // CORRECT html = process("\\bfseries a\n\nb"); expect(html).toEqual( @@ -272,8 +272,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // Custom labels are handled ast = process(`$a\\text{\\#}b$`); expect(normalizeHtml(ast)).toEqual( - // normalizeHtml(`a\\text{\\#}b`) - normalizeHtml(`a\\text{#}b`) // needs to be wrapped by

    + normalizeHtml(`a\\text{\\#}b`) ); }); @@ -285,9 +284,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // normalizeHtml( // `

    x

    y

    a\\\\b

    z

    ` // ) - normalizeHtml( - `

    x

    y

    a\\\\b

    z

    ` - ) + normalizeHtml(`

    x

    y

    a\\\\b

    z

    `) ); }); it.skip("replaces command inside argument", () => { From 9d0c2daf187ec2f01e9d7e5c10657aa520d714ff Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Fri, 5 Jul 2024 20:22:00 -0400 Subject: [PATCH 18/62] added boolean to the plugins --- .../libs/unified-latex-plugin-to-pretext.ts | 2 +- .../libs/unified-latex-plugin-to-xml-like.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 88eabd1a..17bc4c66 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -12,7 +12,7 @@ import { PluginOptions as HtmlLikePluginOptions, } from "./unified-latex-plugin-to-xml-like"; -export type PluginOptions = HtmlLikePluginOptions & {}; +export type PluginOptions = HtmlLikePluginOptions & {producePretextFragment: boolean}; /** * Unified plugin to convert a `unified-latex` AST into a `xast` AST representation of PreTeXt source. diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index d8aeff80..88f5f6dc 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -34,6 +34,8 @@ export type PluginOptions = { * You probably want to use the function `htmlLike(...)` to return a node that gets converted to specific HTML. */ macroReplacements?: MacroReplacements; + + producePretextFragment: boolean; }; /** @@ -126,6 +128,11 @@ export const unifiedLatexToXmlLike: Plugin< } }); + if (!options.producePretextFragment) { + // Wrap in enough tags to ensure a valid pretext document + // ... + } + // Make sure we are actually mutating the current tree. originalTree.content = tree.content; }; From 24008c6bb7de1f934fb6607d542439567664dff3 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Fri, 5 Jul 2024 21:03:58 -0400 Subject: [PATCH 19/62] updated a few more test cases --- .../libs/unified-latex-plugin-to-pretext.ts | 8 ++++- .../libs/unified-latex-plugin-to-xml-like.ts | 6 +++- .../tests/unified-latex-to-pretext.test.ts | 30 +++++++++++-------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 17bc4c66..8f8c2cfd 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -12,7 +12,13 @@ import { PluginOptions as HtmlLikePluginOptions, } from "./unified-latex-plugin-to-xml-like"; -export type PluginOptions = HtmlLikePluginOptions & {producePretextFragment: boolean}; +export type PluginOptions = HtmlLikePluginOptions & { + /** + * A boolean where if it's true then the output won't be wrapped in the
    ... etc. tags. + * If it's false (default), a valid and complete PreTeXt document is returned. + */ + producePretextFragment?: boolean; +}; /** * Unified plugin to convert a `unified-latex` AST into a `xast` AST representation of PreTeXt source. diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index 88f5f6dc..d2c20e3b 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -35,7 +35,11 @@ export type PluginOptions = { */ macroReplacements?: MacroReplacements; - producePretextFragment: boolean; + /** + * A boolean where if it's true then the output won't be wrapped in the
    ... etc. tags. + * If it's false (default), a valid and complete PreTeXt document is returned. + */ + producePretextFragment?: false; }; /** diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index ecc57f9a..351a8468 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import Prettier from "prettier"; import util from "util"; import { processLatexViaUnified } from "@unified-latex/unified-latex"; -import { unifiedLatexToPretext } from "../libs/unified-latex-plugin-to-pretext"; +import { unifiedLatexToPretext, PluginOptions } from "../libs/unified-latex-plugin-to-pretext"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { match } from "@unified-latex/unified-latex-util-match"; @@ -29,7 +29,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { const process = (value: string) => processLatexViaUnified({ macros: { xxx: { signature: "m m" } } }) - .use(unifiedLatexToPretext) + .use(unifiedLatexToPretext, {producePretextFragment: true }) .use(xmlCompilePlugin) .processSync({ value }).value as string; @@ -39,27 +39,30 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process("\\bfseries a\n\nb"); expect(html).toEqual( - '

    a

    b

    ' + // '

    a

    b

    ' + '

    a

    b

    ' // maybe alert instead, test difference ); html = process("\\bf a\n\nb"); expect(html).toEqual( - '

    a

    b

    ' + // '

    a

    b

    ' + '

    a

    b

    ' ); }); it.skip("Can replace text-style macros", () => { html = process(String.raw`a \textbf{different} word`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`a different word`) + // normalizeHtml(`a different word`) + normalizeHtml(`a different word`) ); - html = process(String.raw`a \textsf{different} word`); + html = process(String.raw`a \textsf{different} word`); // no equivalent? expect(normalizeHtml(html)).toEqual( normalizeHtml(`a different word`) ); - html = process(String.raw`a \textrm{different} word`); + html = process(String.raw`a \textrm{different} word`); // no equivalent? expect(normalizeHtml(html)).toEqual( normalizeHtml(`a different word`) ); @@ -74,19 +77,19 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`

    My Chapter

    `) - normalizeHtml(`My Chapter`) + normalizeHtml(`My Chapter`) ); html = process(String.raw`\section{My Section}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`My Section`) - normalizeHtml(`
    My Section
    `) + normalizeHtml(`
    My Section
    `) ); html = process(String.raw`\section*{My Section}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`My Section`) - normalizeHtml(`
    My Section
    `) + normalizeHtml(`
    My Section
    `) ); }); @@ -108,13 +111,13 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(`a\\url{foo.com}b`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`afoo.comb`) - normalizeHtml(`ab`) // ** or in between tags? (errored for me) + normalizeHtml(`afoo.comb`) ); html = process(`a\\href{foo.com}{FOO}b`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`aFOOb`) - normalizeHtml(`ab`) + normalizeHtml(`ab`) // ? check diff with href in pretext ); }); @@ -255,6 +258,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); + // output used inline instead it.skip("Macros aren't replaced with html code in math mode", () => { let ast; @@ -262,7 +266,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\[a\\\\b\\]`); expect(normalizeHtml(ast)).toEqual( // normalizeHtml(`
    a\\\\b
    `) - normalizeHtml(`a\\\\b`) // needs to be wrapped by

    + normalizeHtml(`a\\\\b`) // needs to be wrapped by

    ); }); From 78a94636b19f4321fa6e7db12ea23ae5869a945c Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 8 Jul 2024 20:45:19 -0400 Subject: [PATCH 20/62] modified plugins to include new boolean --- .../libs/unified-latex-plugin-to-xml-like.ts | 10 ++++++++-- .../tests/unified-latex-to-pretext.test.ts | 10 ++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index d2c20e3b..98143fc8 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -39,7 +39,7 @@ export type PluginOptions = { * A boolean where if it's true then the output won't be wrapped in the
    ... etc. tags. * If it's false (default), a valid and complete PreTeXt document is returned. */ - producePretextFragment?: false; + producePretextFragment?: boolean; }; /** @@ -64,6 +64,11 @@ export const unifiedLatexToXmlLike: Plugin< _environmentReplacements, options?.environmentReplacements || {} ); + const producePretextFragment = Object.assign( + {}, + false, + options?.producePretextFragment || {} + ); const isReplaceableMacro = match.createMacroMatcher(macroReplacements); const isReplaceableEnvironment = match.createEnvironmentMatcher( environmentReplacements @@ -132,7 +137,8 @@ export const unifiedLatexToXmlLike: Plugin< } }); - if (!options.producePretextFragment) { + // if (!options.producePretextFragment) { + if (!producePretextFragment) { // Wrap in enough tags to ensure a valid pretext document // ... } diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 351a8468..0617af2e 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import Prettier from "prettier"; import util from "util"; import { processLatexViaUnified } from "@unified-latex/unified-latex"; -import { unifiedLatexToPretext, PluginOptions } from "../libs/unified-latex-plugin-to-pretext"; +import { unifiedLatexToPretext } from "../libs/unified-latex-plugin-to-pretext"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { match } from "@unified-latex/unified-latex-util-match"; @@ -29,7 +29,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { const process = (value: string) => processLatexViaUnified({ macros: { xxx: { signature: "m m" } } }) - .use(unifiedLatexToPretext, {producePretextFragment: true }) + .use(unifiedLatexToPretext, { producePretextFragment: true }) .use(xmlCompilePlugin) .processSync({ value }).value as string; @@ -40,13 +40,13 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process("\\bfseries a\n\nb"); expect(html).toEqual( // '

    a

    b

    ' - '

    a

    b

    ' // maybe alert instead, test difference + "

    a

    b

    " // maybe alert instead, test difference ); html = process("\\bf a\n\nb"); expect(html).toEqual( // '

    a

    b

    ' - '

    a

    b

    ' + "

    a

    b

    " ); }); @@ -346,6 +346,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { yyy: (node) => htmlLike({ tag: "yyy", content: node.content }), }, + producePretextFragment: true, }) .use(xmlCompilePlugin) .processSync({ value }).value as string; @@ -387,6 +388,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { }); }, }, + producePretextFragment: true, }) .use(xmlCompilePlugin) .processSync({ value }).value as string; From 0809260a32c6c6affff10ca4b39e0e29f66b84ab Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:40:21 -0400 Subject: [PATCH 21/62] added another tabular test --- .../libs/unified-latex-plugin-to-xml-like.ts | 11 +- .../tests/unified-latex-to-pretext.test.ts | 131 +++++++++++++++++- 2 files changed, 132 insertions(+), 10 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index 98143fc8..db03e1da 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -64,11 +64,10 @@ export const unifiedLatexToXmlLike: Plugin< _environmentReplacements, options?.environmentReplacements || {} ); - const producePretextFragment = Object.assign( - {}, - false, - options?.producePretextFragment || {} - ); + const producePretextFragment = options?.producePretextFragment + ? options?.producePretextFragment + : false; + const isReplaceableMacro = match.createMacroMatcher(macroReplacements); const isReplaceableEnvironment = match.createEnvironmentMatcher( environmentReplacements @@ -136,8 +135,6 @@ export const unifiedLatexToXmlLike: Plugin< ); } }); - - // if (!options.producePretextFragment) { if (!producePretextFragment) { // Wrap in enough tags to ensure a valid pretext document // ... diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 0617af2e..8ab05609 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -117,7 +117,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(`a\\href{foo.com}{FOO}b`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`aFOOb`) - normalizeHtml(`ab`) // ? check diff with href in pretext + normalizeHtml(`aFoob`) ); }); @@ -126,7 +126,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { expect(normalizeHtml(html)).toEqual( normalizeHtml( // don't need

    tag for first two test cases - `

    1. a

    2. b

    ` // correct, without class + // `
    1. a

    2. b

    ` + `
    1. a

    2. b

    ` ) ); @@ -136,7 +137,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); expect(normalizeHtml(html)).toEqual( normalizeHtml( - `
    1. a

    2. b

    ` // correct, without class + // `
    1. a

    2. b

    ` + `
    1. a

    2. b

    ` ) ); @@ -193,6 +195,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); + // make this more descriptive since adding another test it.skip("Converts tabular environment", () => { html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( @@ -227,6 +230,128 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); + // add another tabular test here from PR + + it("Can wrap in

    ...

    tags", () => { + html = process(`a\\par b`); + expect(normalizeHtml(html)).toEqual(normalizeHtml(`

    a

    b

    `)); + + html = process(`a\n\n b`); + expect(normalizeHtml(html)).toEqual(normalizeHtml(`

    a

    b

    `)); + + html = process(`a\n b\n\nc`); + expect(normalizeHtml(html)).toEqual( + normalizeHtml(`

    a b

    c

    `) + ); + html = process(`a\\section{foo} b\n\nc`); + expect(normalizeHtml(html)).toEqual( + normalizeHtml(`

    a

    foo

    b

    c

    `) + ); + html = process(`a\\section{foo} b\\section{bar}\n\nc`); + expect(normalizeHtml(html)).toEqual( + normalizeHtml( + `

    a

    foo

    b

    bar

    c

    ` + ) + ); + html = process(`a\n \\emph{b}\n\nc`); + expect(normalizeHtml(html)).toEqual( + normalizeHtml(`

    a b

    c

    `) + ); + html = process(`a\n b\\begin{foo}x\\end{foo}c\n\nd`); + expect(normalizeHtml(html)).toEqual( + normalizeHtml(`

    a b

    x

    c

    d

    `) + ); + }); + + // output used inline instead + it.skip("Macros aren't replaced with html code in math mode", () => { + let ast; + + // Custom labels are handled + ast = process(`\\[a\\\\b\\]`); + expect(normalizeHtml(ast)).toEqual( + // normalizeHtml(`
    a\\\\b
    `) + normalizeHtml(`a\\\\b`) // needs to be wrapped by

    + ); + }); + + it("Ligatures that are nested inside of math mode are not replaced", () => { + let ast; + + // Custom labels are handled + ast = process(`$a\\text{\\#}b$`); + expect(normalizeHtml(ast)).toEqual( + normalizeHtml(`a\\text{\\#}b`) + ); + }); + + it.skip("Pars are broken at display math", () => { + let ast; + + ast = process(`x\n\ny\\[a\\\\b\\]z`); + expect(normalizeHtml(ast)).toEqual( + // normalizeHtml( + // `

    x

    y

    a\\\\b

    z

    ` + // ) + normalizeHtml(`

    x

    y

    a\\\\b

    z

    `) + ); + }); + it.skip("Converts tabular environment with same column alignments", () => { + html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); + expect(normalizeHtml(html)).toEqual( + // normalizeHtml( + // ` + // + // + // + // + // + // + // + // + // + // + //
    ab
    cd
    ` + // ) + + // centered tho + // left is default alignment so don't need col here + normalizeHtml( + ` + + a + b + + + c + d + + ` + ) + ); + }); + + it.skip("Converts tabular environment with different column alignments", () => { + html = process(`\\begin{tabular}{r l}a & b\\\\c & d\\end{tabular}`); + expect(normalizeHtml(html)).toEqual( + // note: even though only one col is right aligned, need all cols + normalizeHtml( + ` + + + + a + b + + + c + d + + ` + ) + ); + }); + it("Can wrap in

    ...

    tags", () => { html = process(`a\\par b`); expect(normalizeHtml(html)).toEqual(normalizeHtml(`

    a

    b

    `)); From 7c9e262396f59635523bb0ab816f31671259bb72 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:05:23 -0400 Subject: [PATCH 22/62] looked into all skipped test cases --- .../tests/unified-latex-to-pretext.test.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 8ab05609..3c8032aa 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -155,7 +155,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `
  • x)

    a

  • b

  • -
    ` // markers are bolded and list is centered though + ` // list is centered though ) ); }); @@ -190,7 +190,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `
  • x)

    a

  • b

  • -
    ` // markers are bolded and list is centered though + ` // list is centered though ) ); }); @@ -315,7 +315,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // ) // centered tho - // left is default alignment so don't need col here normalizeHtml( ` @@ -429,11 +428,16 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\begin{enumerate}\\item\\bfseries b\\end{enumerate}`); expect(normalizeHtml(ast)).toEqual( - normalizeHtml(`
      -
    1. -

      b

      -
    2. -
    `) + // normalizeHtml(`
      + //
    1. + //

      b

      + //
    2. + //
    `) + normalizeHtml(`
      +
    1. +

      b

      +
    2. +
    `) ); }); it("replaces paragraphs", () => { @@ -443,7 +447,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { expect(normalizeHtml(ast)).toEqual( normalizeHtml(` Important. Paragraph - `) + `) ); }); it("custom replacers work", () => { From 02b525ae90ca26ea76a7bd8365553f2ebf7c3b4e Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:34:20 -0400 Subject: [PATCH 23/62] added comments for cases to fix later --- .../tests/unified-latex-to-pretext.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 3c8032aa..2474b58f 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -50,19 +50,19 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Can replace text-style macros", () => { + it("Can replace text-style macros", () => { html = process(String.raw`a \textbf{different} word`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`a different word`) normalizeHtml(`a different word`) ); - html = process(String.raw`a \textsf{different} word`); // no equivalent? + html = process(String.raw`a \textsf{different} word`); // no equivalent = em and warn expect(normalizeHtml(html)).toEqual( normalizeHtml(`a different word`) ); - html = process(String.raw`a \textrm{different} word`); // no equivalent? + html = process(String.raw`a \textrm{different} word`); // no equivalent = , warn expect(normalizeHtml(html)).toEqual( normalizeHtml(`a different word`) ); @@ -73,7 +73,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { normalizeHtml(`a different word`) ); }); - it.skip("Can replace headings", () => { + it("Can replace headings", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`

    My Chapter

    `) From 03966d26254ff556a7970570932808bcc39a5abf Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:47:04 -0400 Subject: [PATCH 24/62] unskipped some test cases --- .../pre-conversion-subs/environment-subs.ts | 28 +-- .../libs/pre-conversion-subs/macro-subs.ts | 24 ++- .../tests/unified-latex-to-pretext.test.ts | 159 +++--------------- 3 files changed, 54 insertions(+), 157 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index e3e017a3..f99a318b 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -84,7 +84,7 @@ function enumerateFactory(parentTag = "ol", className = "enumerate") { return htmlLike({ tag: parentTag, - attributes: { className }, + // attributes: { className }, content, }); }; @@ -136,28 +136,32 @@ function createTableFromTabular(env: Ast.Environment) { return htmlLike( Object.keys(styles).length > 0 ? { - tag: "td", + tag: "cell", // "td", content: cell, attributes: { style: styles }, } : { - tag: "td", + tag: "cell", // "td", content: cell, } ); }); - return htmlLike({ tag: "tr", content }); + return htmlLike({ tag: "row", content }); }); + // return htmlLike({ + // tag: "table", + // content: [ + // htmlLike({ + // tag: "tbody", + // content: tableBody, + // }), + // ], + // attributes: { className: "tabular" }, + // }); return htmlLike({ - tag: "table", - content: [ - htmlLike({ - tag: "tbody", - content: tableBody, - }), - ], - attributes: { className: "tabular" }, + tag: "tabular", + content: tableBody, }); } diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 5398ee13..0203aedf 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -54,15 +54,15 @@ export const macroReplacements: Record< (node: Ast.Macro, info: VisitInfo) => Ast.Node > = { emph: factory("em"), - textrm: factory("span", { className: "textrm" }), - textsf: factory("span", { className: "textsf" }), - texttt: factory("span", { className: "texttt" }), - textsl: factory("span", { className: "textsl" }), - textit: factory("i", { className: "textit" }), - textbf: factory("b", { className: "textbf" }), - underline: factory("span", { className: "underline" }), - mbox: factory("span", { className: "mbox" }), - phantom: factory("span", { className: "phantom" }), + textrm: factory("em"), // give warning + textsf: factory("em"), // give warning + texttt: factory("span"), + textsl: factory("span"), + textit: factory("em"), + textbf: factory("alert"), + underline: factory("span"), + mbox: factory("span"), + phantom: factory("span"), part: createHeading("title"), chapter: createHeading("title"), section: createHeading("title"), @@ -75,9 +75,8 @@ export const macroReplacements: Record< const args = getArgsContent(node); const url = printRaw(args[0] || "#"); return htmlLike({ - tag: "a", + tag: "url", attributes: { - className: "url", href: url, }, content: [{ type: "string", content: url }], @@ -87,9 +86,8 @@ export const macroReplacements: Record< const args = getArgsContent(node); const url = printRaw(args[1] || "#"); return htmlLike({ - tag: "a", + tag: "url", attributes: { - className: "href", href: url, }, content: args[2] || [], diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 2474b58f..0baa1f21 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -33,47 +33,47 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { .use(xmlCompilePlugin) .processSync({ value }).value as string; - it.skip("wrap pars and streaming commands", () => { + it("wrap pars and streaming commands", () => { html = process("a\n\nb"); - expect(html).toEqual("

    a

    b

    "); // CORRECT + expect(html).toEqual("

    a

    b

    "); html = process("\\bfseries a\n\nb"); expect(html).toEqual( // '

    a

    b

    ' - "

    a

    b

    " // maybe alert instead, test difference + "

    a

    b

    " ); html = process("\\bf a\n\nb"); expect(html).toEqual( // '

    a

    b

    ' - "

    a

    b

    " + "

    a

    b

    " ); }); it("Can replace text-style macros", () => { html = process(String.raw`a \textbf{different} word`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`a different word`) - normalizeHtml(`a different word`) + normalizeHtml(`a different word`) ); - html = process(String.raw`a \textsf{different} word`); // no equivalent = em and warn + html = process(String.raw`a \textsf{different} word`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`a different word`) + normalizeHtml(`a different word`) ); - html = process(String.raw`a \textrm{different} word`); // no equivalent = , warn + html = process(String.raw`a \textrm{different} word`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`a different word`) + normalizeHtml(`a different word`) ); html = process(String.raw`a \emph{different} word`); expect(normalizeHtml(html)).toEqual( - // CORRECT but error if not wrapped around something else like

    normalizeHtml(`a different word`) ); }); - it("Can replace headings", () => { + + // UNSKIP BACK IN AFTER BREAK ON SECTIONS PR IS MERGED + it.skip("Can replace headings", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`

    My Chapter

    `) @@ -107,28 +107,22 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { expect(normalizeHtml(html)).toEqual(normalizeHtml(`

    a

    b

    `)); }); - it.skip("Wraps URLs", () => { + it("Wraps URLs", () => { html = process(`a\\url{foo.com}b`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`afoo.comb`) normalizeHtml(`afoo.comb`) ); html = process(`a\\href{foo.com}{FOO}b`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`aFOOb`) - normalizeHtml(`aFoob`) + normalizeHtml(`aFOOb`) ); }); it.skip("Converts enumerate environments", () => { html = process(`\\begin{enumerate}\\item a\\item b\\end{enumerate}`); expect(normalizeHtml(html)).toEqual( - normalizeHtml( - // don't need

    tag for first two test cases - // `

    1. a

    2. b

    ` - `
    1. a

    2. b

    ` - ) + normalizeHtml(`
    1. a

    2. b

    `) ); // Any content before an \item is ignored @@ -136,16 +130,15 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `\\begin{enumerate}before content\\item a\\item b\\end{enumerate}` ); expect(normalizeHtml(html)).toEqual( - normalizeHtml( - // `
    1. a

    2. b

    ` - `
    1. a

    2. b

    ` - ) + normalizeHtml(`
    1. a

    2. b

    `) ); // Custom labels are handled html = process( `\\begin{enumerate}before content\\item[x)] a\\item[] b\\end{enumerate}` ); + + // only this one doesn't work expect(normalizeHtml(html)).toEqual( // normalizeHtml(`
      //
    1. a

    2. @@ -159,6 +152,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ) ); }); + + // haven't fixed all test cases yet it.skip("Converts itemize environments", () => { html = process(`\\begin{itemize}\\item a\\item b\\end{itemize}`); expect(normalizeHtml(html)).toEqual( @@ -195,7 +190,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - // make this more descriptive since adding another test + // \n in every tag for some reason it.skip("Converts tabular environment", () => { html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( @@ -230,106 +225,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - // add another tabular test here from PR - - it("Can wrap in

      ...

      tags", () => { - html = process(`a\\par b`); - expect(normalizeHtml(html)).toEqual(normalizeHtml(`

      a

      b

      `)); - - html = process(`a\n\n b`); - expect(normalizeHtml(html)).toEqual(normalizeHtml(`

      a

      b

      `)); - - html = process(`a\n b\n\nc`); - expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

      a b

      c

      `) - ); - html = process(`a\\section{foo} b\n\nc`); - expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

      a

      foo

      b

      c

      `) - ); - html = process(`a\\section{foo} b\\section{bar}\n\nc`); - expect(normalizeHtml(html)).toEqual( - normalizeHtml( - `

      a

      foo

      b

      bar

      c

      ` - ) - ); - html = process(`a\n \\emph{b}\n\nc`); - expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

      a b

      c

      `) - ); - html = process(`a\n b\\begin{foo}x\\end{foo}c\n\nd`); - expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

      a b

      x

      c

      d

      `) - ); - }); - - // output used inline instead - it.skip("Macros aren't replaced with html code in math mode", () => { - let ast; - - // Custom labels are handled - ast = process(`\\[a\\\\b\\]`); - expect(normalizeHtml(ast)).toEqual( - // normalizeHtml(`
      a\\\\b
      `) - normalizeHtml(`a\\\\b`) // needs to be wrapped by

      - ); - }); - - it("Ligatures that are nested inside of math mode are not replaced", () => { - let ast; - - // Custom labels are handled - ast = process(`$a\\text{\\#}b$`); - expect(normalizeHtml(ast)).toEqual( - normalizeHtml(`a\\text{\\#}b`) - ); - }); - - it.skip("Pars are broken at display math", () => { - let ast; - - ast = process(`x\n\ny\\[a\\\\b\\]z`); - expect(normalizeHtml(ast)).toEqual( - // normalizeHtml( - // `

      x

      y

      a\\\\b

      z

      ` - // ) - normalizeHtml(`

      x

      y

      a\\\\b

      z

      `) - ); - }); - it.skip("Converts tabular environment with same column alignments", () => { - html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); - expect(normalizeHtml(html)).toEqual( - // normalizeHtml( - // ` - // - // - // - // - // - // - // - // - // - // - //
      ab
      cd
      ` - // ) - - // centered tho - normalizeHtml( - ` - - a - b - - - c - d - - ` - ) - ); - }); - it.skip("Converts tabular environment with different column alignments", () => { html = process(`\\begin{tabular}{r l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( @@ -382,7 +277,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - // output used inline instead + // don't know where comes from, ctrl-shift-F search it it.skip("Macros aren't replaced with html code in math mode", () => { let ast; @@ -415,15 +310,15 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { normalizeHtml(`

      x

      y

      a\\\\b

      z

      `) ); }); - it.skip("replaces command inside argument", () => { + it("replaces command inside argument", () => { let ast; ast = process(`\\emph{\\bfseries b}`); expect(normalizeHtml(ast)).toEqual( - normalizeHtml('b') + normalizeHtml("b") ); }); - it.skip("replaces command inside enumerate", () => { + it("replaces command inside enumerate", () => { let ast; ast = process(`\\begin{enumerate}\\item\\bfseries b\\end{enumerate}`); @@ -435,7 +330,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { //
    `) normalizeHtml(`
    1. -

      b

      +

      b

    `) ); @@ -447,7 +342,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { expect(normalizeHtml(ast)).toEqual( normalizeHtml(` Important. Paragraph - `) + `) ); }); it("custom replacers work", () => { From a522c4f21e84810038e9a9ba15818148b33696ed Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 16 Jul 2024 19:31:01 -0400 Subject: [PATCH 25/62] changed tags for displaymath and tabular --- .../libs/pre-conversion-subs/environment-subs.ts | 4 ++-- .../unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index f99a318b..0ff509ec 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -136,12 +136,12 @@ function createTableFromTabular(env: Ast.Environment) { return htmlLike( Object.keys(styles).length > 0 ? { - tag: "cell", // "td", + tag: "cell", // cell -> td, content: cell, attributes: { style: styles }, } : { - tag: "cell", // "td", + tag: "cell", // cell -> td, content: cell, } ); diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index c8b8fb25..3cfd6dfb 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -59,7 +59,7 @@ export function toPretextWithLoggerFactory( return x("m", printRaw(node.content)); case "mathenv": case "displaymath": - return x("m", printRaw(node.content)); + return x("me", printRaw(node.content)); // CHANGE m -> me case "verb": case "verbatim": return x("pre", { className: node.env }, node.content); From fd21bae6295b5a2d80c9da291505cf4e6a1e37ee Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:15:49 -0400 Subject: [PATCH 26/62] fixed a couple more test cases --- .../tests/unified-latex-to-pretext.test.ts | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 0baa1f21..1faf3605 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -39,13 +39,11 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process("\\bfseries a\n\nb"); expect(html).toEqual( - // '

    a

    b

    ' "

    a

    b

    " ); html = process("\\bf a\n\nb"); expect(html).toEqual( - // '

    a

    b

    ' "

    a

    b

    " ); }); @@ -153,12 +151,11 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - // haven't fixed all test cases yet it.skip("Converts itemize environments", () => { html = process(`\\begin{itemize}\\item a\\item b\\end{itemize}`); expect(normalizeHtml(html)).toEqual( normalizeHtml( - `
    • a

    • b

    ` + `
    • a

    • b

    ` ) ); @@ -168,7 +165,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); expect(normalizeHtml(html)).toEqual( normalizeHtml( - `
    • a

    • b

    ` + `
    • a

    • b

    ` ) ); @@ -176,6 +173,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process( `\\begin{itemize}before content\\item[x)] a\\item[] b\\end{itemize}` ); + // just this doesn't work expect(normalizeHtml(html)).toEqual( // normalizeHtml(`
      //
    • a

    • @@ -185,13 +183,14 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `
    • x)

      a

    • b

    • -
      ` // list is centered though + ` ) ); }); - // \n in every tag for some reason + // \n in some tags for some reason, seems to come from normalizeHTML it.skip("Converts tabular environment", () => { + // the spaces before or after each letter stay html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml( @@ -208,14 +207,13 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // // ` // ) - - // centered tho normalizeHtml( ` a b + c d @@ -277,15 +275,13 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - // don't know where comes from, ctrl-shift-F search it - it.skip("Macros aren't replaced with html code in math mode", () => { + it("Macros aren't replaced with html code in math mode", () => { let ast; // Custom labels are handled ast = process(`\\[a\\\\b\\]`); expect(normalizeHtml(ast)).toEqual( - // normalizeHtml(`
      a\\\\b
      `) - normalizeHtml(`a\\\\b`) // needs to be wrapped by

      + normalizeHtml(`a\\\\b`) ); }); @@ -304,9 +300,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`x\n\ny\\[a\\\\b\\]z`); expect(normalizeHtml(ast)).toEqual( - // normalizeHtml( - // `

      x

      y

      a\\\\b

      z

      ` - // ) + // block not wrapped by

      but should be + // likely needs to be added as an option in split-for-pars since type = displaymath isn't a macro or env normalizeHtml(`

      x

      y

      a\\\\b

      z

      `) ); }); @@ -323,11 +318,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\begin{enumerate}\\item\\bfseries b\\end{enumerate}`); expect(normalizeHtml(ast)).toEqual( - // normalizeHtml(`
        - //
      1. - //

        b

        - //
      2. - //
      `) normalizeHtml(`
      1. b

        From 09c711eaf7eb2ad9967b62b3054673fb101c7030 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:30:53 -0400 Subject: [PATCH 27/62] fixed xml like test cases --- .../tests/unified-latex-to-xml-like.test.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts index 2f613e84..687bd2ed 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts @@ -26,21 +26,15 @@ describe("unified-latex-to-pretext:unified-latex-to-xml-like", () => { expect(file.value).toEqual("\\html-tag:p{a}\\html-tag:p{b}"); file = process("\\bfseries a\n\nb"); - expect(file.value).toEqual( - '\\html-tag:p{\\html-tag:b{\\html-attr:className{"textbf"}a}}\\html-tag:p{\\html-tag:b{\\html-attr:className{"textbf"}b}}' - ); + expect(file.value).toEqual("\\html-tag:p{\\html-tag:alert{a}}\\html-tag:p{\\html-tag:alert{b}}") file = process("\\bf a\n\nb"); - expect(file.value).toEqual( - '\\html-tag:p{\\html-tag:b{\\html-attr:className{"textbf"}a}}\\html-tag:p{\\html-tag:b{\\html-attr:className{"textbf"}b}}' - ); + expect(file.value).toEqual("\\html-tag:p{\\html-tag:alert{a}}\\html-tag:p{\\html-tag:alert{b}}"); file = process( "\\begin{enumerate}\\item foo\\item bar\\end{enumerate}" ); - expect(file.value).toEqual( - '\\html-tag:ol{\\html-attr:className{"enumerate"}\\html-tag:li{\\html-tag:p{foo}}\\html-tag:li{\\html-tag:p{bar}}}' - ); + expect(file.value).toEqual("\\html-tag:ol{\\html-tag:li{\\html-tag:p{foo}}\\html-tag:li{\\html-tag:p{bar}}}"); }); it("can accept custom replacers", () => { From dae8baf8ac344a71651a7758eef66418db6c77ae Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:56:43 -0400 Subject: [PATCH 28/62] began fixing enumerate --- .../pre-conversion-subs/environment-subs.ts | 52 +++++++++++++------ .../libs/split-for-pars.ts | 10 ++-- .../tests/unified-latex-to-pretext.test.ts | 49 +++++------------ 3 files changed, 55 insertions(+), 56 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 0ff509ec..a4df3848 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -1,4 +1,4 @@ -import cssesc from "cssesc"; +// import cssesc from "cssesc"; import { parseTabularSpec, TabularColumn, @@ -14,6 +14,7 @@ import { match } from "@unified-latex/unified-latex-util-match"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; +import { trim } from "@unified-latex/unified-latex-util-trim"; const ITEM_ARG_NAMES_REG = ["label"] as const; const ITEM_ARG_NAMES_BEAMER = [null, "label", null] as const; @@ -48,7 +49,7 @@ function getItemArgs(node: Ast.Macro): ItemArgs { return ret as ItemArgs; } -function enumerateFactory(parentTag = "ol", className = "enumerate") { +function enumerateFactory(parentTag = "ol") { return function enumerateToHtml(env: Ast.Environment) { // The body of an enumerate has already been processed and all relevant parts have // been attached to \item macros as arguments. @@ -58,27 +59,45 @@ function enumerateFactory(parentTag = "ol", className = "enumerate") { return []; } - const attributes: Record> = - {}; + // const attributes: Record> = + // {}; + + const customMarker: Record = {}; + + // Figure out if there any manually-specified item labels. If there are, // we need to specify a custom list-style-type. // We test the open mark to see if an optional argument was actually supplied. const namedArgs = getItemArgs(node); + if (namedArgs.label != null) { - const formattedLabel = cssesc(printRaw(namedArgs.label || [])); - attributes.style = { - // Note the space after `formattedLabel`. That is on purpose! - "list-style-type": formattedLabel - ? `'${formattedLabel} '` - : "none", - }; + // parentTag = "dl" // can't do it here + const formattedLabel = printRaw(namedArgs.label || []) // cssesc(printRaw(namedArgs.label || [])); + // attributes.style = { + // // Note the space after `formattedLabel`. That is on purpose! + // "list-style-type": formattedLabel + // ? `'${formattedLabel} '` + // : "none", + // }; + console.log(formattedLabel) + // customMarker.marker = htmlLike({ + // tag: "title", + // content: namedArgs.label, + // // attributes, + // }) + // namedArgs.body = htmlLike({ + // tag: "title", + // content: namedArgs.label, + // // attributes, + // }) } const body = namedArgs.body; + console.log(namedArgs.body) return htmlLike({ tag: "li", content: wrapPars(body), - attributes, + // attributes, }); }); @@ -133,15 +152,18 @@ function createTableFromTabular(env: Ast.Environment) { styles["border-right"] = "1px solid"; } } + // trim whitespace off cell + trim(cell) + return htmlLike( Object.keys(styles).length > 0 ? { - tag: "cell", // cell -> td, + tag: "cell", content: cell, attributes: { style: styles }, } : { - tag: "cell", // cell -> td, + tag: "cell", content: cell, } ); @@ -177,7 +199,7 @@ export const environmentReplacements: Record< ) => Ast.Macro | Ast.String | Ast.Environment > = { enumerate: enumerateFactory("ol"), - itemize: enumerateFactory("ul", "itemize"), + itemize: enumerateFactory("ul"), center: createCenteredElement, tabular: createTableFromTabular, quote: (env) => { diff --git a/packages/unified-latex-to-pretext/libs/split-for-pars.ts b/packages/unified-latex-to-pretext/libs/split-for-pars.ts index 2d62ec5a..0f823810 100644 --- a/packages/unified-latex-to-pretext/libs/split-for-pars.ts +++ b/packages/unified-latex-to-pretext/libs/split-for-pars.ts @@ -50,11 +50,11 @@ export function splitForPars( continue; } // Display-math should always break pars - if (node.type === "displaymath") { - pushBody(); - ret.push({ content: [node], wrapInPar: false }); - continue; - } + // if (node.type === "displaymath") { + // pushBody(); + // ret.push({ content: [node], wrapInPar: true }); + // continue; + // } if (match.parbreak(node) || match.macro(node, "par")) { pushBody(); continue; diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 1faf3605..27487500 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -117,7 +117,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Converts enumerate environments", () => { + it("Converts enumerate environments", () => { html = process(`\\begin{enumerate}\\item a\\item b\\end{enumerate}`); expect(normalizeHtml(html)).toEqual( normalizeHtml(`
        1. a

        2. b

        `) @@ -183,42 +183,21 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `
      2. x)

        a

      3. b

      4. -
        ` + ` // list is centered though, @margins or @width in tabular could help tho + // width for how much space in marker so not helpful + // margins doesn't work for lists only tabulars ) ); }); - // \n in some tags for some reason, seems to come from normalizeHTML - it.skip("Converts tabular environment", () => { - // the spaces before or after each letter stay + it("Converts tabular environment", () => { html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); + expect(normalizeHtml(html)).toEqual( - // normalizeHtml( - // ` - // - // - // - // - // - // - // - // - // - // - //
        ab
        cd
        ` - // ) + // centered tho + // can fix with margins="0%" normalizeHtml( - ` - - a - b - - - - c - d - - ` + `abcd` ) ); }); @@ -227,7 +206,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(`\\begin{tabular}{r l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( // note: even though only one col is right aligned, need all cols - normalizeHtml( + // put all in single line once implemented ` @@ -240,7 +219,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { d ` - ) ); }); @@ -295,14 +273,12 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Pars are broken at display math", () => { + it("Pars are broken at display math", () => { let ast; ast = process(`x\n\ny\\[a\\\\b\\]z`); expect(normalizeHtml(ast)).toEqual( - // block not wrapped by

        but should be - // likely needs to be added as an option in split-for-pars since type = displaymath isn't a macro or env - normalizeHtml(`

        x

        y

        a\\\\b

        z

        `) + normalizeHtml(`

        x

        ya\\\\bz

        `) ); }); it("replaces command inside argument", () => { @@ -330,6 +306,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\paragraph{Important.} Paragraph`); expect(normalizeHtml(ast)).toEqual( + // should there be a or

        tag? normalizeHtml(` Important. Paragraph `) From 37c55b61352ac6c7c49bf538c0a6f67608b5b323 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Thu, 25 Jul 2024 20:52:07 -0400 Subject: [PATCH 29/62] fixed all list related test cases --- .../pre-conversion-subs/environment-subs.ts | 60 ++++++------------- .../libs/split-for-pars.ts | 6 -- .../tests/unified-latex-to-pretext.test.ts | 34 +++-------- 3 files changed, 26 insertions(+), 74 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index a4df3848..a811d518 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -59,51 +59,37 @@ function enumerateFactory(parentTag = "ol") { return []; } - // const attributes: Record> = - // {}; - - const customMarker: Record = {}; - - // Figure out if there any manually-specified item labels. If there are, - // we need to specify a custom list-style-type. + // we need to add a title tag // We test the open mark to see if an optional argument was actually supplied. const namedArgs = getItemArgs(node); - + + // if there are custom markers, don't want title to be wrapped in pars + // so we wrap the body first + namedArgs.body = wrapPars(namedArgs.body); + if (namedArgs.label != null) { - // parentTag = "dl" // can't do it here - const formattedLabel = printRaw(namedArgs.label || []) // cssesc(printRaw(namedArgs.label || [])); - // attributes.style = { - // // Note the space after `formattedLabel`. That is on purpose! - // "list-style-type": formattedLabel - // ? `'${formattedLabel} '` - // : "none", - // }; - console.log(formattedLabel) - // customMarker.marker = htmlLike({ - // tag: "title", - // content: namedArgs.label, - // // attributes, - // }) - // namedArgs.body = htmlLike({ - // tag: "title", - // content: namedArgs.label, - // // attributes, - // }) + parentTag = "dl"; + + // add title tag containing custom marker + namedArgs.body.unshift( + htmlLike({ + tag: "title", + content: namedArgs.label, + }) + ); } const body = namedArgs.body; - console.log(namedArgs.body) + return htmlLike({ tag: "li", - content: wrapPars(body), - // attributes, + content: body, }); }); return htmlLike({ tag: parentTag, - // attributes: { className }, content, }); }; @@ -153,7 +139,7 @@ function createTableFromTabular(env: Ast.Environment) { } } // trim whitespace off cell - trim(cell) + trim(cell); return htmlLike( Object.keys(styles).length > 0 @@ -171,16 +157,6 @@ function createTableFromTabular(env: Ast.Environment) { return htmlLike({ tag: "row", content }); }); - // return htmlLike({ - // tag: "table", - // content: [ - // htmlLike({ - // tag: "tbody", - // content: tableBody, - // }), - // ], - // attributes: { className: "tabular" }, - // }); return htmlLike({ tag: "tabular", content: tableBody, diff --git a/packages/unified-latex-to-pretext/libs/split-for-pars.ts b/packages/unified-latex-to-pretext/libs/split-for-pars.ts index 0f823810..b0d449a2 100644 --- a/packages/unified-latex-to-pretext/libs/split-for-pars.ts +++ b/packages/unified-latex-to-pretext/libs/split-for-pars.ts @@ -49,12 +49,6 @@ export function splitForPars( ret.push({ content: [node], wrapInPar: false }); continue; } - // Display-math should always break pars - // if (node.type === "displaymath") { - // pushBody(); - // ret.push({ content: [node], wrapInPar: true }); - // continue; - // } if (match.parbreak(node) || match.macro(node, "par")) { pushBody(); continue; diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 27487500..64c8fbf8 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -38,14 +38,10 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { expect(html).toEqual("

        a

        b

        "); html = process("\\bfseries a\n\nb"); - expect(html).toEqual( - "

        a

        b

        " - ); + expect(html).toEqual("

        a

        b

        "); html = process("\\bf a\n\nb"); - expect(html).toEqual( - "

        a

        b

        " - ); + expect(html).toEqual("

        a

        b

        "); }); it("Can replace text-style macros", () => { @@ -70,7 +66,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - // UNSKIP BACK IN AFTER BREAK ON SECTIONS PR IS MERGED it.skip("Can replace headings", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( @@ -138,10 +133,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // only this one doesn't work expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`
          - //
        1. a

        2. - //
        3. b

        4. - //
        `) normalizeHtml( `
      5. x)

        a

      6. @@ -154,9 +145,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { it.skip("Converts itemize environments", () => { html = process(`\\begin{itemize}\\item a\\item b\\end{itemize}`); expect(normalizeHtml(html)).toEqual( - normalizeHtml( - `
        • a

        • b

        ` - ) + normalizeHtml(`
        • a

        • b

        `) ); // Any content before an \item is ignored @@ -164,9 +153,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `\\begin{itemize}before content\\item a\\item b\\end{itemize}` ); expect(normalizeHtml(html)).toEqual( - normalizeHtml( - `
        • a

        • b

        ` - ) + normalizeHtml(`
        • a

        • b

        `) ); // Custom labels are handled @@ -175,10 +162,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); // just this doesn't work expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`
          - //
        • a

        • - //
        • b

        • - //
        `) normalizeHtml( `
      7. x)

        a

      8. @@ -207,7 +190,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { expect(normalizeHtml(html)).toEqual( // note: even though only one col is right aligned, need all cols // put all in single line once implemented - ` + ` @@ -258,9 +241,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { // Custom labels are handled ast = process(`\\[a\\\\b\\]`); - expect(normalizeHtml(ast)).toEqual( - normalizeHtml(`a\\\\b`) - ); + expect(normalizeHtml(ast)).toEqual(normalizeHtml(`a\\\\b`)); }); it("Ligatures that are nested inside of math mode are not replaced", () => { @@ -289,7 +270,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { normalizeHtml("b") ); }); - it("replaces command inside enumerate", () => { + // first enumerate test dl makes this fail for some reason + it.skip("replaces command inside enumerate", () => { let ast; ast = process(`\\begin{enumerate}\\item\\bfseries b\\end{enumerate}`); From 46a4001cf3522aa09d4fe62783bc6e3d009077f6 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sat, 27 Jul 2024 00:34:51 -0400 Subject: [PATCH 30/62] implemented support for tabular borders --- .../pre-conversion-subs/environment-subs.ts | 83 ++++++++++++++----- .../tests/unified-latex-to-pretext.test.ts | 22 ++--- 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index a811d518..48eaff42 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -11,7 +11,6 @@ import { getNamedArgsContent, } from "@unified-latex/unified-latex-util-arguments"; import { match } from "@unified-latex/unified-latex-util-match"; -import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { trim } from "@unified-latex/unified-latex-util-trim"; @@ -111,55 +110,95 @@ function createTableFromTabular(env: Ast.Environment) { columnSpecs = parseTabularSpec(args[1] || []); } catch (e) {} + // for the tabular tag + const attributes: Record> = {}; + + // we only need the col tags if one of the columns aren't left aligned/have a border + let notLeftAligned: boolean = false; + + // stores which columns have borders to the right + // number is the column's index in columnSpecs + const columnRightBorder: Record = {}; + const tableBody = tabularBody.map((row) => { const content = row.cells.map((cell, i) => { const columnSpec = columnSpecs[i]; - const styles: Record = {}; + if (columnSpec) { const { alignment } = columnSpec; - if (alignment.alignment === "center") { - styles["text-align"] = "center"; - } - if (alignment.alignment === "right") { - styles["text-align"] = "right"; - } + + // this will need to be in the tabular tag if ( columnSpec.pre_dividers.some( (div) => div.type === "vert_divider" ) ) { - styles["border-left"] = "1px solid"; + attributes["left"] = "minor"; } + + // check if the column has a right border if ( columnSpec.post_dividers.some( (div) => div.type === "vert_divider" ) ) { - styles["border-right"] = "1px solid"; + columnRightBorder[i] = true; + } + + // check if the default alignment isn't used + if (alignment.alignment !== "left") { + notLeftAligned = true; } } + // trim whitespace off cell trim(cell); - return htmlLike( - Object.keys(styles).length > 0 - ? { - tag: "cell", - content: cell, - attributes: { style: styles }, - } - : { - tag: "cell", - content: cell, - } - ); + return htmlLike({ + tag: "cell", + content: cell, + }); }); return htmlLike({ tag: "row", content }); }); + // add col tags if needed + if ( + notLeftAligned || + Object.values(columnRightBorder).some((bool) => bool) + ) { + // go backwards since adding col tags to the front of the tableBody list + // otherwise, col tags will be in the reversed order + for (let i = columnSpecs.length; i >= 0; i--) { + const columnSpec = columnSpecs[i]; + if (columnSpec) { + const colAttributes: Record< + string, + string | Record + > = {}; + const { alignment } = columnSpec; + + // add h-align attribute if not default + if (alignment.alignment !== "left") { + colAttributes["halign"] = alignment.alignment; + } + + // if there is a right border add it + if ((columnRightBorder[i] = true)) { + colAttributes["right"] = "minor"; + } + + tableBody.unshift( + htmlLike({ tag: "col", attributes: colAttributes }) + ); + } + } + } + return htmlLike({ tag: "tabular", content: tableBody, + attributes: attributes, }); } diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 64c8fbf8..7c82f86b 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -185,23 +185,13 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Converts tabular environment with different column alignments", () => { - html = process(`\\begin{tabular}{r l}a & b\\\\c & d\\end{tabular}`); + it("Converts tabular environment with different column alignments and borders", () => { + html = process(`\\begin{tabular}{|r|l|}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( - // note: even though only one col is right aligned, need all cols - // put all in single line once implemented - ` - - - - a - b - - - c - d - - ` + normalizeHtml( + `` + + `abcd` + ) ); }); From 7803f0f088464787f03defb2439adf4d00a3ce8e Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 28 Jul 2024 01:03:44 -0400 Subject: [PATCH 31/62] corrected most subs --- .../pre-conversion-subs/environment-subs.ts | 4 +- .../libs/pre-conversion-subs/macro-subs.ts | 38 ++++++++++--------- .../libs/pretext-subs/to-pretext.ts | 6 +-- .../tests/unified-latex-to-pretext.test.ts | 11 ++---- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 48eaff42..9c19023c 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -94,6 +94,7 @@ function enumerateFactory(parentTag = "ol") { }; } +// seemsw to be no center tag function createCenteredElement(env: Ast.Environment) { return htmlLike({ tag: "center", @@ -215,13 +216,12 @@ export const environmentReplacements: Record< > = { enumerate: enumerateFactory("ol"), itemize: enumerateFactory("ul"), - center: createCenteredElement, + center: createCenteredElement, // ? tabular: createTableFromTabular, quote: (env) => { return htmlLike({ tag: "blockquote", content: env.content, - attributes: { className: "environment quote" }, }); }, }; diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 0203aedf..86a630cd 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -32,10 +32,8 @@ function factory( function createHeading(tag: string, attrs = {}) { return (macro: Ast.Macro) => { const args = getArgsContent(macro); - const starred = !!args[0]; - const attributes: Record = starred - ? { className: "starred" } - : {}; + // const starred = !!args[0]; + const attributes: Record = {}; if (attrs) { Object.assign(attributes, attrs); @@ -56,21 +54,21 @@ export const macroReplacements: Record< emph: factory("em"), textrm: factory("em"), // give warning textsf: factory("em"), // give warning - texttt: factory("span"), - textsl: factory("span"), + texttt: factory("span"), // cd + cline tags are an option? + textsl: factory("span"), // maybe em textit: factory("em"), textbf: factory("alert"), - underline: factory("span"), - mbox: factory("span"), - phantom: factory("span"), - part: createHeading("title"), + underline: factory("span"), // > maybe em and warn + mbox: factory("span"), // can use \text{} but not an html like tag + phantom: factory("span"), // no equivalent? + part: createHeading("title"), // maybe divisions shouldn't even be in here chapter: createHeading("title"), section: createHeading("title"), subsection: createHeading("title"), subsubsection: createHeading("title"), paragraph: createHeading("title"), subparagraph: createHeading("title"), - appendix: createHeading("title"), + appendix: createHeading("appendix"), // title -> appendix url: (node) => { const args = getArgsContent(node); const url = printRaw(args[0] || "#"); @@ -97,20 +95,21 @@ export const macroReplacements: Record< const args = getArgsContent(node); const url = "#" + printRaw(args[0] || ""); return htmlLike({ - tag: "a", + tag: "url", attributes: { - className: "href", href: url, }, content: args[1] || [], }); }, "\\": () => + // no whitespace in pretext htmlLike({ tag: "br", attributes: { className: "linebreak" }, }), vspace: (node) => { + // no equivalent? const args = getArgsContent(node); return htmlLike({ tag: "div", @@ -122,6 +121,7 @@ export const macroReplacements: Record< }); }, hspace: (node) => { + // no equivalent? const args = getArgsContent(node); return htmlLike({ tag: "span", @@ -133,6 +133,7 @@ export const macroReplacements: Record< }); }, textcolor: (node) => { + // no colors in pretext const args = getArgsContent(node); const computedColor = xcolorMacroToHex(node); const color = computedColor.hex; @@ -156,6 +157,7 @@ export const macroReplacements: Record< } }, textsize: (node) => { + // no equivalent? const args = getArgsContent(node); const textSize = printRaw(args[0] || []); return htmlLike({ @@ -167,6 +169,7 @@ export const macroReplacements: Record< }); }, makebox: (node) => { + // maybe just do the same as mbox, text const args = getArgsContent(node); return htmlLike({ tag: "span", @@ -177,15 +180,14 @@ export const macroReplacements: Record< content: args[3] || [], }); }, - noindent: () => ({ type: "string", content: "" }), + noindent: () => ({ type: "string", content: "" }), // no equivalent? includegraphics: (node) => { const args = getArgsContent(node); - const src = printRaw(args[args.length - 1] || []); + const source = printRaw(args[args.length - 1] || []); return htmlLike({ - tag: "img", + tag: "image", // img -> image attributes: { - className: "includegraphics", - src, + source, // src -> source }, content: [], }); diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index 3cfd6dfb..ffacd839 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -59,13 +59,13 @@ export function toPretextWithLoggerFactory( return x("m", printRaw(node.content)); case "mathenv": case "displaymath": - return x("me", printRaw(node.content)); // CHANGE m -> me + return x("me", printRaw(node.content)); case "verb": case "verbatim": - return x("pre", { className: node.env }, node.content); + return x("pre", node.content); case "whitespace": return { type: "text", value: " ", position: node.position }; - case "parbreak": + case "parbreak": // no equivalent? return x("br"); case "group": // Groups are just ignored. diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 7c82f86b..d653a4d5 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -131,7 +131,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `\\begin{enumerate}before content\\item[x)] a\\item[] b\\end{enumerate}` ); - // only this one doesn't work expect(normalizeHtml(html)).toEqual( normalizeHtml( `
        @@ -142,7 +141,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Converts itemize environments", () => { + it("Converts itemize environments", () => { html = process(`\\begin{itemize}\\item a\\item b\\end{itemize}`); expect(normalizeHtml(html)).toEqual( normalizeHtml(`
        • a

        • b

        `) @@ -160,15 +159,13 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process( `\\begin{itemize}before content\\item[x)] a\\item[] b\\end{itemize}` ); - // just this doesn't work + expect(normalizeHtml(html)).toEqual( normalizeHtml( `
      9. x)

        a

      10. b

      11. -
        ` // list is centered though, @margins or @width in tabular could help tho - // width for how much space in marker so not helpful - // margins doesn't work for lists only tabulars +
        ` ) ); }); @@ -260,7 +257,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { normalizeHtml("b") ); }); - // first enumerate test dl makes this fail for some reason + it.skip("replaces command inside enumerate", () => { let ast; From 034d58d724a9288e54f6a45370cf3db1d9830f47 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:28:19 -0400 Subject: [PATCH 32/62] added new functions into the xml plugin --- .../libs/unified-latex-plugin-to-xml-like.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index db03e1da..b95f3a34 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -19,6 +19,9 @@ import { import { macroReplacements as _macroReplacements } from "./pre-conversion-subs/macro-subs"; import { streamingMacroReplacements } from "./pre-conversion-subs/streaming-command-subs"; import { unifiedLatexWrapPars } from "./unified-latex-wrap-pars"; +import { breakOnBoundaries } from "./pre-conversion-subs/break-on-boundaries"; +import { reportMacrosUnsupportedByKatex } from "./pre-conversion-subs/report-unsupported-macro-katex"; +import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; type EnvironmentReplacements = typeof _environmentReplacements; type MacroReplacements = typeof _macroReplacements; @@ -112,6 +115,13 @@ export const unifiedLatexToXmlLike: Plugin< return environmentReplacements[printRaw(node.env)](node, info); } }); + + // replace division macros with environments + const warningMessages = breakOnBoundaries(tree); // returns messages, what should we do with that? + + // expand any user defined macros + expandUserDefinedMacros(tree); + replaceNode(tree, (node, info) => { // Children of math-mode are rendered by KaTeX/MathJax and so we shouldn't touch them! if (info.context.hasMathModeAncestor) { @@ -123,6 +133,10 @@ export const unifiedLatexToXmlLike: Plugin< } }); + // before replacing math-mode macros, report any macros that can't be replaced + const unsupportedByKatex: string[] = + reportMacrosUnsupportedByKatex(tree); // what to do with return? + // Replace math-mode macros for appropriate KaTeX rendering attachNeededRenderInfo(tree); replaceNode(tree, (node) => { From 8a8fbd5b5ec060ce2540b4d1b5c886d98815f843 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 28 Jul 2024 15:37:35 -0400 Subject: [PATCH 33/62] fixed a list related test case --- .../libs/pre-conversion-subs/environment-subs.ts | 12 ++++++++---- .../tests/unified-latex-to-pretext.test.ts | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 9c19023c..244cca88 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -53,13 +53,16 @@ function enumerateFactory(parentTag = "ol") { // The body of an enumerate has already been processed and all relevant parts have // been attached to \item macros as arguments. const items = env.content.filter((node) => match.macro(node, "item")); + + // Figure out if there any manually-specified item labels. If there are, + // we need to add a title tag + let isDescriptionList = false; + const content = items.flatMap((node) => { if (!match.macro(node) || !node.args) { return []; } - // Figure out if there any manually-specified item labels. If there are, - // we need to add a title tag // We test the open mark to see if an optional argument was actually supplied. const namedArgs = getItemArgs(node); @@ -67,8 +70,9 @@ function enumerateFactory(parentTag = "ol") { // so we wrap the body first namedArgs.body = wrapPars(namedArgs.body); + // check if a custom marker is used if (namedArgs.label != null) { - parentTag = "dl"; + isDescriptionList = true; // add title tag containing custom marker namedArgs.body.unshift( @@ -88,7 +92,7 @@ function enumerateFactory(parentTag = "ol") { }); return htmlLike({ - tag: parentTag, + tag: isDescriptionList ? "dl" : parentTag, content, }); }; diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index d653a4d5..a5a81faf 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -258,7 +258,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("replaces command inside enumerate", () => { + it("replaces command inside enumerate", () => { let ast; ast = process(`\\begin{enumerate}\\item\\bfseries b\\end{enumerate}`); From 1a39d7580f46ba2667e9ec3f0bbac38780cbfba1 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:32:35 -0400 Subject: [PATCH 34/62] started adding in mandatory pretext tags --- .../libs/pre-conversion-subs/macro-subs.ts | 14 +++++++------- .../libs/pretext-subs/to-pretext.ts | 3 ++- .../libs/unified-latex-plugin-to-xml-like.ts | 19 +++++++++++++++---- .../tests/unified-latex-to-pretext.test.ts | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 86a630cd..c070d71a 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -61,13 +61,13 @@ export const macroReplacements: Record< underline: factory("span"), // > maybe em and warn mbox: factory("span"), // can use \text{} but not an html like tag phantom: factory("span"), // no equivalent? - part: createHeading("title"), // maybe divisions shouldn't even be in here - chapter: createHeading("title"), - section: createHeading("title"), - subsection: createHeading("title"), - subsubsection: createHeading("title"), - paragraph: createHeading("title"), - subparagraph: createHeading("title"), + // part: createHeading("title"), // maybe divisions shouldn't even be in here, depends on when breakonboundaries is called or these are just useless + // chapter: createHeading("title"), + // section: createHeading("title"), + // subsection: createHeading("title"), + // subsubsection: createHeading("title"), + // paragraph: createHeading("title"), + // subparagraph: createHeading("title"), appendix: createHeading("appendix"), // title -> appendix url: (node) => { const args = getArgsContent(node); diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index ffacd839..eb8963a8 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -70,7 +70,8 @@ export function toPretextWithLoggerFactory( case "group": // Groups are just ignored. return node.content.flatMap(toPretext); - case "environment": + case "environment": // this is where breakonboundaries has problems likely + // could export the divisions object and ismappedenviron to check further here logger( `Unknown environment when converting to HTML \`${formatNodeForError( node.env diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index b95f3a34..ce92bd2b 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -22,6 +22,7 @@ import { unifiedLatexWrapPars } from "./unified-latex-wrap-pars"; import { breakOnBoundaries } from "./pre-conversion-subs/break-on-boundaries"; import { reportMacrosUnsupportedByKatex } from "./pre-conversion-subs/report-unsupported-macro-katex"; import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; +import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; type EnvironmentReplacements = typeof _environmentReplacements; type MacroReplacements = typeof _macroReplacements; @@ -102,7 +103,7 @@ export const unifiedLatexToXmlLike: Plugin< processor = processor.use(unifiedLatexWrapPars); } tree = processor.runSync(tree); - + // Replace text-mode environments and then macros. Environments *must* be processed first, since // environments like tabular use `\\` as a newline indicator, but a `\\` macro gets replaced with // a `
        ` during macro replacement. @@ -116,8 +117,7 @@ export const unifiedLatexToXmlLike: Plugin< } }); - // replace division macros with environments - const warningMessages = breakOnBoundaries(tree); // returns messages, what should we do with that? + const warningMessages = breakOnBoundaries(tree); // returns messages, what should we do with that? // expand any user defined macros expandUserDefinedMacros(tree); @@ -133,6 +133,10 @@ export const unifiedLatexToXmlLike: Plugin< } }); + // the earliest breakonboundaries can be called without div problem if macro subs stuff not commented out (from prev replaceNode) + // but heading test case doesn't work, since divisions replaced with titles + // could fix in to-pretext (pretext plugin problem) + // before replacing math-mode macros, report any macros that can't be replaced const unsupportedByKatex: string[] = reportMacrosUnsupportedByKatex(tree); // what to do with return? @@ -149,9 +153,16 @@ export const unifiedLatexToXmlLike: Plugin< ); } }); + if (!producePretextFragment) { // Wrap in enough tags to ensure a valid pretext document - // ... + // wrap around with pretext tag + tree.content = [htmlLike({tag: "pretext", content: tree.content})] + + // need anything else?, like it's either a book or article, which must have certain tags + // like right after article must be a title + + // add boilerplate, but it's formatted differently, , so can't use htmllike directly } // Make sure we are actually mutating the current tree. diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index a5a81faf..ecd6e4f6 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -66,7 +66,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Can replace headings", () => { + it("Can replace headings", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( // normalizeHtml(`

        My Chapter

        `) From adef778c90d09563d295e2cceaa24dcca10cc8ae Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:34:25 -0400 Subject: [PATCH 35/62] removed unneeded imports --- .../libs/pre-conversion-subs/environment-subs.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 244cca88..4d31d729 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -1,4 +1,3 @@ -// import cssesc from "cssesc"; import { parseTabularSpec, TabularColumn, From 414dcdae5be4a553a89581be122d573c020b6232 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:09:04 -0400 Subject: [PATCH 36/62] added new plugin option to every test file --- .../tests/convert-to-pretext.test.ts | 1 + .../tests/unified-latex-to-xml-like.test.ts | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts index bba5f4e5..6ec03b79 100644 --- a/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts @@ -87,6 +87,7 @@ describe("unified-latex-to-pretext:convert-to-pretext", () => { }); }, }, + producePretextFragment: true, }) .use(xmlCompilePlugin) .processSync(value).value as string; diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts index 687bd2ed..cd47038f 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts @@ -18,7 +18,7 @@ describe("unified-latex-to-pretext:unified-latex-to-xml-like", () => { let file: VFile; const process = (value: string) => processLatexViaUnified() - .use(unifiedLatexToXmlLike) + .use(unifiedLatexToXmlLike, { producePretextFragment: true }) .processSync({ value }); it("wrap pars and streaming commands", () => { @@ -26,15 +26,21 @@ describe("unified-latex-to-pretext:unified-latex-to-xml-like", () => { expect(file.value).toEqual("\\html-tag:p{a}\\html-tag:p{b}"); file = process("\\bfseries a\n\nb"); - expect(file.value).toEqual("\\html-tag:p{\\html-tag:alert{a}}\\html-tag:p{\\html-tag:alert{b}}") + expect(file.value).toEqual( + "\\html-tag:p{\\html-tag:alert{a}}\\html-tag:p{\\html-tag:alert{b}}" + ); file = process("\\bf a\n\nb"); - expect(file.value).toEqual("\\html-tag:p{\\html-tag:alert{a}}\\html-tag:p{\\html-tag:alert{b}}"); + expect(file.value).toEqual( + "\\html-tag:p{\\html-tag:alert{a}}\\html-tag:p{\\html-tag:alert{b}}" + ); file = process( "\\begin{enumerate}\\item foo\\item bar\\end{enumerate}" ); - expect(file.value).toEqual("\\html-tag:ol{\\html-tag:li{\\html-tag:p{foo}}\\html-tag:li{\\html-tag:p{bar}}}"); + expect(file.value).toEqual( + "\\html-tag:ol{\\html-tag:li{\\html-tag:p{foo}}\\html-tag:li{\\html-tag:p{bar}}}" + ); }); it("can accept custom replacers", () => { @@ -57,6 +63,7 @@ describe("unified-latex-to-pretext:unified-latex-to-xml-like", () => { yyy: (node) => htmlLike({ tag: "yyy", content: node.content }), }, + producePretextFragment: true, }) .processSync({ value }); From e5229d04663706dabb2849511514f2ad6d105f94 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:13:38 -0400 Subject: [PATCH 37/62] added option to one more test file --- .../unified-latex-to-pretext/tests/convert-to-pretext.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts index 6ec03b79..12703dda 100644 --- a/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/convert-to-pretext.test.ts @@ -61,6 +61,7 @@ describe("unified-latex-to-pretext:convert-to-pretext", () => { yyy: (node) => htmlLike({ tag: "yyy", content: node.content }), }, + producePretextFragment: true, }); let ast; From 31726e50af0c7765853ce86abaa5d5e0be8b0bb9 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:32:09 -0400 Subject: [PATCH 38/62] fixed unskipped test case to be proper pretext output --- .../tests/unified-latex-to-pretext.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index a5a81faf..2e92058c 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -192,7 +192,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it("Can wrap in

        ...

        tags", () => { + it.skip("Can wrap in

        ...

        tags", () => { html = process(`a\\par b`); expect(normalizeHtml(html)).toEqual(normalizeHtml(`

        a

        b

        `)); @@ -205,12 +205,16 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); html = process(`a\\section{foo} b\n\nc`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

        a

        foo

        b

        c

        `) + // normalizeHtml(`

        a

        foo

        b

        c

        `) + normalizeHtml( + `

        a

        foo

        b

        c

        ` + ) ); html = process(`a\\section{foo} b\\section{bar}\n\nc`); expect(normalizeHtml(html)).toEqual( normalizeHtml( - `

        a

        foo

        b

        bar

        c

        ` + // `

        a

        foo

        b

        bar

        c

        ` + `

        a

        foo

        b

        bar

        c

        ` ) ); html = process(`a\n \\emph{b}\n\nc`); @@ -276,6 +280,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\paragraph{Important.} Paragraph`); expect(normalizeHtml(ast)).toEqual( // should there be a or

        tag? + // paragraphs seems like it should replace paragraph and p for subparagraph (or still paragraphs) normalizeHtml(` Important. Paragraph `) From 4d1594ff60dba1ecfe44e0e8fdea3beb55ca31aa Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 30 Jul 2024 22:48:25 -0400 Subject: [PATCH 39/62] changed order of function calls in xml plugin --- .../libs/unified-latex-plugin-to-xml-like.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index ce92bd2b..df319379 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -97,13 +97,19 @@ export const unifiedLatexToXmlLike: Plugin< replacers: streamingMacroReplacements, }); + // expand any user defined macros + expandUserDefinedMacros(tree); + + // convert division macros into environments + const warningMessages = breakOnBoundaries(tree); // returns messages, what should we do with that? + // Must be done *after* streaming commands are replaced. // We only wrap PARs if we *need* to. That is, if the content contains multiple paragraphs if (shouldBeWrappedInPars(tree)) { processor = processor.use(unifiedLatexWrapPars); } tree = processor.runSync(tree); - + // Replace text-mode environments and then macros. Environments *must* be processed first, since // environments like tabular use `\\` as a newline indicator, but a `\\` macro gets replaced with // a `
        ` during macro replacement. @@ -117,11 +123,6 @@ export const unifiedLatexToXmlLike: Plugin< } }); - const warningMessages = breakOnBoundaries(tree); // returns messages, what should we do with that? - - // expand any user defined macros - expandUserDefinedMacros(tree); - replaceNode(tree, (node, info) => { // Children of math-mode are rendered by KaTeX/MathJax and so we shouldn't touch them! if (info.context.hasMathModeAncestor) { @@ -134,8 +135,6 @@ export const unifiedLatexToXmlLike: Plugin< }); // the earliest breakonboundaries can be called without div problem if macro subs stuff not commented out (from prev replaceNode) - // but heading test case doesn't work, since divisions replaced with titles - // could fix in to-pretext (pretext plugin problem) // before replacing math-mode macros, report any macros that can't be replaced const unsupportedByKatex: string[] = @@ -157,7 +156,9 @@ export const unifiedLatexToXmlLike: Plugin< if (!producePretextFragment) { // Wrap in enough tags to ensure a valid pretext document // wrap around with pretext tag - tree.content = [htmlLike({tag: "pretext", content: tree.content})] + tree.content = [ + htmlLike({ tag: "pretext", content: tree.content }), + ]; // need anything else?, like it's either a book or article, which must have certain tags // like right after article must be a title From 18821c30e4e031cbce82bea77074ed5020b0d770 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 30 Jul 2024 22:55:34 -0400 Subject: [PATCH 40/62] fixed tabular code --- .../libs/pre-conversion-subs/environment-subs.ts | 4 ++-- .../libs/pre-conversion-subs/macro-subs.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 4d31d729..077e15f4 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -97,7 +97,7 @@ function enumerateFactory(parentTag = "ol") { }; } -// seemsw to be no center tag +// seems to be no center tag function createCenteredElement(env: Ast.Environment) { return htmlLike({ tag: "center", @@ -188,7 +188,7 @@ function createTableFromTabular(env: Ast.Environment) { } // if there is a right border add it - if ((columnRightBorder[i] = true)) { + if (columnRightBorder[i] === true) { colAttributes["right"] = "minor"; } diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 86a630cd..f0eea6e4 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -58,10 +58,10 @@ export const macroReplacements: Record< textsl: factory("span"), // maybe em textit: factory("em"), textbf: factory("alert"), - underline: factory("span"), // > maybe em and warn - mbox: factory("span"), // can use \text{} but not an html like tag + underline: factory("span"), // maybe em and warn + mbox: factory("span"), // can use \text{} but not an html like tag, so can't just use htmlLike phantom: factory("span"), // no equivalent? - part: createHeading("title"), // maybe divisions shouldn't even be in here + part: createHeading("title"), // maybe divisions shouldn't be in here due to break on boundaries function chapter: createHeading("title"), section: createHeading("title"), subsection: createHeading("title"), From eae1fc8e01263fb6f5d5d9c4a952d56c812b95ef Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:34:00 -0400 Subject: [PATCH 41/62] added vfile to xmllike plugin --- .../pre-conversion-subs/environment-subs.ts | 2 +- .../libs/pre-conversion-subs/macro-subs.ts | 22 +++++++++---------- .../libs/unified-latex-plugin-to-pretext.ts | 2 +- .../libs/unified-latex-plugin-to-xml-like.ts | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 077e15f4..ccb3e2e9 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -219,7 +219,7 @@ export const environmentReplacements: Record< > = { enumerate: enumerateFactory("ol"), itemize: enumerateFactory("ul"), - center: createCenteredElement, // ? + center: createCenteredElement, // remove tabular: createTableFromTabular, quote: (env) => { return htmlLike({ diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index f0eea6e4..96bd9975 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -4,6 +4,7 @@ import * as Ast from "@unified-latex/unified-latex-types"; import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; +import { VFile } from "unified-lint-rule/lib"; /** * Factory function that generates html-like macros that wrap their contents. @@ -49,7 +50,7 @@ function createHeading(tag: string, attrs = {}) { export const macroReplacements: Record< string, - (node: Ast.Macro, info: VisitInfo) => Ast.Node + (node: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Node > = { emph: factory("em"), textrm: factory("em"), // give warning @@ -59,15 +60,8 @@ export const macroReplacements: Record< textit: factory("em"), textbf: factory("alert"), underline: factory("span"), // maybe em and warn - mbox: factory("span"), // can use \text{} but not an html like tag, so can't just use htmlLike - phantom: factory("span"), // no equivalent? - part: createHeading("title"), // maybe divisions shouldn't be in here due to break on boundaries function - chapter: createHeading("title"), - section: createHeading("title"), - subsection: createHeading("title"), - subsubsection: createHeading("title"), - paragraph: createHeading("title"), - subparagraph: createHeading("title"), + // mbox: factory("span"), // can use \text{} but not an html like tag, so can't just use htmlLike + phantom: factory("span"), // remove it, make a function that returna an empty text node (string) appendix: createHeading("appendix"), // title -> appendix url: (node) => { const args = getArgsContent(node); @@ -103,12 +97,14 @@ export const macroReplacements: Record< }); }, "\\": () => + // same as phantom and warn // no whitespace in pretext htmlLike({ tag: "br", attributes: { className: "linebreak" }, }), vspace: (node) => { + // remove // no equivalent? const args = getArgsContent(node); return htmlLike({ @@ -121,6 +117,7 @@ export const macroReplacements: Record< }); }, hspace: (node) => { + // remove // no equivalent? const args = getArgsContent(node); return htmlLike({ @@ -133,6 +130,7 @@ export const macroReplacements: Record< }); }, textcolor: (node) => { + // em // no colors in pretext const args = getArgsContent(node); const computedColor = xcolorMacroToHex(node); @@ -157,6 +155,7 @@ export const macroReplacements: Record< } }, textsize: (node) => { + // remove // no equivalent? const args = getArgsContent(node); const textSize = printRaw(args[0] || []); @@ -169,6 +168,7 @@ export const macroReplacements: Record< }); }, makebox: (node) => { + // remove for now // maybe just do the same as mbox, text const args = getArgsContent(node); return htmlLike({ @@ -180,7 +180,7 @@ export const macroReplacements: Record< content: args[3] || [], }); }, - noindent: () => ({ type: "string", content: "" }), // no equivalent? + noindent: () => ({ type: "string", content: "" }), // remove includegraphics: (node) => { const args = getArgsContent(node); const source = printRaw(args[args.length - 1] || []); diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 8f8c2cfd..d3cb30a3 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -29,7 +29,7 @@ export const unifiedLatexToPretext: Plugin< Xast.Root > = function unifiedLatexAttachMacroArguments(options) { return (tree, file) => { - unified().use(unifiedLatexToXmlLike, options).run(tree); + unified().use(unifiedLatexToXmlLike, options).run(tree, file); // This should happen right before converting to HTML because macros like `\&` should // be expanded via html rules first (and not turned into their corresponding ligature directly) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index db03e1da..963dd82a 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -79,7 +79,7 @@ export const unifiedLatexToXmlLike: Plugin< katexSpecificEnvironmentReplacements ); - return (tree) => { + return (tree, file) => { const originalTree = tree; // NOTE: These operations need to be done in a particular order. @@ -98,7 +98,7 @@ export const unifiedLatexToXmlLike: Plugin< if (shouldBeWrappedInPars(tree)) { processor = processor.use(unifiedLatexWrapPars); } - tree = processor.runSync(tree); + tree = processor.runSync(tree, file); // Replace text-mode environments and then macros. Environments *must* be processed first, since // environments like tabular use `\\` as a newline indicator, but a `\\` macro gets replaced with From 155b07f9051879a389e1872f75b6103ea61b8f62 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 31 Jul 2024 15:35:05 -0400 Subject: [PATCH 42/62] added vfile import --- .../libs/pre-conversion-subs/macro-subs.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 96bd9975..db3141d9 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -96,15 +96,13 @@ export const macroReplacements: Record< content: args[1] || [], }); }, - "\\": () => - // same as phantom and warn + "\\": () => // same as phantom and warn // no whitespace in pretext htmlLike({ tag: "br", attributes: { className: "linebreak" }, }), - vspace: (node) => { - // remove + vspace: (node) => {// remove // no equivalent? const args = getArgsContent(node); return htmlLike({ @@ -116,8 +114,7 @@ export const macroReplacements: Record< content: [], }); }, - hspace: (node) => { - // remove + hspace: (node) => { // remove // no equivalent? const args = getArgsContent(node); return htmlLike({ @@ -129,8 +126,7 @@ export const macroReplacements: Record< content: [], }); }, - textcolor: (node) => { - // em + textcolor: (node) => { // em // no colors in pretext const args = getArgsContent(node); const computedColor = xcolorMacroToHex(node); @@ -154,8 +150,7 @@ export const macroReplacements: Record< }); } }, - textsize: (node) => { - // remove + textsize: (node) => { // remove // no equivalent? const args = getArgsContent(node); const textSize = printRaw(args[0] || []); @@ -167,8 +162,7 @@ export const macroReplacements: Record< content: args[1] || [], }); }, - makebox: (node) => { - // remove for now + makebox: (node) => { // remove for now // maybe just do the same as mbox, text const args = getArgsContent(node); return htmlLike({ From 62b4511093172a57b25f3d7b047fcc64ad68d3c9 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Fri, 2 Aug 2024 15:08:49 -0400 Subject: [PATCH 43/62] made functions to create a valid document --- .../libs/unified-latex-plugin-to-pretext.ts | 9 ++ .../libs/unified-latex-plugin-to-xml-like.ts | 85 ++++++++++++++++--- 2 files changed, 84 insertions(+), 10 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 8f8c2cfd..34f4cd2d 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -29,6 +29,10 @@ export const unifiedLatexToPretext: Plugin< Xast.Root > = function unifiedLatexAttachMacroArguments(options) { return (tree, file) => { + const producePretextFragment = options?.producePretextFragment + ? options?.producePretextFragment + : false; + unified().use(unifiedLatexToXmlLike, options).run(tree); // This should happen right before converting to HTML because macros like `\&` should @@ -61,6 +65,11 @@ export const unifiedLatexToPretext: Plugin< // Wrap everything in a Hast.Root node let ret = x(); ret.children = converted; + + // add boilerplate + if (!producePretextFragment) { + ret.children.unshift({type: "instruction", name: "xml", value: "version='1.0' encoding='utf-8'"}) + } return ret; }; }; diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index df319379..962eff26 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -3,13 +3,17 @@ import { Plugin, unified } from "unified"; import { unifiedLatexLintNoTexFontShapingCommands } from "@unified-latex/unified-latex-lint/rules/unified-latex-lint-no-tex-font-shaping-commands"; import * as Ast from "@unified-latex/unified-latex-types"; import { deleteComments } from "@unified-latex/unified-latex-util-comments"; -import { match } from "@unified-latex/unified-latex-util-match"; +import { + anyEnvironment, + anyMacro, + match, +} from "@unified-latex/unified-latex-util-match"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { replaceNode, unifiedLatexReplaceStreamingCommands, } from "@unified-latex/unified-latex-util-replace"; -import { EXIT, visit } from "@unified-latex/unified-latex-util-visit"; +import { EXIT, SKIP, visit } from "@unified-latex/unified-latex-util-visit"; import { environmentReplacements as _environmentReplacements } from "./pre-conversion-subs/environment-subs"; import { attachNeededRenderInfo, @@ -23,6 +27,7 @@ import { breakOnBoundaries } from "./pre-conversion-subs/break-on-boundaries"; import { reportMacrosUnsupportedByKatex } from "./pre-conversion-subs/report-unsupported-macro-katex"; import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; +import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; type EnvironmentReplacements = typeof _environmentReplacements; type MacroReplacements = typeof _macroReplacements; @@ -101,7 +106,7 @@ export const unifiedLatexToXmlLike: Plugin< expandUserDefinedMacros(tree); // convert division macros into environments - const warningMessages = breakOnBoundaries(tree); // returns messages, what should we do with that? + const warningMessages = breakOnBoundaries(tree); // Must be done *after* streaming commands are replaced. // We only wrap PARs if we *need* to. That is, if the content contains multiple paragraphs @@ -138,7 +143,7 @@ export const unifiedLatexToXmlLike: Plugin< // before replacing math-mode macros, report any macros that can't be replaced const unsupportedByKatex: string[] = - reportMacrosUnsupportedByKatex(tree); // what to do with return? + reportMacrosUnsupportedByKatex(tree); // Replace math-mode macros for appropriate KaTeX rendering attachNeededRenderInfo(tree); @@ -153,17 +158,15 @@ export const unifiedLatexToXmlLike: Plugin< } }); + // Wrap in enough tags to ensure a valid pretext document if (!producePretextFragment) { - // Wrap in enough tags to ensure a valid pretext document + // choose a book or articla tag + createValidPretextDoc(tree); + // wrap around with pretext tag tree.content = [ htmlLike({ tag: "pretext", content: tree.content }), ]; - - // need anything else?, like it's either a book or article, which must have certain tags - // like right after article must be a title - - // add boilerplate, but it's formatted differently, , so can't use htmllike directly } // Make sure we are actually mutating the current tree. @@ -191,3 +194,65 @@ function shouldBeWrappedInPars(tree: Ast.Root): boolean { (node) => match.parbreak(node) || match.macro(node, "par") ); } + +/** + * Wrap the tree contents in a book or article tag. + */ +function createValidPretextDoc(tree: Ast.Root): void { + let isBook: boolean = false; + + // look for a \documentclass + const docClassArg = findMacroArg(tree, "documentclass"); + + // memoirs will be books too + if (docClassArg?.content == "book" || docClassArg?.content == "memoir") { + isBook = true; + } + + // if it isn't a book, look for chapter division (_chapters environment since breakonboundaries called before) + if (!isBook) { + visit(tree, (node) => { + if (anyEnvironment(node) && node.env == "_chapter") { + isBook = true; + return EXIT; + } + }); + } + + // a book and article tag must have a title tag right after it + // extract the title first + // const titleArg = findMacroArg(tree, "title") + // tree.content.unshift(htmlLike({ tag: "title", content: tree.content })); + + // now create a book or article tag + if (isBook) { + tree.content = [htmlLike({ tag: "book", content: tree.content })]; + } else { + tree.content = [htmlLike({ tag: "article", content: tree.content })]; + } +} + +// maybe could use match instead, could be slower tho since likely goes into environments +function findMacroArg(tree: Ast.Root, content: string): Ast.String | null { + let macroArg: Ast.String | null = null; + + // look for the macro + visit(tree, (node) => { + // skip visiting the children of environments + if (anyEnvironment(node)) { + return SKIP; + } + if (anyMacro(node) && node.content === content) { + // get the desired argument + const arg = getArgsContent(node)[1]; + + // extract the string + if (arg) { + macroArg = arg[0] as Ast.String; + return EXIT; + } + } + }); + + return macroArg; +} From 2be12adf96be2b98a06213772495330a1ed7d99f Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Fri, 2 Aug 2024 23:34:33 -0400 Subject: [PATCH 44/62] changed return of report unsupported macros by katex to VMessages --- .../break-on-boundaries.ts | 2 +- .../report-unsupported-macro-katex.ts | 34 +++++++++++++++++-- .../report-unsupported-macro-katex.test.ts | 15 ++++---- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts index 83cf2b38..594a18c2 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts @@ -74,7 +74,7 @@ export function breakOnBoundaries(ast: Ast.Ast): { messages: VFileMessage[] } { }; } - message.source = "LatexConversion"; + message.source = "latex-to-pretext:warning"; messagesLst.messages.push(message); return node.content; diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts index 38651036..e2b77888 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts @@ -2,12 +2,15 @@ import * as Ast from "@unified-latex/unified-latex-types"; import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; import { KATEX_SUPPORT } from "./katex-subs"; +import { VFileMessage } from "vfile-message"; /** * Return a list of macros used in ast that are unsupported by KaTeX */ -export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): string[] { - const unsupported: string[] = []; +export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): { + messages: VFileMessage[]; +} { + const unsupported: { messages: VFileMessage[] } = { messages: [] }; // match a macro supported by Katex const isSupported = match.createMacroMatcher(KATEX_SUPPORT.macros); @@ -18,7 +21,32 @@ export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): string[] { if (anyMacro(node) && info.context.hasMathModeAncestor) { // check if not supported by katex if (!isSupported(node)) { - unsupported.push((node as Ast.Macro).content); + // get rid of type never + node = node as Ast.Macro; + + // create a message specifing the unsupported macro + const message = new VFileMessage( + `Warning: \"${node.content}\" is unsupported by Katex.` + ); + + // add the position of the group if available + if (node.position) { + message.line = node.position.start.line; + message.column = node.position.start.column; + message.position = { + start: { + line: node.position.start.line, + column: node.position.start.column, + }, + end: { + line: node.position.end.line, + column: node.position.end.column, + }, + }; + } + + message.source = "latex-to-pretext:warning"; + unsupported.messages.push(message); } } }); diff --git a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts index be40a3d8..f0a2f4f6 100644 --- a/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts +++ b/packages/unified-latex-to-pretext/tests/report-unsupported-macro-katex.test.ts @@ -18,7 +18,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["fakemacro"]); + expect(reportMacrosUnsupportedByKatex(ast).messages.length).toEqual(1); }); it("can report no unsupported macros in mathmode", () => { @@ -27,7 +27,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); + expect(reportMacrosUnsupportedByKatex(ast).messages.length).toEqual(0); }); it("doesn't report unsupported macros outside of math mode", () => { @@ -36,7 +36,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual([]); + expect(reportMacrosUnsupportedByKatex(ast).messages.length).toEqual(0); }); it("reports unsupported macros in text mode with a math anscestor", () => { @@ -45,7 +45,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["unsupported"]); + expect(reportMacrosUnsupportedByKatex(ast).messages.length).toEqual(1); }); it("can report unsupported macros in display mathmode", () => { @@ -54,7 +54,7 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual(["fake", "baz"]); + expect(reportMacrosUnsupportedByKatex(ast).messages.length).toEqual(2); }); it("can report unsupported macros in equation environment", () => { @@ -63,9 +63,6 @@ describe("unified-latex-to-pretext:report-unsupported-macro-katex", () => { const parser = getParser(); const ast = parser.parse(value); - expect(reportMacrosUnsupportedByKatex(ast)).toEqual([ - "unsupported", - "baz", - ]); + expect(reportMacrosUnsupportedByKatex(ast).messages.length).toEqual(2); }); }); From 491f409e6cb0576bdb1654f81e9397c4c4916fcc Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sat, 3 Aug 2024 23:25:17 -0400 Subject: [PATCH 45/62] added function that creates an empty string node --- .../libs/pre-conversion-subs/macro-subs.ts | 119 ++++-------------- .../libs/pretext-subs/to-pretext.ts | 28 ++++- 2 files changed, 50 insertions(+), 97 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 96bd9975..7ad5209f 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -5,12 +5,14 @@ import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "unified-lint-rule/lib"; +import { s } from "@unified-latex/unified-latex-builder"; /** * Factory function that generates html-like macros that wrap their contents. */ function factory( tag: string, + isWarn = false, attributes?: Record ): (macro: Ast.Macro) => Ast.Macro { return (macro) => { @@ -48,21 +50,26 @@ function createHeading(tag: string, attrs = {}) { }; } +function createEmptyString(): () => Ast.String { + // add a warning too (in function) + return () => s(""); +} + export const macroReplacements: Record< string, (node: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Node > = { emph: factory("em"), - textrm: factory("em"), // give warning - textsf: factory("em"), // give warning - texttt: factory("span"), // cd + cline tags are an option? - textsl: factory("span"), // maybe em + textrm: factory("em", true), // give warning + textsf: factory("em", true), // give warning + texttt: factory("em", true), // cd + cline tags are an option? + textsl: factory("em", true), textit: factory("em"), textbf: factory("alert"), - underline: factory("span"), // maybe em and warn - // mbox: factory("span"), // can use \text{} but not an html like tag, so can't just use htmlLike - phantom: factory("span"), // remove it, make a function that returna an empty text node (string) - appendix: createHeading("appendix"), // title -> appendix + underline: factory("em", true), + mbox: createEmptyString(), + phantom: createEmptyString(), + appendix: createHeading("appendix"), url: (node) => { const args = getArgsContent(node); const url = printRaw(args[0] || "#"); @@ -96,98 +103,20 @@ export const macroReplacements: Record< content: args[1] || [], }); }, - "\\": () => - // same as phantom and warn - // no whitespace in pretext - htmlLike({ - tag: "br", - attributes: { className: "linebreak" }, - }), - vspace: (node) => { - // remove - // no equivalent? - const args = getArgsContent(node); - return htmlLike({ - tag: "div", - attributes: { - className: "vspace", - "data-amount": printRaw(args[1] || []), - }, - content: [], - }); - }, - hspace: (node) => { - // remove - // no equivalent? - const args = getArgsContent(node); - return htmlLike({ - tag: "span", - attributes: { - className: "vspace", - "data-amount": printRaw(args[1] || []), - }, - content: [], - }); - }, - textcolor: (node) => { - // em - // no colors in pretext - const args = getArgsContent(node); - const computedColor = xcolorMacroToHex(node); - const color = computedColor.hex; - - if (color) { - return htmlLike({ - tag: "span", - attributes: { style: `color: ${color};` }, - content: args[2] || [], - }); - } else { - // If we couldn't compute the color, it's probably a named - // color that wasn't supplied. In this case, we fall back to a css variable - return htmlLike({ - tag: "span", - attributes: { - style: `color: var(${computedColor.cssVarName});`, - }, - content: args[2] || [], - }); - } - }, - textsize: (node) => { - // remove - // no equivalent? - const args = getArgsContent(node); - const textSize = printRaw(args[0] || []); - return htmlLike({ - tag: "span", - attributes: { - className: `textsize-${textSize}`, - }, - content: args[1] || [], - }); - }, - makebox: (node) => { - // remove for now - // maybe just do the same as mbox, text - const args = getArgsContent(node); - return htmlLike({ - tag: "span", - attributes: { - className: `latex-box`, - style: "display: inline-block;", - }, - content: args[3] || [], - }); - }, - noindent: () => ({ type: "string", content: "" }), // remove + "\\": createEmptyString(), + vspace: createEmptyString(), + hspace: createEmptyString(), + textcolor: factory("em", true), + textsize: createEmptyString(), + makebox: createEmptyString(), // remove for now + noindent: createEmptyString(), includegraphics: (node) => { const args = getArgsContent(node); const source = printRaw(args[args.length - 1] || []); return htmlLike({ - tag: "image", // img -> image + tag: "image", attributes: { - source, // src -> source + source, }, content: [], }); diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index eb8963a8..494c3c04 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -6,6 +6,11 @@ import { } from "@unified-latex/unified-latex-util-html-like"; import * as Ast from "@unified-latex/unified-latex-types"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; +import { + divisions, + isMappedEnviron, +} from "../pre-conversion-subs/break-on-boundaries"; +import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; function formatNodeForError(node: Ast.Node | any): string { try { @@ -65,13 +70,32 @@ export function toPretextWithLoggerFactory( return x("pre", node.content); case "whitespace": return { type: "text", value: " ", position: node.position }; - case "parbreak": // no equivalent? + case "parbreak": // remove return x("br"); case "group": // Groups are just ignored. return node.content.flatMap(toPretext); case "environment": // this is where breakonboundaries has problems likely - // could export the divisions object and ismappedenviron to check further here + // check if it's a new environment made to replace a division node + if (isMappedEnviron(node)) { + // all division macro names are in pretext but paragraph and subparagraph + + // get the division macro associated with this node + const macroName = divisions.find( + (x) => x.mappedEnviron === node.env + )?.division; + + // create a title tag containing the division macro's title arg + const title = getArgsContent(node)[0]; + const titleTag = x("title", title?.flatMap(toPretext)); + console.log(titleTag); + + if (macroName && title) { + return x(macroName, titleTag); + } + // have case when title is undefined? is it possible? ig when not given, null + } + logger( `Unknown environment when converting to HTML \`${formatNodeForError( node.env From 295a6db4b39ef73622ef567d08369d3747920634 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 4 Aug 2024 00:00:38 -0400 Subject: [PATCH 46/62] added function warnings to VFile --- .../libs/unified-latex-plugin-to-xml-like.ts | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index 263f0a1d..f80feea5 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -108,6 +108,12 @@ export const unifiedLatexToXmlLike: Plugin< // convert division macros into environments const warningMessages = breakOnBoundaries(tree); + // add warning messages into the file one at a time + for (const warningmessage of warningMessages.messages) { + file.message(warningmessage); + } + console.log(file.messages); + // Must be done *after* streaming commands are replaced. // We only wrap PARs if we *need* to. That is, if the content contains multiple paragraphs if (shouldBeWrappedInPars(tree)) { @@ -134,16 +140,24 @@ export const unifiedLatexToXmlLike: Plugin< return; } if (isReplaceableMacro(node)) { - const replacement = macroReplacements[node.content](node, info); + const replacement = macroReplacements[node.content]( + node, + info, + file + ); return replacement; } }); - // the earliest breakonboundaries can be called without div problem if macro subs stuff not commented out (from prev replaceNode) - // before replacing math-mode macros, report any macros that can't be replaced - const unsupportedByKatex: string[] = - reportMacrosUnsupportedByKatex(tree); + const unsupportedByKatex = reportMacrosUnsupportedByKatex(tree); + + // add these warning messages into the file one at a time + for (const warningmessage of unsupportedByKatex.messages) { + file.message(warningmessage); + } + + // both function warning messages seem to have null position info tho (doesn't in actual function test file) // Replace math-mode macros for appropriate KaTeX rendering attachNeededRenderInfo(tree); @@ -160,7 +174,7 @@ export const unifiedLatexToXmlLike: Plugin< // Wrap in enough tags to ensure a valid pretext document if (!producePretextFragment) { - // choose a book or articla tag + // choose a book or article tag createValidPretextDoc(tree); // wrap around with pretext tag @@ -244,7 +258,7 @@ function findMacroArg(tree: Ast.Root, content: string): Ast.String | null { } if (anyMacro(node) && node.content === content) { // get the desired argument - const arg = getArgsContent(node)[1]; + const arg = getArgsContent(node)[0]; // maybe not always right spot tho // extract the string if (arg) { From d7f9277ee4576ca6e1a57e8af381aa64be4dde02 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 4 Aug 2024 16:17:19 -0400 Subject: [PATCH 47/62] added warnings to VFile for no equivalent pretext tags --- .../break-on-boundaries.ts | 4 +- .../pre-conversion-subs/environment-subs.ts | 60 +++++++++++++++---- .../libs/pre-conversion-subs/macro-subs.ts | 57 +++++++++++++++--- .../report-unsupported-macro-katex.ts | 2 +- .../libs/pretext-subs/to-pretext.ts | 17 +++++- 5 files changed, 115 insertions(+), 25 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts index 594a18c2..ccfc2d5c 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts @@ -18,7 +18,7 @@ import { VFileMessage } from "vfile-message"; * All the divisions, where each item is {division macro, mapped environment}. * Note that this is ordered from the "largest" division to the "smallest" division. */ -const divisions: { division: string; mappedEnviron: string }[] = [ +export const divisions: { division: string; mappedEnviron: string }[] = [ { division: "part", mappedEnviron: "_part" }, { division: "chapter", mappedEnviron: "_chapter" }, { division: "section", mappedEnviron: "_section" }, @@ -34,7 +34,7 @@ const isDivisionMacro = match.createMacroMatcher( ); // check if an environment is a newly created environment -const isMappedEnviron = match.createEnvironmentMatcher( +export const isMappedEnviron = match.createEnvironmentMatcher( divisions.map((x) => x.mappedEnviron) ); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index ccb3e2e9..c5e5c662 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -13,6 +13,9 @@ import { match } from "@unified-latex/unified-latex-util-match"; import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { trim } from "@unified-latex/unified-latex-util-trim"; +import { VFileMessage } from "vfile-message"; +import { VFile } from "unified-lint-rule/lib"; +import { s } from "@unified-latex/unified-latex-builder"; const ITEM_ARG_NAMES_REG = ["label"] as const; const ITEM_ARG_NAMES_BEAMER = [null, "label", null] as const; @@ -97,15 +100,6 @@ function enumerateFactory(parentTag = "ol") { }; } -// seems to be no center tag -function createCenteredElement(env: Ast.Environment) { - return htmlLike({ - tag: "center", - attributes: { className: "center" }, - content: env.content, - }); -} - function createTableFromTabular(env: Ast.Environment) { const tabularBody = parseAlignEnvironment(env.content); const args = getArgsContent(env); @@ -206,6 +200,49 @@ function createTableFromTabular(env: Ast.Environment) { }); } +function createMessage( + node: Ast.Environment, + replacement: string +): VFileMessage { + const message = new VFileMessage( + `Warning: There is no equivalent tag for \"${node.env}\", \"${replacement}\" was used as a replacement.` + ); + + // add the position of the environment if available + if (node.position) { + message.line = node.position.start.line; + message.column = node.position.start.column; + message.position = { + start: { + line: node.position.start.line, + column: node.position.start.column, + }, + end: { + line: node.position.end.line, + column: node.position.end.column, + }, + }; + } + + message.source = "latex-to-pretext:warning"; + return message; +} + +function createEmptyString(): ( + env: Ast.Environment, + info: VisitInfo, + file?: VFile +) => Ast.String { + return (env, info, file) => { + // add a warning message + if (file) { + file.message(createMessage(env, "an empty Ast.String")); + } + + return s(""); + }; +} + /** * Rules for replacing a macro with an html-like macro * that will render has html when printed. @@ -214,12 +251,13 @@ export const environmentReplacements: Record< string, ( node: Ast.Environment, - info: VisitInfo + info: VisitInfo, + file?: VFile ) => Ast.Macro | Ast.String | Ast.Environment > = { enumerate: enumerateFactory("ol"), itemize: enumerateFactory("ul"), - center: createCenteredElement, // remove + center: createEmptyString(), tabular: createTableFromTabular, quote: (env) => { return htmlLike({ diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 7ad5209f..b7c51296 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -1,4 +1,3 @@ -import { xcolorMacroToHex } from "@unified-latex/unified-latex-ctan/package/xcolor"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import * as Ast from "@unified-latex/unified-latex-types"; import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; @@ -6,6 +5,7 @@ import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "unified-lint-rule/lib"; import { s } from "@unified-latex/unified-latex-builder"; +import { VFileMessage } from "vfile-message"; /** * Factory function that generates html-like macros that wrap their contents. @@ -14,8 +14,8 @@ function factory( tag: string, isWarn = false, attributes?: Record -): (macro: Ast.Macro) => Ast.Macro { - return (macro) => { +): (macro: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Macro { + return (macro, info, file) => { if (!macro.args) { throw new Error( `Found macro to replace but couldn't find content ${printRaw( @@ -23,6 +23,12 @@ function factory( )}` ); } + + // add a warning message to the file if needed + if (isWarn && file) { + file.message(createMessage(macro, tag)); + } + // Assume the meaningful argument is the last argument. This // ensures that we can convert for default packages as well as // packages like beamer, which may add optional arguments. @@ -32,6 +38,31 @@ function factory( }; } +function createMessage(node: Ast.Macro, replacement: string): VFileMessage { + const message = new VFileMessage( + `Warning: There is no equivalent tag for \"${node.content}\", \"${replacement}\" was used as a replacement.` + ); + + // add the position of the macro if available + if (node.position) { + message.line = node.position.start.line; + message.column = node.position.start.column; + message.position = { + start: { + line: node.position.start.line, + column: node.position.start.column, + }, + end: { + line: node.position.end.line, + column: node.position.end.column, + }, + }; + } + + message.source = "latex-to-pretext:warning"; + return message; +} + function createHeading(tag: string, attrs = {}) { return (macro: Ast.Macro) => { const args = getArgsContent(macro); @@ -50,9 +81,19 @@ function createHeading(tag: string, attrs = {}) { }; } -function createEmptyString(): () => Ast.String { - // add a warning too (in function) - return () => s(""); +function createEmptyString(): ( + macro: Ast.Macro, + info: VisitInfo, + file?: VFile +) => Ast.String { + return (macro, info, file) => { + // add a warning message + if (file) { + file.message(createMessage(macro, "an empty Ast.String")); + } + + return s(""); + }; } export const macroReplacements: Record< @@ -60,8 +101,8 @@ export const macroReplacements: Record< (node: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Node > = { emph: factory("em"), - textrm: factory("em", true), // give warning - textsf: factory("em", true), // give warning + textrm: factory("em", true), + textsf: factory("em", true), texttt: factory("em", true), // cd + cline tags are an option? textsl: factory("em", true), textit: factory("em"), diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts index e2b77888..718a5829 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts @@ -29,7 +29,7 @@ export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): { `Warning: \"${node.content}\" is unsupported by Katex.` ); - // add the position of the group if available + // add the position of the node if available if (node.position) { message.line = node.position.start.line; message.column = node.position.start.column; diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index 494c3c04..abef337d 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -70,8 +70,19 @@ export function toPretextWithLoggerFactory( return x("pre", node.content); case "whitespace": return { type: "text", value: " ", position: node.position }; - case "parbreak": // remove - return x("br"); + case "parbreak": + // warn first + logger( + `There is no equivalent for parbreak, so it was replaced with an empty string.`, + node + ); + + // return an empty string + return { + type: "text", + value: "", + position: node.position, + }; case "group": // Groups are just ignored. return node.content.flatMap(toPretext); @@ -88,7 +99,7 @@ export function toPretextWithLoggerFactory( // create a title tag containing the division macro's title arg const title = getArgsContent(node)[0]; const titleTag = x("title", title?.flatMap(toPretext)); - console.log(titleTag); + // console.log(titleTag); if (macroName && title) { return x(macroName, titleTag); From 83fd3527308a5d1140437e990e400ce6e11c31f2 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 4 Aug 2024 23:38:40 -0400 Subject: [PATCH 48/62] fixed warning message positions being null --- .../pre-conversion-subs/environment-subs.ts | 7 ++++- .../libs/pre-conversion-subs/macro-subs.ts | 14 +++++++-- .../libs/unified-latex-plugin-to-xml-like.ts | 30 ++++++++++++------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index c5e5c662..042ac140 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -236,7 +236,12 @@ function createEmptyString(): ( return (env, info, file) => { // add a warning message if (file) { - file.message(createMessage(env, "an empty Ast.String")); + const message = createMessage(env, "an empty Ast.String"); + file.message( + message, + message.position, + "unified-latex-to-pretext:environment-subs" + ); } return s(""); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index b7c51296..a4fc4a5c 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -26,7 +26,12 @@ function factory( // add a warning message to the file if needed if (isWarn && file) { - file.message(createMessage(macro, tag)); + const message = createMessage(macro, tag); + file.message( + message, + message.position, + "unified-latex-to-pretext:macro-subs" + ); } // Assume the meaningful argument is the last argument. This @@ -89,7 +94,12 @@ function createEmptyString(): ( return (macro, info, file) => { // add a warning message if (file) { - file.message(createMessage(macro, "an empty Ast.String")); + const message = createMessage(macro, "an empty Ast.String"); + file.message( + message, + message.position, + "unified-latex-to-pretext:macro-subs" + ); } return s(""); diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index f80feea5..91f78e2d 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -109,10 +109,13 @@ export const unifiedLatexToXmlLike: Plugin< const warningMessages = breakOnBoundaries(tree); // add warning messages into the file one at a time - for (const warningmessage of warningMessages.messages) { - file.message(warningmessage); + for (const warningMessage of warningMessages.messages) { + file.message( + warningMessage, + warningMessage.position, + "unified-latex-to-pretext:break-on-boundaries" + ); } - console.log(file.messages); // Must be done *after* streaming commands are replaced. // We only wrap PARs if we *need* to. That is, if the content contains multiple paragraphs @@ -130,7 +133,11 @@ export const unifiedLatexToXmlLike: Plugin< return; } if (isReplaceableEnvironment(node)) { - return environmentReplacements[printRaw(node.env)](node, info); + return environmentReplacements[printRaw(node.env)]( + node, + info, + file + ); } }); @@ -153,12 +160,14 @@ export const unifiedLatexToXmlLike: Plugin< const unsupportedByKatex = reportMacrosUnsupportedByKatex(tree); // add these warning messages into the file one at a time - for (const warningmessage of unsupportedByKatex.messages) { - file.message(warningmessage); + for (const warningMessage of unsupportedByKatex.messages) { + file.message( + warningMessage, + warningMessage.position, + "unified-latex-to-pretext:report-unsupported-macro-katex" + ); } - // both function warning messages seem to have null position info tho (doesn't in actual function test file) - // Replace math-mode macros for appropriate KaTeX rendering attachNeededRenderInfo(tree); replaceNode(tree, (node) => { @@ -185,6 +194,7 @@ export const unifiedLatexToXmlLike: Plugin< // Make sure we are actually mutating the current tree. originalTree.content = tree.content; + console.log(file.messages); }; }; @@ -210,7 +220,7 @@ function shouldBeWrappedInPars(tree: Ast.Root): boolean { } /** - * Wrap the tree contents in a book or article tag. + * Wrap the tree content in a book or article tag. */ function createValidPretextDoc(tree: Ast.Root): void { let isBook: boolean = false; @@ -223,7 +233,7 @@ function createValidPretextDoc(tree: Ast.Root): void { isBook = true; } - // if it isn't a book, look for chapter division (_chapters environment since breakonboundaries called before) + // if we still don't know if it's a book, look for _chapters environments (since breakonboundaries was called before) if (!isBook) { visit(tree, (node) => { if (anyEnvironment(node) && node.env == "_chapter") { From c64b1f831139cbb0b5c9fbb16bb11d87d205567c Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 5 Aug 2024 18:18:26 -0400 Subject: [PATCH 49/62] added title tag to valid pretext doc --- .../libs/unified-latex-plugin-to-xml-like.ts | 65 ++++++++++++++----- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index 91f78e2d..da95227c 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -28,6 +28,7 @@ import { reportMacrosUnsupportedByKatex } from "./pre-conversion-subs/report-uns import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; +import { s } from "@unified-latex/unified-latex-builder"; type EnvironmentReplacements = typeof _environmentReplacements; type MacroReplacements = typeof _macroReplacements; @@ -122,6 +123,7 @@ export const unifiedLatexToXmlLike: Plugin< if (shouldBeWrappedInPars(tree)) { processor = processor.use(unifiedLatexWrapPars); } + // *THIS CAUSES TITLE TO BE WRAPPED IN PARS tree = processor.runSync(tree, file); // Replace text-mode environments and then macros. Environments *must* be processed first, since @@ -194,7 +196,6 @@ export const unifiedLatexToXmlLike: Plugin< // Make sure we are actually mutating the current tree. originalTree.content = tree.content; - console.log(file.messages); }; }; @@ -226,11 +227,24 @@ function createValidPretextDoc(tree: Ast.Root): void { let isBook: boolean = false; // look for a \documentclass - const docClassArg = findMacroArg(tree, "documentclass"); + const docClass = findMacro(tree, "documentclass"); - // memoirs will be books too - if (docClassArg?.content == "book" || docClassArg?.content == "memoir") { - isBook = true; + // check if there was a documentclass + if (docClass) { + const docClassArg = getArgsContent(docClass)[0]; + + // get the actual class + if (docClassArg) { + const docClassTitle = docClassArg[0] as Ast.String; + + // memoirs will be books too + if ( + docClassTitle.content == "book" || + docClassTitle.content == "memoir" + ) { + isBook = true; + } + } } // if we still don't know if it's a book, look for _chapters environments (since breakonboundaries was called before) @@ -245,8 +259,29 @@ function createValidPretextDoc(tree: Ast.Root): void { // a book and article tag must have a title tag right after it // extract the title first - // const titleArg = findMacroArg(tree, "title") - // tree.content.unshift(htmlLike({ tag: "title", content: tree.content })); + const title = findMacro(tree, "title"); + + // create the title tag (this part doesn't work, adds a bunch of spans, repeats title name) + // this happens before this function is called, likely from wrap pars + if (title) { + const titleArg = getArgsContent(title)[1]; + + // get the actual title + if (titleArg) { + const titleString = titleArg[0] as Ast.String; + tree.content.unshift( + htmlLike({ tag: "title", content: titleString }) + ); + } + // if no title name was given, make an empty tag + else { + tree.content.unshift(htmlLike({ tag: "title", content: s("") })); + } + } + // if there is no title, add an empty title tag + else { + tree.content.unshift(htmlLike({ tag: "title", content: s("") })); + } // now create a book or article tag if (isBook) { @@ -257,8 +292,8 @@ function createValidPretextDoc(tree: Ast.Root): void { } // maybe could use match instead, could be slower tho since likely goes into environments -function findMacroArg(tree: Ast.Root, content: string): Ast.String | null { - let macroArg: Ast.String | null = null; +function findMacro(tree: Ast.Root, content: string): Ast.Macro | null { + let macro: Ast.Macro | null = null; // look for the macro visit(tree, (node) => { @@ -267,16 +302,10 @@ function findMacroArg(tree: Ast.Root, content: string): Ast.String | null { return SKIP; } if (anyMacro(node) && node.content === content) { - // get the desired argument - const arg = getArgsContent(node)[0]; // maybe not always right spot tho - - // extract the string - if (arg) { - macroArg = arg[0] as Ast.String; - return EXIT; - } + macro = node; + return EXIT; } }); - return macroArg; + return macro; } From 603539eb00d39b117a078dcc7b7dcec8e1e73bcb Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:49:58 -0400 Subject: [PATCH 50/62] cleaned up code --- .../libs/pre-conversion-subs/environment-subs.ts | 3 ++- .../libs/pre-conversion-subs/macro-subs.ts | 2 +- .../unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts | 5 ++--- .../libs/unified-latex-plugin-to-xml-like.ts | 3 +++ .../tests/unified-latex-to-pretext.test.ts | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 042ac140..8a02da57 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -68,7 +68,7 @@ function enumerateFactory(parentTag = "ol") { // We test the open mark to see if an optional argument was actually supplied. const namedArgs = getItemArgs(node); - // if there are custom markers, don't want title to be wrapped in pars + // if there are custom markers, don't want the title tag to be wrapped in pars // so we wrap the body first namedArgs.body = wrapPars(namedArgs.body); @@ -169,6 +169,7 @@ function createTableFromTabular(env: Ast.Environment) { // otherwise, col tags will be in the reversed order for (let i = columnSpecs.length; i >= 0; i--) { const columnSpec = columnSpecs[i]; + if (columnSpec) { const colAttributes: Record< string, diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index a4fc4a5c..17667529 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -113,7 +113,7 @@ export const macroReplacements: Record< emph: factory("em"), textrm: factory("em", true), textsf: factory("em", true), - texttt: factory("em", true), // cd + cline tags are an option? + texttt: factory("em", true), textsl: factory("em", true), textit: factory("em"), textbf: factory("alert"), diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index abef337d..7a1dc67b 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -86,7 +86,7 @@ export function toPretextWithLoggerFactory( case "group": // Groups are just ignored. return node.content.flatMap(toPretext); - case "environment": // this is where breakonboundaries has problems likely + case "environment": // check if it's a new environment made to replace a division node if (isMappedEnviron(node)) { // all division macro names are in pretext but paragraph and subparagraph @@ -99,12 +99,11 @@ export function toPretextWithLoggerFactory( // create a title tag containing the division macro's title arg const title = getArgsContent(node)[0]; const titleTag = x("title", title?.flatMap(toPretext)); - // console.log(titleTag); if (macroName && title) { return x(macroName, titleTag); } - // have case when title is undefined? is it possible? ig when not given, null + // have case when title is undefined? doesn't happen when title not given, happens when no {} } logger( diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index da95227c..d95a55a5 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -184,6 +184,7 @@ export const unifiedLatexToXmlLike: Plugin< }); // Wrap in enough tags to ensure a valid pretext document + // but if there is a document env, want to only wrap that if (!producePretextFragment) { // choose a book or article tag createValidPretextDoc(tree); @@ -259,6 +260,8 @@ function createValidPretextDoc(tree: Ast.Root): void { // a book and article tag must have a title tag right after it // extract the title first + // wrap the document env since title is before it, dissapears + // but this assumes that this is only put as false when a document env is used, but if not then would still have duplicate const title = findMacro(tree, "title"); // create the title tag (this part doesn't work, adds a bunch of spans, repeats title name) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 0f234e2e..d971c1be 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -34,7 +34,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { .processSync({ value }).value as string; it("wrap pars and streaming commands", () => { - html = process("a\n\nb"); + html = process("\\begin{document}a\n\nb\\end{document}"); expect(html).toEqual("

        a

        b

        "); html = process("\\bfseries a\n\nb"); From 6ec2e43e2dbb2f1305fbd52dfd52690e01017e78 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:55:36 -0400 Subject: [PATCH 51/62] fixed one test case --- .../tests/unified-latex-to-pretext.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index d971c1be..0f234e2e 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -34,7 +34,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { .processSync({ value }).value as string; it("wrap pars and streaming commands", () => { - html = process("\\begin{document}a\n\nb\\end{document}"); + html = process("a\n\nb"); expect(html).toEqual("

        a

        b

        "); html = process("\\bfseries a\n\nb"); From 9ae7ee3d0ff7e0a2516daa9e39147e0986a8782e Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Thu, 8 Aug 2024 23:56:31 -0400 Subject: [PATCH 52/62] addressed some PR comments --- .../pre-conversion-subs/environment-subs.ts | 43 +++++----- .../libs/pre-conversion-subs/macro-subs.ts | 85 ++++++++++++++----- .../libs/pre-conversion-subs/utils.ts | 0 .../libs/pretext-subs/to-pretext.ts | 26 ++++-- .../libs/unified-latex-plugin-to-pretext.ts | 8 ++ .../libs/unified-latex-plugin-to-xml-like.ts | 12 +-- .../libs/unified-latex-wrap-pars.ts | 12 ++- .../tests/unified-latex-to-pretext.test.ts | 17 ++-- .../tests/unified-latex-to-xml-like.test.ts | 2 +- 9 files changed, 133 insertions(+), 72 deletions(-) create mode 100644 packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 8a02da57..4f857da9 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -14,7 +14,7 @@ import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { trim } from "@unified-latex/unified-latex-util-trim"; import { VFileMessage } from "vfile-message"; -import { VFile } from "unified-lint-rule/lib"; +import { VFile } from "vfile"; import { s } from "@unified-latex/unified-latex-builder"; const ITEM_ARG_NAMES_REG = ["label"] as const; @@ -161,36 +161,35 @@ function createTableFromTabular(env: Ast.Environment) { }); // add col tags if needed - if ( - notLeftAligned || - Object.values(columnRightBorder).some((bool) => bool) - ) { + if (notLeftAligned || Object.values(columnRightBorder).some((b) => b)) { // go backwards since adding col tags to the front of the tableBody list // otherwise, col tags will be in the reversed order for (let i = columnSpecs.length; i >= 0; i--) { const columnSpec = columnSpecs[i]; - if (columnSpec) { - const colAttributes: Record< - string, - string | Record - > = {}; - const { alignment } = columnSpec; + if (!columnSpec) { + continue; + } - // add h-align attribute if not default - if (alignment.alignment !== "left") { - colAttributes["halign"] = alignment.alignment; - } + const colAttributes: Record< + string, + string | Record + > = {}; + const { alignment } = columnSpec; - // if there is a right border add it - if (columnRightBorder[i] === true) { - colAttributes["right"] = "minor"; - } + // add h-align attribute if not default + if (alignment.alignment !== "left") { + colAttributes["halign"] = alignment.alignment; // supports all alignments but stuff like p{'width'} (closest is @colspan in cell) + } - tableBody.unshift( - htmlLike({ tag: "col", attributes: colAttributes }) - ); + // if there is a right border add it + if (columnRightBorder[i] === true) { + colAttributes["right"] = "minor"; } + + tableBody.unshift( + htmlLike({ tag: "col", attributes: colAttributes }) + ); } } diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 17667529..6166e132 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -9,10 +9,12 @@ import { VFileMessage } from "vfile-message"; /** * Factory function that generates html-like macros that wrap their contents. + * warningMessage is a warning for any latex macros that don't have an equivalent + * pretext tag. */ function factory( tag: string, - isWarn = false, + warningMessage: string = "", attributes?: Record ): (macro: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Macro { return (macro, info, file) => { @@ -25,7 +27,7 @@ function factory( } // add a warning message to the file if needed - if (isWarn && file) { + if (warningMessage && file) { const message = createMessage(macro, tag); file.message( message, @@ -43,6 +45,9 @@ function factory( }; } +/** + * Create a warning message if the latex node has no equivalent pretext tag. + */ function createMessage(node: Ast.Macro, replacement: string): VFileMessage { const message = new VFileMessage( `Warning: There is no equivalent tag for \"${node.content}\", \"${replacement}\" was used as a replacement.` @@ -86,15 +91,17 @@ function createHeading(tag: string, attrs = {}) { }; } -function createEmptyString(): ( - macro: Ast.Macro, - info: VisitInfo, - file?: VFile -) => Ast.String { +// put this and createMessage in a utils file +/** + * Create an empty Ast.String node. + */ +function createEmptyString( + warningMessage: string +): (macro: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.String { return (macro, info, file) => { // add a warning message if (file) { - const message = createMessage(macro, "an empty Ast.String"); + const message = createMessage(macro, warningMessage); file.message( message, message.position, @@ -111,15 +118,34 @@ export const macroReplacements: Record< (node: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Node > = { emph: factory("em"), - textrm: factory("em", true), - textsf: factory("em", true), - texttt: factory("em", true), - textsl: factory("em", true), + textrm: factory( + "em", + `Warning: There is no equivalent tag for \"textrm\", \"em\" was used as a replacement.` + ), + textsf: factory( + "em", + `Warning: There is no equivalent tag for \"textsf\", \"em\" was used as a replacement.` + ), + texttt: factory( + "em", + `Warning: There is no equivalent tag for \"textsf\", \"em\" was used as a replacement.` + ), + textsl: factory( + "em", + `Warning: There is no equivalent tag for \"textsl\", \"em\" was used as a replacement.` + ), textit: factory("em"), textbf: factory("alert"), - underline: factory("em", true), - mbox: createEmptyString(), - phantom: createEmptyString(), + underline: factory( + "em", + `Warning: There is no equivalent tag for \"underline\", \"em\" was used as a replacement.` + ), + mbox: createEmptyString( + `Warning: There is no equivalent tag for \"mbox\", an empty Ast.String was used as a replacement.` + ), + phantom: createEmptyString( + `Warning: There is no equivalent tag for \"phantom\", an empty Ast.String was used as a replacement.` + ), appendix: createHeading("appendix"), url: (node) => { const args = getArgsContent(node); @@ -154,13 +180,28 @@ export const macroReplacements: Record< content: args[1] || [], }); }, - "\\": createEmptyString(), - vspace: createEmptyString(), - hspace: createEmptyString(), - textcolor: factory("em", true), - textsize: createEmptyString(), - makebox: createEmptyString(), // remove for now - noindent: createEmptyString(), + "\\": createEmptyString( + `Warning: There is no equivalent tag for \"\\\", an empty Ast.String was used as a replacement.` + ), + vspace: createEmptyString( + `Warning: There is no equivalent tag for \"vspace\", an empty Ast.String was used as a replacement.` + ), + hspace: createEmptyString( + `Warning: There is no equivalent tag for \"hspace\", an empty Ast.String was used as a replacement.` + ), + textcolor: factory( + "em", + `Warning: There is no equivalent tag for \"textcolor\", \"em\" was used as a replacement.` + ), + textsize: createEmptyString( + `Warning: There is no equivalent tag for \"textsize\", an empty Ast.String was used as a replacement.` + ), + makebox: createEmptyString( + `Warning: There is no equivalent tag for \"makebox\", an empty Ast.String was used as a replacement.` + ), // remove for now + noindent: createEmptyString( + `Warning: There is no equivalent tag for \"noindent\", an empty Ast.String was used as a replacement.` + ), includegraphics: (node) => { const args = getArgsContent(node); const source = printRaw(args[args.length - 1] || []); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts new file mode 100644 index 00000000..e69de29b diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index 7a1dc67b..606a2ad6 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -89,21 +89,35 @@ export function toPretextWithLoggerFactory( case "environment": // check if it's a new environment made to replace a division node if (isMappedEnviron(node)) { - // all division macro names are in pretext but paragraph and subparagraph - // get the division macro associated with this node - const macroName = divisions.find( + let divisionName = divisions.find( (x) => x.mappedEnviron === node.env )?.division; + // for subparagraph, give a warning since pretext has no equivalent tag + if (divisionName === "subparagraph") { + logger( + `There is no equivalent tag for "subparagraph", so it was replaced with a "paragraphs." tag`, + node + ); + } + + // paragraph and subparagraph become paragraphs + if ( + divisionName === "paragraph" || + divisionName === "subparagraph" + ) { + divisionName = "paragraphs"; + } + // create a title tag containing the division macro's title arg const title = getArgsContent(node)[0]; + const titleTag = x("title", title?.flatMap(toPretext)); - if (macroName && title) { - return x(macroName, titleTag); + if (divisionName && title) { + return x(divisionName, [titleTag]); } - // have case when title is undefined? doesn't happen when title not given, happens when no {} } logger( diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index f3171f0e..fd6f0a3e 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -11,6 +11,7 @@ import { unifiedLatexToXmlLike, PluginOptions as HtmlLikePluginOptions, } from "./unified-latex-plugin-to-xml-like"; +import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; export type PluginOptions = HtmlLikePluginOptions & { /** @@ -33,6 +34,9 @@ export const unifiedLatexToPretext: Plugin< ? options?.producePretextFragment : false; + // bring expandmacros in here instead + // getting authorinfo would be in here too + unified().use(unifiedLatexToXmlLike, options).run(tree, file); // This should happen right before converting to HTML because macros like `\&` should @@ -41,6 +45,8 @@ export const unifiedLatexToPretext: Plugin< // If there is a \begin{document}...\end{document}, that's the only // content we want to convert. + // *move this to before xmllike called + // after done do tree.content = content (content in document env) let content = tree.content; visit( tree, @@ -57,6 +63,8 @@ export const unifiedLatexToPretext: Plugin< } ); + tree.content = content; + const toHast = toPretextWithLoggerFactory(file.message.bind(file)); let converted = toHast({ type: "root", content }); if (!Array.isArray(converted)) { diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index d95a55a5..a2e67f38 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -23,9 +23,8 @@ import { import { macroReplacements as _macroReplacements } from "./pre-conversion-subs/macro-subs"; import { streamingMacroReplacements } from "./pre-conversion-subs/streaming-command-subs"; import { unifiedLatexWrapPars } from "./unified-latex-wrap-pars"; -import { breakOnBoundaries } from "./pre-conversion-subs/break-on-boundaries"; +import { breakOnBoundaries, isMappedEnviron } from "./pre-conversion-subs/break-on-boundaries"; import { reportMacrosUnsupportedByKatex } from "./pre-conversion-subs/report-unsupported-macro-katex"; -import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { s } from "@unified-latex/unified-latex-builder"; @@ -103,9 +102,6 @@ export const unifiedLatexToXmlLike: Plugin< replacers: streamingMacroReplacements, }); - // expand any user defined macros - expandUserDefinedMacros(tree); - // convert division macros into environments const warningMessages = breakOnBoundaries(tree); @@ -125,6 +121,7 @@ export const unifiedLatexToXmlLike: Plugin< } // *THIS CAUSES TITLE TO BE WRAPPED IN PARS tree = processor.runSync(tree, file); + //console.log(printRaw(tree)) // Replace text-mode environments and then macros. Environments *must* be processed first, since // environments like tabular use `\\` as a newline indicator, but a `\\` macro gets replaced with @@ -157,6 +154,7 @@ export const unifiedLatexToXmlLike: Plugin< return replacement; } }); + // before replacing math-mode macros, report any macros that can't be replaced const unsupportedByKatex = reportMacrosUnsupportedByKatex(tree); @@ -213,7 +211,7 @@ function shouldBeWrappedInPars(tree: Ast.Root): boolean { return EXIT; } }, - { test: (node) => match.environment(node, "document") } + { test: (node) => match.environment(node, "document") || isMappedEnviron(node) } ); return content.some( @@ -225,6 +223,8 @@ function shouldBeWrappedInPars(tree: Ast.Root): boolean { * Wrap the tree content in a book or article tag. */ function createValidPretextDoc(tree: Ast.Root): void { + // very early on get the content in the document tag if there is one + // this will be incomplete since the author info isn't pushed yet, which obtains documentclass, title, etc. let isBook: boolean = false; // look for a \documentclass diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts b/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts index 49603ab1..78c52f9f 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts @@ -3,7 +3,7 @@ import * as Ast from "@unified-latex/unified-latex-types"; import { match } from "@unified-latex/unified-latex-util-match"; import { EXIT, visit } from "@unified-latex/unified-latex-util-visit"; import { wrapPars } from "./wrap-pars"; - +import { isMappedEnviron } from "./pre-conversion-subs/break-on-boundaries"; type PluginOptions = { macrosThatBreakPars?: string[]; environmentsThatDontBreakPars?: string[]; @@ -20,12 +20,18 @@ export const unifiedLatexWrapPars: Plugin = options || {}; return (tree) => { // If \begin{document}...\end{document} is present, we only wrap pars inside of it. + let hasDocumentEnv = false; visit( tree, (env) => { - if (match.environment(env, "document")) { - hasDocumentEnv = true; + if ( + match.environment(env, "document") || + isMappedEnviron(env) + ) { + if (match.environment(env, "document")) { + hasDocumentEnv = true; + } // While we're here, we might as well wrap the pars! env.content = wrapPars(env.content, { diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 0f234e2e..4950b84b 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -69,19 +69,16 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { it("Can replace headings", () => { html = process(String.raw`\chapter{My Chapter}`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`

        My Chapter

        `) normalizeHtml(`My Chapter`) ); html = process(String.raw`\section{My Section}`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`My Section`) normalizeHtml(`
        My Section
        `) ); html = process(String.raw`\section*{My Section}`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`My Section`) normalizeHtml(`
        My Section
        `) ); }); @@ -183,7 +180,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { }); it("Converts tabular environment with different column alignments and borders", () => { - html = process(`\\begin{tabular}{|r|l|}a & b\\\\c & d\\end{tabular}`); + html = process(`\\begin{tabular}{|r||l|}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( normalizeHtml( `` + @@ -192,7 +189,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); }); - it.skip("Can wrap in

        ...

        tags", () => { + it("Can wrap in

        ...

        tags", () => { html = process(`a\\par b`); expect(normalizeHtml(html)).toEqual(normalizeHtml(`

        a

        b

        `)); @@ -205,16 +202,14 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); html = process(`a\\section{foo} b\n\nc`); expect(normalizeHtml(html)).toEqual( - // normalizeHtml(`

        a

        foo

        b

        c

        `) normalizeHtml( - `

        a

        foo

        b

        c

        ` + `

        a

        foo

        b

        c

        ` ) ); html = process(`a\\section{foo} b\\section{bar}\n\nc`); expect(normalizeHtml(html)).toEqual( normalizeHtml( - // `

        a

        foo

        b

        bar

        c

        ` - `

        a

        foo

        b

        bar

        c

        ` + `

        a

        foo

        b

        bar

        c

        ` ) ); html = process(`a\n \\emph{b}\n\nc`); @@ -279,10 +274,8 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\paragraph{Important.} Paragraph`); expect(normalizeHtml(ast)).toEqual( - // should there be a or

        tag? - // paragraphs seems like it should replace paragraph and p for subparagraph (or still paragraphs) normalizeHtml(` - Important. Paragraph + Important. Paragraph `) ); }); diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts index cd47038f..86f8ddce 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from "vitest"; import { processLatexViaUnified } from "@unified-latex/unified-latex"; -import { VFile } from "unified-lint-rule/lib"; +import { VFile } from "vfile"; import util from "util"; import { unifiedLatexToXmlLike } from "../libs/unified-latex-plugin-to-xml-like"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; From 14a005c409357084c54e9277d34cbb9fa95fa142 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sat, 10 Aug 2024 00:44:14 -0400 Subject: [PATCH 53/62] moved some functions into utils file --- .../pre-conversion-subs/environment-subs.ts | 56 +---------- .../libs/pre-conversion-subs/macro-subs.ts | 99 ++++++------------- .../libs/pre-conversion-subs/utils.ts | 46 +++++++++ 3 files changed, 82 insertions(+), 119 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 4f857da9..cea97b00 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -13,9 +13,8 @@ import { match } from "@unified-latex/unified-latex-util-match"; import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { trim } from "@unified-latex/unified-latex-util-trim"; -import { VFileMessage } from "vfile-message"; import { VFile } from "vfile"; -import { s } from "@unified-latex/unified-latex-builder"; +import { emptyStringWithWarning } from "./utils"; const ITEM_ARG_NAMES_REG = ["label"] as const; const ITEM_ARG_NAMES_BEAMER = [null, "label", null] as const; @@ -200,54 +199,6 @@ function createTableFromTabular(env: Ast.Environment) { }); } -function createMessage( - node: Ast.Environment, - replacement: string -): VFileMessage { - const message = new VFileMessage( - `Warning: There is no equivalent tag for \"${node.env}\", \"${replacement}\" was used as a replacement.` - ); - - // add the position of the environment if available - if (node.position) { - message.line = node.position.start.line; - message.column = node.position.start.column; - message.position = { - start: { - line: node.position.start.line, - column: node.position.start.column, - }, - end: { - line: node.position.end.line, - column: node.position.end.column, - }, - }; - } - - message.source = "latex-to-pretext:warning"; - return message; -} - -function createEmptyString(): ( - env: Ast.Environment, - info: VisitInfo, - file?: VFile -) => Ast.String { - return (env, info, file) => { - // add a warning message - if (file) { - const message = createMessage(env, "an empty Ast.String"); - file.message( - message, - message.position, - "unified-latex-to-pretext:environment-subs" - ); - } - - return s(""); - }; -} - /** * Rules for replacing a macro with an html-like macro * that will render has html when printed. @@ -262,7 +213,10 @@ export const environmentReplacements: Record< > = { enumerate: enumerateFactory("ol"), itemize: enumerateFactory("ul"), - center: createEmptyString(), + center: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"center\", an empty Ast.String was used as a replacement.`, + "environment-subs" + ), tabular: createTableFromTabular, quote: (env) => { return htmlLike({ diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 6166e132..de361f9b 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -4,8 +4,7 @@ import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "unified-lint-rule/lib"; -import { s } from "@unified-latex/unified-latex-builder"; -import { VFileMessage } from "vfile-message"; +import { createMessage, emptyStringWithWarning } from "./utils"; /** * Factory function that generates html-like macros that wrap their contents. @@ -28,11 +27,15 @@ function factory( // add a warning message to the file if needed if (warningMessage && file) { - const message = createMessage(macro, tag); + const message = createMessage( + macro, + `Warning: There is no equivalent tag for \"${macro.content}\", \"${tag}\" was used as a replacement.`, + "macro-subs" + ); file.message( message, message.position, - "unified-latex-to-pretext:macro-subs" + message.source // check if rule id still given ); } @@ -45,34 +48,6 @@ function factory( }; } -/** - * Create a warning message if the latex node has no equivalent pretext tag. - */ -function createMessage(node: Ast.Macro, replacement: string): VFileMessage { - const message = new VFileMessage( - `Warning: There is no equivalent tag for \"${node.content}\", \"${replacement}\" was used as a replacement.` - ); - - // add the position of the macro if available - if (node.position) { - message.line = node.position.start.line; - message.column = node.position.start.column; - message.position = { - start: { - line: node.position.start.line, - column: node.position.start.column, - }, - end: { - line: node.position.end.line, - column: node.position.end.column, - }, - }; - } - - message.source = "latex-to-pretext:warning"; - return message; -} - function createHeading(tag: string, attrs = {}) { return (macro: Ast.Macro) => { const args = getArgsContent(macro); @@ -92,26 +67,6 @@ function createHeading(tag: string, attrs = {}) { } // put this and createMessage in a utils file -/** - * Create an empty Ast.String node. - */ -function createEmptyString( - warningMessage: string -): (macro: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.String { - return (macro, info, file) => { - // add a warning message - if (file) { - const message = createMessage(macro, warningMessage); - file.message( - message, - message.position, - "unified-latex-to-pretext:macro-subs" - ); - } - - return s(""); - }; -} export const macroReplacements: Record< string, @@ -140,11 +95,13 @@ export const macroReplacements: Record< "em", `Warning: There is no equivalent tag for \"underline\", \"em\" was used as a replacement.` ), - mbox: createEmptyString( - `Warning: There is no equivalent tag for \"mbox\", an empty Ast.String was used as a replacement.` + mbox: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"mbox\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), - phantom: createEmptyString( - `Warning: There is no equivalent tag for \"phantom\", an empty Ast.String was used as a replacement.` + phantom: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"phantom\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), appendix: createHeading("appendix"), url: (node) => { @@ -180,27 +137,33 @@ export const macroReplacements: Record< content: args[1] || [], }); }, - "\\": createEmptyString( - `Warning: There is no equivalent tag for \"\\\", an empty Ast.String was used as a replacement.` + "\\": emptyStringWithWarning( + `Warning: There is no equivalent tag for \"\\\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), - vspace: createEmptyString( - `Warning: There is no equivalent tag for \"vspace\", an empty Ast.String was used as a replacement.` + vspace: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"vspace\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), - hspace: createEmptyString( - `Warning: There is no equivalent tag for \"hspace\", an empty Ast.String was used as a replacement.` + hspace: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"hspace\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), textcolor: factory( "em", `Warning: There is no equivalent tag for \"textcolor\", \"em\" was used as a replacement.` ), - textsize: createEmptyString( - `Warning: There is no equivalent tag for \"textsize\", an empty Ast.String was used as a replacement.` + textsize: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"textsize\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), - makebox: createEmptyString( - `Warning: There is no equivalent tag for \"makebox\", an empty Ast.String was used as a replacement.` + makebox: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"makebox\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), // remove for now - noindent: createEmptyString( - `Warning: There is no equivalent tag for \"noindent\", an empty Ast.String was used as a replacement.` + noindent: emptyStringWithWarning( + `Warning: There is no equivalent tag for \"noindent\", an empty Ast.String was used as a replacement.`, + "macro-subs" ), includegraphics: (node) => { const args = getArgsContent(node); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts index e69de29b..ff28e10e 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts @@ -0,0 +1,46 @@ +import * as Ast from "@unified-latex/unified-latex-types"; +import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; +import { VFile } from "unified-lint-rule/lib"; +import { s } from "@unified-latex/unified-latex-builder"; +import { VFileMessage } from "vfile-message"; + +/** + * Create a message about node from the given source file. + */ +export function createMessage( + node: Ast.Node, + message: string, + sourceFile: string +): VFileMessage { + const newMessage = new VFileMessage( + message, + node, + ); + + newMessage.source = `latex-to-pretext:${sourceFile}` + + return newMessage +} + +/** + * Create an empty Ast.String node, adding a warning message from + * the source file into the VFile. + */ +export function emptyStringWithWarning( + warningMessage: string, + sourceFile: string +): (node: Ast.Node, info: VisitInfo, file?: VFile) => Ast.String { + return (node, info, file) => { + // add a warning message + if (file) { + const message = createMessage(node, warningMessage, sourceFile); + file.message( + message, + message.position, + `unified-latex-to-pretext:${sourceFile}` + ); + } + + return s(""); + }; +} \ No newline at end of file From b5cfa215d142b59a2f2ee41aab91f4b7361e24f3 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sat, 10 Aug 2024 23:47:26 -0400 Subject: [PATCH 54/62] added new file for creating tabular --- .../break-on-boundaries.ts | 29 ++-- .../create-table-from-tabular.ts | 111 +++++++++++++++ .../pre-conversion-subs/environment-subs.ts | 127 +++--------------- .../libs/pre-conversion-subs/macro-subs.ts | 4 +- .../report-unsupported-macro-katex.ts | 35 ++--- .../libs/pre-conversion-subs/utils.ts | 23 ++-- 6 files changed, 162 insertions(+), 167 deletions(-) create mode 100644 packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts index ccfc2d5c..be9684cb 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/break-on-boundaries.ts @@ -13,6 +13,7 @@ import { } from "@unified-latex/unified-latex-util-split"; import { visit } from "@unified-latex/unified-latex-util-visit"; import { VFileMessage } from "vfile-message"; +import { makeWarningMessage } from "./utils"; /** * All the divisions, where each item is {division macro, mapped environment}. @@ -54,29 +55,15 @@ export function breakOnBoundaries(ast: Ast.Ast): { messages: VFileMessage[] } { return anyMacro(child) && isDivisionMacro(child); }) ) { - const message = new VFileMessage( - "Warning: hoisted out of a group, which might break the LaTeX code." + // add a warning message + messagesLst.messages.push( + makeWarningMessage( + node, + "Warning: hoisted out of a group, which might break the LaTeX code.", + "break-on-boundaries" + ) ); - // add the position of the group if available - if (node.position) { - message.line = node.position.start.line; - message.column = node.position.start.column; - message.position = { - start: { - line: node.position.start.line, - column: node.position.start.column, - }, - end: { - line: node.position.end.line, - column: node.position.end.column, - }, - }; - } - - message.source = "latex-to-pretext:warning"; - messagesLst.messages.push(message); - return node.content; } } diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts new file mode 100644 index 00000000..c9447994 --- /dev/null +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts @@ -0,0 +1,111 @@ +import * as Ast from "@unified-latex/unified-latex-types"; +import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; +import { + parseTabularSpec, + TabularColumn, +} from "@unified-latex/unified-latex-ctan/package/tabularx"; +import { parseAlignEnvironment } from "@unified-latex/unified-latex-util-align"; +import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; +import { trim } from "@unified-latex/unified-latex-util-trim"; + +type Attributes = Record>; + +/** + * Convert env into a tabular in pretext. + */ +export function createTableFromTabular(env: Ast.Environment) { + const tabularBody = parseAlignEnvironment(env.content); + const args = getArgsContent(env); + let columnSpecs: TabularColumn[] = []; + try { + columnSpecs = parseTabularSpec(args[1] || []); + } catch (e) {} + + // for the tabular tag + const attributes: Attributes = {}; + + // we only need the col tags if one of the columns aren't left aligned/have a border + let notLeftAligned: boolean = false; + + // stores which columns have borders to the right + // number is the column's index in columnSpecs + const columnRightBorder: Record = {}; + + const tableBody = tabularBody.map((row) => { + const content = row.cells.map((cell, i) => { + const columnSpec = columnSpecs[i]; + + if (columnSpec) { + const { alignment } = columnSpec; + + // this will need to be in the tabular tag + if ( + columnSpec.pre_dividers.some( + (div) => div.type === "vert_divider" + ) + ) { + attributes["left"] = "minor"; + } + + // check if the column has a right border + if ( + columnSpec.post_dividers.some( + (div) => div.type === "vert_divider" + ) + ) { + columnRightBorder[i] = true; + } + + // check if the default alignment isn't used + if (alignment.alignment !== "left") { + notLeftAligned = true; + } + } + + // trim whitespace off cell + trim(cell); + + return htmlLike({ + tag: "cell", + content: cell, + }); + }); + return htmlLike({ tag: "row", content }); + }); + + // add col tags if needed + if (notLeftAligned || Object.values(columnRightBorder).some((b) => b)) { + // go backwards since adding col tags to the front of the tableBody list + // otherwise, col tags will be in the reversed order + for (let i = columnSpecs.length; i >= 0; i--) { + const columnSpec = columnSpecs[i]; + + if (!columnSpec) { + continue; + } + + const colAttributes: Attributes = {}; + const { alignment } = columnSpec; + + // add h-align attribute if not default + if (alignment.alignment !== "left") { + colAttributes["halign"] = alignment.alignment; // supports all alignments but stuff like p{'width'} (closest is @colspan in cell) + } + + // if there is a right border add it + if (columnRightBorder[i] === true) { + colAttributes["right"] = "minor"; + } + + tableBody.unshift( + htmlLike({ tag: "col", attributes: colAttributes }) + ); + } + } + + return htmlLike({ + tag: "tabular", + content: tableBody, + attributes: attributes, + }); +} diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index cea97b00..2d49f624 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -1,20 +1,13 @@ -import { - parseTabularSpec, - TabularColumn, -} from "@unified-latex/unified-latex-ctan/package/tabularx"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import * as Ast from "@unified-latex/unified-latex-types"; -import { parseAlignEnvironment } from "@unified-latex/unified-latex-util-align"; -import { - getArgsContent, - getNamedArgsContent, -} from "@unified-latex/unified-latex-util-arguments"; +import { getNamedArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { match } from "@unified-latex/unified-latex-util-match"; import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; -import { trim } from "@unified-latex/unified-latex-util-trim"; import { VFile } from "vfile"; -import { emptyStringWithWarning } from "./utils"; +import { emptyStringWithWarning, makeWarningMessage } from "./utils"; +import { createTableFromTabular } from "./create-table-from-tabular"; +import { fileURLToPath } from "url"; const ITEM_ARG_NAMES_REG = ["label"] as const; const ITEM_ARG_NAMES_BEAMER = [null, "label", null] as const; @@ -99,104 +92,22 @@ function enumerateFactory(parentTag = "ol") { }; } -function createTableFromTabular(env: Ast.Environment) { - const tabularBody = parseAlignEnvironment(env.content); - const args = getArgsContent(env); - let columnSpecs: TabularColumn[] = []; - try { - columnSpecs = parseTabularSpec(args[1] || []); - } catch (e) {} - - // for the tabular tag - const attributes: Record> = {}; - - // we only need the col tags if one of the columns aren't left aligned/have a border - let notLeftAligned: boolean = false; - - // stores which columns have borders to the right - // number is the column's index in columnSpecs - const columnRightBorder: Record = {}; - - const tableBody = tabularBody.map((row) => { - const content = row.cells.map((cell, i) => { - const columnSpec = columnSpecs[i]; - - if (columnSpec) { - const { alignment } = columnSpec; - - // this will need to be in the tabular tag - if ( - columnSpec.pre_dividers.some( - (div) => div.type === "vert_divider" - ) - ) { - attributes["left"] = "minor"; - } - - // check if the column has a right border - if ( - columnSpec.post_dividers.some( - (div) => div.type === "vert_divider" - ) - ) { - columnRightBorder[i] = true; - } - - // check if the default alignment isn't used - if (alignment.alignment !== "left") { - notLeftAligned = true; - } - } - - // trim whitespace off cell - trim(cell); - - return htmlLike({ - tag: "cell", - content: cell, - }); - }); - return htmlLike({ tag: "row", content }); - }); - - // add col tags if needed - if (notLeftAligned || Object.values(columnRightBorder).some((b) => b)) { - // go backwards since adding col tags to the front of the tableBody list - // otherwise, col tags will be in the reversed order - for (let i = columnSpecs.length; i >= 0; i--) { - const columnSpec = columnSpecs[i]; - - if (!columnSpec) { - continue; - } - - const colAttributes: Record< - string, - string | Record - > = {}; - const { alignment } = columnSpec; - - // add h-align attribute if not default - if (alignment.alignment !== "left") { - colAttributes["halign"] = alignment.alignment; // supports all alignments but stuff like p{'width'} (closest is @colspan in cell) - } - - // if there is a right border add it - if (columnRightBorder[i] === true) { - colAttributes["right"] = "minor"; - } - - tableBody.unshift( - htmlLike({ tag: "col", attributes: colAttributes }) - ); - } - } +function removeCenterEnv( + center: Ast.Environment, + info: VisitInfo, + file?: VFile +) { + // add warning + file?.message( + makeWarningMessage( + center, + `Warning: There is no equivalent tag for \"center\", so the center environment was removed.`, + "environment-subs" + ) + ); - return htmlLike({ - tag: "tabular", - content: tableBody, - attributes: attributes, - }); + // can't return Node[] tho + return center.content; // or should it convert the stuff in here? or is that done already in plugin? } /** diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index de361f9b..853257b2 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -4,7 +4,7 @@ import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "unified-lint-rule/lib"; -import { createMessage, emptyStringWithWarning } from "./utils"; +import { makeWarningMessage, emptyStringWithWarning } from "./utils"; /** * Factory function that generates html-like macros that wrap their contents. @@ -27,7 +27,7 @@ function factory( // add a warning message to the file if needed if (warningMessage && file) { - const message = createMessage( + const message = makeWarningMessage( macro, `Warning: There is no equivalent tag for \"${macro.content}\", \"${tag}\" was used as a replacement.`, "macro-subs" diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts index 718a5829..152e1f4d 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/report-unsupported-macro-katex.ts @@ -3,6 +3,7 @@ import { anyMacro, match } from "@unified-latex/unified-latex-util-match"; import { visit } from "@unified-latex/unified-latex-util-visit"; import { KATEX_SUPPORT } from "./katex-subs"; import { VFileMessage } from "vfile-message"; +import { makeWarningMessage } from "./utils"; /** * Return a list of macros used in ast that are unsupported by KaTeX @@ -21,32 +22,16 @@ export function reportMacrosUnsupportedByKatex(ast: Ast.Ast): { if (anyMacro(node) && info.context.hasMathModeAncestor) { // check if not supported by katex if (!isSupported(node)) { - // get rid of type never - node = node as Ast.Macro; - - // create a message specifing the unsupported macro - const message = new VFileMessage( - `Warning: \"${node.content}\" is unsupported by Katex.` + // add a warning message + unsupported.messages.push( + makeWarningMessage( + node, + `Warning: \"${ + (node as Ast.Macro).content + }\" is unsupported by Katex.`, + "report-unsupported-macro-katex" + ) ); - - // add the position of the node if available - if (node.position) { - message.line = node.position.start.line; - message.column = node.position.start.column; - message.position = { - start: { - line: node.position.start.line, - column: node.position.start.column, - }, - end: { - line: node.position.end.line, - column: node.position.end.column, - }, - }; - } - - message.source = "latex-to-pretext:warning"; - unsupported.messages.push(message); } } }); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts index ff28e10e..927e0592 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts @@ -5,21 +5,18 @@ import { s } from "@unified-latex/unified-latex-builder"; import { VFileMessage } from "vfile-message"; /** - * Create a message about node from the given source file. + * Create a warning message about node from the given source file. */ -export function createMessage( +export function makeWarningMessage( node: Ast.Node, message: string, sourceFile: string ): VFileMessage { - const newMessage = new VFileMessage( - message, - node, - ); + const newMessage = new VFileMessage(message, node); - newMessage.source = `latex-to-pretext:${sourceFile}` + newMessage.source = `latex-to-pretext:${sourceFile}`; - return newMessage + return newMessage; } /** @@ -33,14 +30,18 @@ export function emptyStringWithWarning( return (node, info, file) => { // add a warning message if (file) { - const message = createMessage(node, warningMessage, sourceFile); + const message = makeWarningMessage( + node, + warningMessage, + sourceFile + ); file.message( message, message.position, - `unified-latex-to-pretext:${sourceFile}` + `unified-latex-to-pretext:${sourceFile}` // might not work like it doesn't in creat warning message ); } return s(""); }; -} \ No newline at end of file +} From 11a5182d5d07de682ccd32af05be241ccb99cc37 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 11 Aug 2024 19:49:09 -0400 Subject: [PATCH 55/62] fixed bug in to pretext file --- .../libs/pretext-subs/to-pretext.ts | 5 ++++- .../libs/unified-latex-plugin-to-xml-like.ts | 11 ++++++----- .../tests/unified-latex-to-pretext.test.ts | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index 606a2ad6..67d78bd5 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -116,7 +116,10 @@ export function toPretextWithLoggerFactory( const titleTag = x("title", title?.flatMap(toPretext)); if (divisionName && title) { - return x(divisionName, [titleTag]); + return x(divisionName, [ + titleTag, + ...node.content.flatMap(toPretext), + ]); } } diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index a2e67f38..3779214f 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -23,7 +23,10 @@ import { import { macroReplacements as _macroReplacements } from "./pre-conversion-subs/macro-subs"; import { streamingMacroReplacements } from "./pre-conversion-subs/streaming-command-subs"; import { unifiedLatexWrapPars } from "./unified-latex-wrap-pars"; -import { breakOnBoundaries, isMappedEnviron } from "./pre-conversion-subs/break-on-boundaries"; +import { + breakOnBoundaries, + isMappedEnviron, +} from "./pre-conversion-subs/break-on-boundaries"; import { reportMacrosUnsupportedByKatex } from "./pre-conversion-subs/report-unsupported-macro-katex"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; @@ -116,12 +119,11 @@ export const unifiedLatexToXmlLike: Plugin< // Must be done *after* streaming commands are replaced. // We only wrap PARs if we *need* to. That is, if the content contains multiple paragraphs + console.log(shouldBeWrappedInPars(tree)); if (shouldBeWrappedInPars(tree)) { processor = processor.use(unifiedLatexWrapPars); } - // *THIS CAUSES TITLE TO BE WRAPPED IN PARS tree = processor.runSync(tree, file); - //console.log(printRaw(tree)) // Replace text-mode environments and then macros. Environments *must* be processed first, since // environments like tabular use `\\` as a newline indicator, but a `\\` macro gets replaced with @@ -154,7 +156,6 @@ export const unifiedLatexToXmlLike: Plugin< return replacement; } }); - // before replacing math-mode macros, report any macros that can't be replaced const unsupportedByKatex = reportMacrosUnsupportedByKatex(tree); @@ -211,7 +212,7 @@ function shouldBeWrappedInPars(tree: Ast.Root): boolean { return EXIT; } }, - { test: (node) => match.environment(node, "document") || isMappedEnviron(node) } + { test: (node) => match.environment(node, "document") } ); return content.some( diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 4950b84b..9835c82c 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -274,9 +274,9 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ast = process(`\\paragraph{Important.} Paragraph`); expect(normalizeHtml(ast)).toEqual( - normalizeHtml(` - Important. Paragraph - `) + normalizeHtml( + `Important. Paragraph` + ) ); }); it("custom replacers work", () => { From 5c599855792ac2aeb375bb6ffb07021baaefcb7c Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 11 Aug 2024 20:22:42 -0400 Subject: [PATCH 56/62] changed structure of to pretext plugin --- .../libs/unified-latex-plugin-to-pretext.ts | 23 ++++++++++--------- .../tests/unified-latex-to-pretext.test.ts | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index fd6f0a3e..8bfa323e 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -11,7 +11,7 @@ import { unifiedLatexToXmlLike, PluginOptions as HtmlLikePluginOptions, } from "./unified-latex-plugin-to-xml-like"; -import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; +import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; export type PluginOptions = HtmlLikePluginOptions & { /** @@ -34,19 +34,11 @@ export const unifiedLatexToPretext: Plugin< ? options?.producePretextFragment : false; - // bring expandmacros in here instead - // getting authorinfo would be in here too - - unified().use(unifiedLatexToXmlLike, options).run(tree, file); - - // This should happen right before converting to HTML because macros like `\&` should - // be expanded via html rules first (and not turned into their corresponding ligature directly) - expandUnicodeLigatures(tree); + // expand user defined macros + expandUserDefinedMacros(tree); // If there is a \begin{document}...\end{document}, that's the only // content we want to convert. - // *move this to before xmllike called - // after done do tree.content = content (content in document env) let content = tree.content; visit( tree, @@ -65,6 +57,15 @@ export const unifiedLatexToPretext: Plugin< tree.content = content; + unified().use(unifiedLatexToXmlLike, options).run(tree, file); + + // This should happen right before converting to HTML because macros like `\&` should + // be expanded via html rules first (and not turned into their corresponding ligature directly) + expandUnicodeLigatures(tree); + + // update content + content = tree.content; + const toHast = toPretextWithLoggerFactory(file.message.bind(file)); let converted = toHast({ type: "root", content }); if (!Array.isArray(converted)) { diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 9835c82c..43634bcb 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -218,7 +218,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); html = process(`a\n b\\begin{foo}x\\end{foo}c\n\nd`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

        a b

        x

        c

        d

        `) + normalizeHtml(`

        a b

        x

        c

        d

        `) // Need to fix, since foo isn't an env in pretext and no div ); }); From 1fe0c37bafccd1771e1b2c815cbf16589a6c319d Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Sun, 11 Aug 2024 23:48:23 -0400 Subject: [PATCH 57/62] fixed comments using html to using pretext --- .../pre-conversion-subs/environment-subs.ts | 3 +-- .../libs/pre-conversion-subs/macro-subs.ts | 9 +------ .../libs/pre-conversion-subs/utils.ts | 2 +- .../libs/pretext-subs/to-pretext.ts | 5 ++-- .../libs/unified-latex-plugin-to-pretext.ts | 6 ++--- .../libs/unified-latex-plugin-to-xml-like.ts | 25 ++++++++++--------- 6 files changed, 22 insertions(+), 28 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 2d49f624..bbdd975a 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -7,7 +7,6 @@ import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "vfile"; import { emptyStringWithWarning, makeWarningMessage } from "./utils"; import { createTableFromTabular } from "./create-table-from-tabular"; -import { fileURLToPath } from "url"; const ITEM_ARG_NAMES_REG = ["label"] as const; const ITEM_ARG_NAMES_BEAMER = [null, "label", null] as const; @@ -112,7 +111,7 @@ function removeCenterEnv( /** * Rules for replacing a macro with an html-like macro - * that will render has html when printed. + * that will render has pretext when printed. */ export const environmentReplacements: Record< string, diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index 853257b2..b36e0b38 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -32,11 +32,7 @@ function factory( `Warning: There is no equivalent tag for \"${macro.content}\", \"${tag}\" was used as a replacement.`, "macro-subs" ); - file.message( - message, - message.position, - message.source // check if rule id still given - ); + file.message(message, message.position, message.source); } // Assume the meaningful argument is the last argument. This @@ -51,7 +47,6 @@ function factory( function createHeading(tag: string, attrs = {}) { return (macro: Ast.Macro) => { const args = getArgsContent(macro); - // const starred = !!args[0]; const attributes: Record = {}; if (attrs) { @@ -66,8 +61,6 @@ function createHeading(tag: string, attrs = {}) { }; } -// put this and createMessage in a utils file - export const macroReplacements: Record< string, (node: Ast.Macro, info: VisitInfo, file?: VFile) => Ast.Node diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts index 927e0592..6b882ef9 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts @@ -14,7 +14,7 @@ export function makeWarningMessage( ): VFileMessage { const newMessage = new VFileMessage(message, node); - newMessage.source = `latex-to-pretext:${sourceFile}`; + newMessage.source = `unified-latex-to-pretext:${sourceFile}`; return newMessage; } diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index 67d78bd5..fff9a8dc 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -28,7 +28,7 @@ export function toPretextWithLoggerFactory( logger: (message: string, node: any) => void ) { /** - * Convert Ast.Node to Hast nodes. + * Convert Ast.Node to Xast nodes. */ return function toPretext( node: Ast.Node | Ast.Argument @@ -129,7 +129,7 @@ export function toPretextWithLoggerFactory( )}\``, node ); - return x("div", node.content.flatMap(toPretext)); + return x("div", node.content.flatMap(toPretext)); // div not in pretext case "macro": logger( `Unknown macro when converting to HTML \`${formatNodeForError( @@ -140,6 +140,7 @@ export function toPretextWithLoggerFactory( return x("span", (node.args || []).map(toPretext).flat()); case "argument": return x( + // span not in pretext "span", { "data-open-mark": node.openMark, diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 8bfa323e..91df9826 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -59,15 +59,15 @@ export const unifiedLatexToPretext: Plugin< unified().use(unifiedLatexToXmlLike, options).run(tree, file); - // This should happen right before converting to HTML because macros like `\&` should + // This should happen right before converting to pretext because macros like `\&` should // be expanded via html rules first (and not turned into their corresponding ligature directly) expandUnicodeLigatures(tree); // update content content = tree.content; - const toHast = toPretextWithLoggerFactory(file.message.bind(file)); - let converted = toHast({ type: "root", content }); + const toXast = toPretextWithLoggerFactory(file.message.bind(file)); + let converted = toXast({ type: "root", content }); if (!Array.isArray(converted)) { converted = [converted]; } diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index 3779214f..a3be9d35 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -119,7 +119,6 @@ export const unifiedLatexToXmlLike: Plugin< // Must be done *after* streaming commands are replaced. // We only wrap PARs if we *need* to. That is, if the content contains multiple paragraphs - console.log(shouldBeWrappedInPars(tree)); if (shouldBeWrappedInPars(tree)) { processor = processor.use(unifiedLatexWrapPars); } @@ -183,7 +182,6 @@ export const unifiedLatexToXmlLike: Plugin< }); // Wrap in enough tags to ensure a valid pretext document - // but if there is a document env, want to only wrap that if (!producePretextFragment) { // choose a book or article tag createValidPretextDoc(tree); @@ -215,20 +213,27 @@ function shouldBeWrappedInPars(tree: Ast.Root): boolean { { test: (node) => match.environment(node, "document") } ); - return content.some( - (node) => match.parbreak(node) || match.macro(node, "par") - ); + return containsPar(content); +} + +function containsPar(content: Ast.Node[]): boolean { + return content.some((node) => { + if (isMappedEnviron(node)) { + return containsPar(node.content); + } + + return match.parbreak(node) || match.macro(node, "par"); + }); } /** * Wrap the tree content in a book or article tag. */ function createValidPretextDoc(tree: Ast.Root): void { - // very early on get the content in the document tag if there is one // this will be incomplete since the author info isn't pushed yet, which obtains documentclass, title, etc. let isBook: boolean = false; - // look for a \documentclass + // look for a \documentclass (this will need to change, as this info will be gotten earlier) const docClass = findMacro(tree, "documentclass"); // check if there was a documentclass @@ -261,12 +266,8 @@ function createValidPretextDoc(tree: Ast.Root): void { // a book and article tag must have a title tag right after it // extract the title first - // wrap the document env since title is before it, dissapears - // but this assumes that this is only put as false when a document env is used, but if not then would still have duplicate const title = findMacro(tree, "title"); - // create the title tag (this part doesn't work, adds a bunch of spans, repeats title name) - // this happens before this function is called, likely from wrap pars if (title) { const titleArg = getArgsContent(title)[1]; @@ -295,7 +296,7 @@ function createValidPretextDoc(tree: Ast.Root): void { } } -// maybe could use match instead, could be slower tho since likely goes into environments +// this will likely be removed function findMacro(tree: Ast.Root, content: string): Ast.Macro | null { let macro: Ast.Macro | null = null; From 3ae132c34bc7774555efbeac01e6cac2f47f6c89 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Mon, 12 Aug 2024 22:06:25 -0400 Subject: [PATCH 58/62] cleaned up code --- .../libs/pre-conversion-subs/create-table-from-tabular.ts | 2 +- .../libs/pre-conversion-subs/environment-subs.ts | 3 +-- .../libs/pre-conversion-subs/utils.ts | 2 +- .../unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts | 4 ++-- .../libs/unified-latex-plugin-to-pretext.ts | 4 ++-- .../libs/unified-latex-plugin-to-xml-like.ts | 3 ++- .../tests/unified-latex-to-pretext.test.ts | 4 +--- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts index c9447994..f969879b 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts @@ -11,7 +11,7 @@ import { trim } from "@unified-latex/unified-latex-util-trim"; type Attributes = Record>; /** - * Convert env into a tabular in pretext. + * Convert env into a tabular in PreTeXt. */ export function createTableFromTabular(env: Ast.Environment) { const tabularBody = parseAlignEnvironment(env.content); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index bbdd975a..f122d6cb 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -105,8 +105,7 @@ function removeCenterEnv( ) ); - // can't return Node[] tho - return center.content; // or should it convert the stuff in here? or is that done already in plugin? + return center.content; } /** diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts index 6b882ef9..c8d30d23 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts @@ -38,7 +38,7 @@ export function emptyStringWithWarning( file.message( message, message.position, - `unified-latex-to-pretext:${sourceFile}` // might not work like it doesn't in creat warning message + `unified-latex-to-pretext:${sourceFile}` ); } diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index fff9a8dc..4cc590d1 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -97,7 +97,7 @@ export function toPretextWithLoggerFactory( // for subparagraph, give a warning since pretext has no equivalent tag if (divisionName === "subparagraph") { logger( - `There is no equivalent tag for "subparagraph", so it was replaced with a "paragraphs." tag`, + `Warning: There is no equivalent tag for "subparagraph", "paragraphs" was used as a replacement.`, node ); } @@ -163,6 +163,6 @@ export function toPretextWithLoggerFactory( } /** - * Convert Ast.Node to Hast nodes. + * Convert Ast.Node to Xast nodes. */ export const toPretext = toPretextWithLoggerFactory(console.warn); diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 91df9826..397cf82b 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -59,7 +59,7 @@ export const unifiedLatexToPretext: Plugin< unified().use(unifiedLatexToXmlLike, options).run(tree, file); - // This should happen right before converting to pretext because macros like `\&` should + // This should happen right before converting to PreTeXt because macros like `\&` should // be expanded via html rules first (and not turned into their corresponding ligature directly) expandUnicodeLigatures(tree); @@ -71,7 +71,7 @@ export const unifiedLatexToPretext: Plugin< if (!Array.isArray(converted)) { converted = [converted]; } - // Wrap everything in a Hast.Root node + // Wrap everything in a Xast.Root node let ret = x(); ret.children = converted; diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index a3be9d35..9dfeb737 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -126,7 +126,7 @@ export const unifiedLatexToXmlLike: Plugin< // Replace text-mode environments and then macros. Environments *must* be processed first, since // environments like tabular use `\\` as a newline indicator, but a `\\` macro gets replaced with - // a `
        ` during macro replacement. + // an empty Ast.String during macro replacement. replaceNode(tree, (node, info) => { // Children of math-mode are rendered by KaTeX/MathJax and so we shouldn't touch them! if (info.context.hasMathModeAncestor) { @@ -194,6 +194,7 @@ export const unifiedLatexToXmlLike: Plugin< // Make sure we are actually mutating the current tree. originalTree.content = tree.content; + console.log(file.messages) }; }; diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 43634bcb..01bff274 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -133,7 +133,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { `
      12. x)

        a

      13. b

      14. -
        ` // list is centered though +
        ` ) ); }); @@ -171,8 +171,6 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { html = process(`\\begin{tabular}{l l}a & b\\\\c & d\\end{tabular}`); expect(normalizeHtml(html)).toEqual( - // centered tho - // can fix with margins="0%" normalizeHtml( `abcd` ) From 6737ed36142fccac812ad3c2c786400bf7fd3897 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Tue, 13 Aug 2024 22:37:59 -0400 Subject: [PATCH 59/62] fixed last test case and removed only center env --- .../pre-conversion-subs/environment-subs.ts | 25 ++++++++----------- .../libs/unified-latex-plugin-to-pretext.ts | 1 + .../libs/unified-latex-plugin-to-xml-like.ts | 2 +- .../libs/unified-latex-wrap-pars.ts | 4 +-- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index f122d6cb..2d7ed9c0 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -5,7 +5,7 @@ import { match } from "@unified-latex/unified-latex-util-match"; import { wrapPars } from "../wrap-pars"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "vfile"; -import { emptyStringWithWarning, makeWarningMessage } from "./utils"; +import { makeWarningMessage } from "./utils"; import { createTableFromTabular } from "./create-table-from-tabular"; const ITEM_ARG_NAMES_REG = ["label"] as const; @@ -91,21 +91,21 @@ function enumerateFactory(parentTag = "ol") { }; } -function removeCenterEnv( - center: Ast.Environment, - info: VisitInfo, - file?: VFile -) { +/** + * + * Remove the env environment by returning the content in env only. + */ +function removeEnv(env: Ast.Environment, info: VisitInfo, file?: VFile) { // add warning file?.message( makeWarningMessage( - center, - `Warning: There is no equivalent tag for \"center\", so the center environment was removed.`, + env, + `Warning: There is no equivalent tag for \"${env.env}\", so the ${env.env} environment was removed.`, "environment-subs" ) ); - return center.content; + return env.content; } /** @@ -118,14 +118,11 @@ export const environmentReplacements: Record< node: Ast.Environment, info: VisitInfo, file?: VFile - ) => Ast.Macro | Ast.String | Ast.Environment + ) => Ast.Macro | Ast.String | Ast.Environment | Ast.Node[] > = { enumerate: enumerateFactory("ol"), itemize: enumerateFactory("ul"), - center: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"center\", an empty Ast.String was used as a replacement.`, - "environment-subs" - ), + center: removeEnv, tabular: createTableFromTabular, quote: (env) => { return htmlLike({ diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 397cf82b..134661ce 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -55,6 +55,7 @@ export const unifiedLatexToPretext: Plugin< } ); + // since we don't want to wrap content outside of \begin{document}...\end{document} with ... tree.content = content; unified().use(unifiedLatexToXmlLike, options).run(tree, file); diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts index 9dfeb737..f45361e5 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts @@ -194,7 +194,7 @@ export const unifiedLatexToXmlLike: Plugin< // Make sure we are actually mutating the current tree. originalTree.content = tree.content; - console.log(file.messages) + console.log(file.messages); }; }; diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts b/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts index 78c52f9f..a6f193ca 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-wrap-pars.ts @@ -1,7 +1,7 @@ import { Plugin } from "unified"; import * as Ast from "@unified-latex/unified-latex-types"; import { match } from "@unified-latex/unified-latex-util-match"; -import { EXIT, visit } from "@unified-latex/unified-latex-util-visit"; +import { visit } from "@unified-latex/unified-latex-util-visit"; import { wrapPars } from "./wrap-pars"; import { isMappedEnviron } from "./pre-conversion-subs/break-on-boundaries"; type PluginOptions = { @@ -38,8 +38,6 @@ export const unifiedLatexWrapPars: Plugin = macrosThatBreakPars, environmentsThatDontBreakPars, }); - - return EXIT; } }, { test: match.anyEnvironment } From a09daa96b5a58d8be3d49134560616adc945c2e7 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Wed, 14 Aug 2024 19:20:14 -0400 Subject: [PATCH 60/62] changed div and span fallbacks --- .../libs/pretext-subs/to-pretext.ts | 28 ++++++++++--------- .../tests/unified-latex-to-pretext.test.ts | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index 4cc590d1..fef0950a 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -124,36 +124,38 @@ export function toPretextWithLoggerFactory( } logger( - `Unknown environment when converting to HTML \`${formatNodeForError( + `Unknown environment when converting to XML \`${formatNodeForError( node.env )}\``, node ); - return x("div", node.content.flatMap(toPretext)); // div not in pretext + return node.content.flatMap(toPretext); // just remove the environment case "macro": logger( - `Unknown macro when converting to HTML \`${formatNodeForError( + `Unknown macro when converting to XML \`${formatNodeForError( node )}\``, node ); - return x("span", (node.args || []).map(toPretext).flat()); + return (node.args || []).map(toPretext).flat(); case "argument": - return x( - // span not in pretext - "span", - { - "data-open-mark": node.openMark, - "data-close-mark": node.closeMark, - }, - printRaw(node.content) + logger( + `Unknown argument when converting to XML \`${formatNodeForError( + node + )}\``, + node ); + return { + type: "text", + value: printRaw(node.content), + position: node.position, + }; case "root": return node.content.flatMap(toPretext); default: { const _exhaustiveCheck: never = node; throw new Error( - `Unknown node type; cannot convert to HAST ${JSON.stringify( + `Unknown node type; cannot convert to XAST ${JSON.stringify( node )}` ); diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts index 01bff274..f3e3f026 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-pretext.test.ts @@ -216,7 +216,7 @@ describe("unified-latex-to-pretext:unified-latex-to-pretext", () => { ); html = process(`a\n b\\begin{foo}x\\end{foo}c\n\nd`); expect(normalizeHtml(html)).toEqual( - normalizeHtml(`

        a b

        x

        c

        d

        `) // Need to fix, since foo isn't an env in pretext and no div + normalizeHtml(`

        a b

        x

        c

        d

        `) ); }); From d5b50f9ffa7c0b782dd71e0dda2e200f8e6ce396 Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:49:07 -0400 Subject: [PATCH 61/62] cleaned up code again --- .../libs/pre-conversion-subs/create-table-from-tabular.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts index f969879b..e51494ab 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/create-table-from-tabular.ts @@ -89,7 +89,7 @@ export function createTableFromTabular(env: Ast.Environment) { // add h-align attribute if not default if (alignment.alignment !== "left") { - colAttributes["halign"] = alignment.alignment; // supports all alignments but stuff like p{'width'} (closest is @colspan in cell) + colAttributes["halign"] = alignment.alignment; } // if there is a right border add it From c359495e02f6a0468533dca045901aa7a40ad3dc Mon Sep 17 00:00:00 2001 From: Nahlee Naria Khan <95993773+renee-k@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:36:32 -0400 Subject: [PATCH 62/62] fixed all new PR comments --- .../pre-conversion-subs/environment-subs.ts | 1 - .../libs/pre-conversion-subs/macro-subs.ts | 44 ++++++++----------- .../libs/pre-conversion-subs/utils.ts | 13 +++--- .../libs/pretext-subs/to-pretext.ts | 9 +++- ...> unified-latex-plugin-to-pretext-like.ts} | 2 +- .../libs/unified-latex-plugin-to-pretext.ts | 6 +-- .../tests/unified-latex-to-xml-like.test.ts | 6 +-- 7 files changed, 39 insertions(+), 42 deletions(-) rename packages/unified-latex-to-pretext/libs/{unified-latex-plugin-to-xml-like.ts => unified-latex-plugin-to-pretext-like.ts} (99%) diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts index 2d7ed9c0..7f6ab9a6 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/environment-subs.ts @@ -92,7 +92,6 @@ function enumerateFactory(parentTag = "ol") { } /** - * * Remove the env environment by returning the content in env only. */ function removeEnv(env: Ast.Environment, info: VisitInfo, file?: VFile) { diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts index b36e0b38..93e37f13 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/macro-subs.ts @@ -4,7 +4,7 @@ import { getArgsContent } from "@unified-latex/unified-latex-util-arguments"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; import { VisitInfo } from "@unified-latex/unified-latex-util-visit"; import { VFile } from "unified-lint-rule/lib"; -import { makeWarningMessage, emptyStringWithWarning } from "./utils"; +import { makeWarningMessage, emptyStringWithWarningFactory } from "./utils"; /** * Factory function that generates html-like macros that wrap their contents. @@ -88,13 +88,11 @@ export const macroReplacements: Record< "em", `Warning: There is no equivalent tag for \"underline\", \"em\" was used as a replacement.` ), - mbox: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"mbox\", an empty Ast.String was used as a replacement.`, - "macro-subs" + mbox: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"mbox\", an empty Ast.String was used as a replacement.` ), - phantom: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"phantom\", an empty Ast.String was used as a replacement.`, - "macro-subs" + phantom: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"phantom\", an empty Ast.String was used as a replacement.` ), appendix: createHeading("appendix"), url: (node) => { @@ -130,33 +128,27 @@ export const macroReplacements: Record< content: args[1] || [], }); }, - "\\": emptyStringWithWarning( - `Warning: There is no equivalent tag for \"\\\", an empty Ast.String was used as a replacement.`, - "macro-subs" + "\\": emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"\\\", an empty Ast.String was used as a replacement.` ), - vspace: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"vspace\", an empty Ast.String was used as a replacement.`, - "macro-subs" + vspace: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"vspace\", an empty Ast.String was used as a replacement.` ), - hspace: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"hspace\", an empty Ast.String was used as a replacement.`, - "macro-subs" + hspace: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"hspace\", an empty Ast.String was used as a replacement.` ), textcolor: factory( "em", `Warning: There is no equivalent tag for \"textcolor\", \"em\" was used as a replacement.` ), - textsize: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"textsize\", an empty Ast.String was used as a replacement.`, - "macro-subs" + textsize: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"textsize\", an empty Ast.String was used as a replacement.` ), - makebox: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"makebox\", an empty Ast.String was used as a replacement.`, - "macro-subs" - ), // remove for now - noindent: emptyStringWithWarning( - `Warning: There is no equivalent tag for \"noindent\", an empty Ast.String was used as a replacement.`, - "macro-subs" + makebox: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"makebox\", an empty Ast.String was used as a replacement.` + ), + noindent: emptyStringWithWarningFactory( + `Warning: There is no equivalent tag for \"noindent\", an empty Ast.String was used as a replacement.` ), includegraphics: (node) => { const args = getArgsContent(node); diff --git a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts index c8d30d23..5b958af5 100644 --- a/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts +++ b/packages/unified-latex-to-pretext/libs/pre-conversion-subs/utils.ts @@ -10,11 +10,11 @@ import { VFileMessage } from "vfile-message"; export function makeWarningMessage( node: Ast.Node, message: string, - sourceFile: string + warningType: string ): VFileMessage { const newMessage = new VFileMessage(message, node); - newMessage.source = `unified-latex-to-pretext:${sourceFile}`; + newMessage.source = `unified-latex-to-pretext:${warningType}`; return newMessage; } @@ -23,9 +23,8 @@ export function makeWarningMessage( * Create an empty Ast.String node, adding a warning message from * the source file into the VFile. */ -export function emptyStringWithWarning( - warningMessage: string, - sourceFile: string +export function emptyStringWithWarningFactory( + warningMessage: string ): (node: Ast.Node, info: VisitInfo, file?: VFile) => Ast.String { return (node, info, file) => { // add a warning message @@ -33,12 +32,12 @@ export function emptyStringWithWarning( const message = makeWarningMessage( node, warningMessage, - sourceFile + "macro-subs" ); file.message( message, message.position, - `unified-latex-to-pretext:${sourceFile}` + `unified-latex-to-pretext:macro-subs` ); } diff --git a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts index fef0950a..a76f553b 100644 --- a/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/pretext-subs/to-pretext.ts @@ -113,9 +113,16 @@ export function toPretextWithLoggerFactory( // create a title tag containing the division macro's title arg const title = getArgsContent(node)[0]; + if (!title) { + logger( + `Warning: No title was given, so an empty title tag was used.`, + node + ); + } + const titleTag = x("title", title?.flatMap(toPretext)); - if (divisionName && title) { + if (divisionName) { return x(divisionName, [ titleTag, ...node.content.flatMap(toPretext), diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext-like.ts similarity index 99% rename from packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts rename to packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext-like.ts index f45361e5..56d51e85 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-xml-like.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext-like.ts @@ -61,7 +61,7 @@ export type PluginOptions = { * * Note: this plugin only wraps paragraphs in `p` tags if there are multiple paragraphs. Otherwise it omits the

        tags. */ -export const unifiedLatexToXmlLike: Plugin< +export const unifiedLatexToPretextLike: Plugin< PluginOptions[], Ast.Root, Hast.Root diff --git a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts index 134661ce..63cba56f 100644 --- a/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts +++ b/packages/unified-latex-to-pretext/libs/unified-latex-plugin-to-pretext.ts @@ -8,9 +8,9 @@ import { match } from "@unified-latex/unified-latex-util-match"; import { EXIT, visit } from "@unified-latex/unified-latex-util-visit"; import { toPretextWithLoggerFactory } from "./pretext-subs/to-pretext"; import { - unifiedLatexToXmlLike, + unifiedLatexToPretextLike, PluginOptions as HtmlLikePluginOptions, -} from "./unified-latex-plugin-to-xml-like"; +} from "./unified-latex-plugin-to-pretext-like"; import { expandUserDefinedMacros } from "./pre-conversion-subs/expand-user-defined-macros"; export type PluginOptions = HtmlLikePluginOptions & { @@ -58,7 +58,7 @@ export const unifiedLatexToPretext: Plugin< // since we don't want to wrap content outside of \begin{document}...\end{document} with ... tree.content = content; - unified().use(unifiedLatexToXmlLike, options).run(tree, file); + unified().use(unifiedLatexToPretextLike, options).run(tree, file); // This should happen right before converting to PreTeXt because macros like `\&` should // be expanded via html rules first (and not turned into their corresponding ligature directly) diff --git a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts index 86f8ddce..4fbb6545 100644 --- a/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts +++ b/packages/unified-latex-to-pretext/tests/unified-latex-to-xml-like.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import { processLatexViaUnified } from "@unified-latex/unified-latex"; import { VFile } from "vfile"; import util from "util"; -import { unifiedLatexToXmlLike } from "../libs/unified-latex-plugin-to-xml-like"; +import { unifiedLatexToPretextLike } from "../libs/unified-latex-plugin-to-pretext-like"; import { htmlLike } from "@unified-latex/unified-latex-util-html-like"; import { printRaw } from "@unified-latex/unified-latex-util-print-raw"; @@ -18,7 +18,7 @@ describe("unified-latex-to-pretext:unified-latex-to-xml-like", () => { let file: VFile; const process = (value: string) => processLatexViaUnified() - .use(unifiedLatexToXmlLike, { producePretextFragment: true }) + .use(unifiedLatexToPretextLike, { producePretextFragment: true }) .processSync({ value }); it("wrap pars and streaming commands", () => { @@ -46,7 +46,7 @@ describe("unified-latex-to-pretext:unified-latex-to-xml-like", () => { it("can accept custom replacers", () => { const process = (value: string) => processLatexViaUnified({ macros: { xxx: { signature: "m m" } } }) - .use(unifiedLatexToXmlLike, { + .use(unifiedLatexToPretextLike, { macroReplacements: { xxx: (node) => htmlLike({