Comparing version 0.0.19 to 0.1.20
@@ -190,2 +190,6 @@ // src/parser.ts | ||
throw new KatexNodeToTexNodeError(`Unknown error type in parsed result:`, node); | ||
case "comment": | ||
res.type = "comment"; | ||
res.content = node.text; | ||
break; | ||
default: | ||
@@ -200,2 +204,40 @@ throw new KatexNodeToTexNodeError(`Unknown node type: ${node.type}`, node); | ||
} | ||
function splitTex(tex) { | ||
const lines = tex.split("\n"); | ||
const out_tex_list = []; | ||
let current_tex = ""; | ||
for (let i = 0;i < lines.length; i++) { | ||
const line = lines[i]; | ||
let index = -1; | ||
while (index + 1 < line.length) { | ||
index = line.indexOf("%", index + 1); | ||
if (index === -1) { | ||
break; | ||
} | ||
if (index === 0 || line[index - 1] !== "\\") { | ||
break; | ||
} | ||
} | ||
if (index !== -1) { | ||
current_tex += line.substring(0, index); | ||
const comment = line.substring(index); | ||
out_tex_list.push(current_tex); | ||
current_tex = ""; | ||
out_tex_list.push(comment); | ||
} else { | ||
current_tex += line; | ||
} | ||
if (i < lines.length - 1) { | ||
const has_begin_command = line.includes("\\begin{"); | ||
const followed_by_end_command = lines[i + 1].includes("\\end{"); | ||
if (!has_begin_command && !followed_by_end_command) { | ||
current_tex += "\\SyMbOlNeWlInE "; | ||
} | ||
} | ||
} | ||
if (current_tex.length > 0) { | ||
out_tex_list.push(current_tex); | ||
} | ||
return out_tex_list; | ||
} | ||
function parseTex(tex, customTexMacros) { | ||
@@ -218,2 +260,3 @@ const macros = { | ||
"\\TeX": "\\operatorname{SyMb01-TeX}", | ||
"\\SyMbOlNeWlInE": "\\operatorname{SyMb01-newline}", | ||
...customTexMacros | ||
@@ -227,3 +270,17 @@ }; | ||
}; | ||
let treeArray = generateParseTree(tex, options); | ||
const tex_list = splitTex(tex); | ||
let treeArray = []; | ||
for (const tex_item of tex_list) { | ||
if (tex_item.startsWith("%")) { | ||
const tex_node = { | ||
type: "comment", | ||
mode: "math", | ||
text: tex_item.substring(1) | ||
}; | ||
treeArray.push(tex_node); | ||
continue; | ||
} | ||
const trees = generateParseTree(tex_item, options); | ||
treeArray = treeArray.concat(trees); | ||
} | ||
let t = { | ||
@@ -521,3 +578,5 @@ type: "ordgroup", | ||
} else if (token === "\\\\") { | ||
return "\\\n"; | ||
return "\\"; | ||
} else if (token == "/") { | ||
return "\\/"; | ||
} else if (["\\$", "\\#", "\\&", "\\_"].includes(token)) { | ||
@@ -575,2 +634,3 @@ return token; | ||
no_need_space ||= /[\(\[{]\s*(-|\+)$/.test(this.buffer) || this.buffer === "-" || this.buffer === "+"; | ||
no_need_space ||= str.startsWith("\n"); | ||
no_need_space ||= this.buffer === ""; | ||
@@ -706,3 +766,8 @@ no_need_space ||= /[\s"_^{\(]$/.test(this.buffer); | ||
} else if (text.startsWith("SyMb01-")) { | ||
this.queue.push({ type: "symbol", content: "\\" + text.substring(7) }); | ||
const special_symbol = text.substring(7); | ||
if (special_symbol === "newline") { | ||
this.queue.push({ type: "newline", content: "\n" }); | ||
return; | ||
} | ||
this.queue.push({ type: "symbol", content: "\\" + special_symbol }); | ||
} else { | ||
@@ -744,2 +809,3 @@ this.queue.push({ type: "symbol", content: "op" }); | ||
if (cell.type === "ordgroup" && cell.args.length === 0) { | ||
this.queue.push({ type: "atom", content: "," }); | ||
return; | ||
@@ -765,2 +831,4 @@ } | ||
} | ||
} else if (node.type === "comment") { | ||
this.queue.push({ type: "comment", content: node.content }); | ||
} else { | ||
@@ -787,2 +855,8 @@ throw new TypstWriterError(`Unimplemented node type to append: ${node.type}`, node); | ||
break; | ||
case "comment": | ||
str = `//${node.content}`; | ||
break; | ||
case "newline": | ||
str = "\n"; | ||
break; | ||
default: | ||
@@ -789,0 +863,0 @@ throw new TypstWriterError(`Unexpected node type to stringify: ${node.type}`, node); |
@@ -22,3 +22,3 @@ export interface KatexParseNode { | ||
export interface TypstNode { | ||
type: 'atom' | 'symbol' | 'text' | 'softSpace'; | ||
type: 'atom' | 'symbol' | 'text' | 'softSpace' | 'comment' | 'newline'; | ||
content: string; | ||
@@ -25,0 +25,0 @@ args?: TypstNode[]; |
{ | ||
"name": "tex2typst", | ||
"version": "0.0.19", | ||
"version": "0.1.20", | ||
"description": "JavaScript library for converting TeX code to Typst", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -19,8 +19,8 @@ # tex2typst | ||
```html | ||
<script src="https://cdn.jsdelivr.net/npm/tex2typst@0.0.19/dist/tex2typst.min.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/tex2typst@0.1.20/dist/tex2typst.min.js"></script> | ||
<!-- or --> | ||
<script src="https://unpkg.com/tex2typst@0.0.19/dist/tex2typst.min.js"></script> | ||
<script src="https://unpkg.com/tex2typst@0.1.20/dist/tex2typst.min.js"></script> | ||
``` | ||
Replace `0.0.19` with the latest version number in case this README is outdated. | ||
Replace `0.1.20` with the latest version number in case this README is outdated. | ||
@@ -27,0 +27,0 @@ ## Usage |
@@ -231,2 +231,6 @@ // @ts-ignore | ||
throw new KatexNodeToTexNodeError(`Unknown error type in parsed result:`, node); | ||
case 'comment': | ||
res.type = 'comment'; | ||
res.content = node.text!; | ||
break; | ||
default: | ||
@@ -242,2 +246,57 @@ throw new KatexNodeToTexNodeError(`Unknown node type: ${node.type}`, node); | ||
// Split tex into a list of tex strings and comments. | ||
// Each item in the returned list is either a tex snippet or a comment. | ||
// Each comment item is a string starting with '%'. | ||
function splitTex(tex: string): string[] { | ||
const lines = tex.split("\n"); | ||
const out_tex_list: string[] = []; | ||
let current_tex = ""; | ||
// let inside_begin_depth = 0; | ||
for (let i = 0; i < lines.length; i++) { | ||
const line = lines[i]; | ||
// if (line.includes('\\begin{')) { | ||
// inside_begin_depth += line.split('\\begin{').length - 1; | ||
// } | ||
let index = -1; | ||
while (index + 1 < line.length) { | ||
index = line.indexOf('%', index + 1); | ||
if (index === -1) { | ||
// No comment in this line | ||
break; | ||
} | ||
if (index === 0 || line[index - 1] !== '\\') { | ||
// Found a comment | ||
break; | ||
} | ||
} | ||
if (index !== -1) { | ||
current_tex += line.substring(0, index); | ||
const comment = line.substring(index); | ||
out_tex_list.push(current_tex); | ||
current_tex = ""; | ||
out_tex_list.push(comment); | ||
} else { | ||
current_tex += line; | ||
} | ||
if (i < lines.length - 1) { | ||
const has_begin_command = line.includes('\\begin{'); | ||
const followed_by_end_command = lines[i + 1].includes('\\end{'); | ||
if(!has_begin_command && !followed_by_end_command) { | ||
current_tex += "\\SyMbOlNeWlInE "; | ||
} | ||
} | ||
// if (line.includes('\\end{')) { | ||
// inside_begin_depth -= line.split('\\end{').length - 1; | ||
// } | ||
} | ||
if (current_tex.length > 0) { | ||
out_tex_list.push(current_tex); | ||
} | ||
return out_tex_list; | ||
} | ||
export function parseTex(tex: string, customTexMacros: {[key: string]: string}): TexNode { | ||
@@ -262,2 +321,3 @@ // displayMode=true. Otherwise, "KaTeX parse error: {align*} can be used only in display mode." | ||
'\\TeX': '\\operatorname{SyMb01-TeX}', | ||
'\\SyMbOlNeWlInE': '\\operatorname{SyMb01-newline}', | ||
...customTexMacros | ||
@@ -271,3 +331,21 @@ }; | ||
}; | ||
let treeArray = generateParseTree(tex, options); | ||
const tex_list = splitTex(tex); | ||
let treeArray: KatexParseNode[] = []; | ||
for (const tex_item of tex_list) { | ||
if (tex_item.startsWith('%')) { | ||
const tex_node: KatexParseNode = { | ||
type: 'comment', | ||
mode: 'math', | ||
text: tex_item.substring(1), | ||
}; | ||
treeArray.push(tex_node); | ||
continue; | ||
} | ||
const trees = generateParseTree(tex_item, options); | ||
treeArray = treeArray.concat(trees); | ||
} | ||
let t = { | ||
@@ -274,0 +352,0 @@ type: 'ordgroup', |
@@ -31,3 +31,3 @@ export interface KatexParseNode { | ||
export interface TypstNode { | ||
type: 'atom' | 'symbol' | 'text' | 'softSpace'; | ||
type: 'atom' | 'symbol' | 'text' | 'softSpace' | 'comment' | 'newline', | ||
content: string; | ||
@@ -34,0 +34,0 @@ args?: TypstNode[]; |
@@ -58,2 +58,4 @@ import { symbolMap } from "./map"; | ||
no_need_space ||= /[\(\[{]\s*(-|\+)$/.test(this.buffer) || this.buffer === "-" || this.buffer === "+"; | ||
// new line | ||
no_need_space ||= str.startsWith('\n'); | ||
// buffer is empty | ||
@@ -214,3 +216,8 @@ no_need_space ||= this.buffer === ""; | ||
// special hacks made in parseTex() | ||
this.queue.push({ type: 'symbol', content: '\\' + text.substring(7)}); | ||
const special_symbol = text.substring(7); | ||
if (special_symbol === 'newline') { | ||
this.queue.push({ type: 'newline', content: '\n'}); | ||
return; | ||
} | ||
this.queue.push({ type: 'symbol', content: '\\' + special_symbol}); | ||
} else { | ||
@@ -254,4 +261,8 @@ this.queue.push({ type: 'symbol', content: 'op' }); | ||
if (cell.type === 'ordgroup' && cell.args!.length === 0) { | ||
this.queue.push({ type: 'atom', content: ',' }); | ||
return; | ||
} | ||
// if (j == 0 && cell.type === 'newline' && cell.content === '\n') { | ||
// return; | ||
// } | ||
this.append(cell); | ||
@@ -276,2 +287,4 @@ // cell.args!.forEach((n) => this.append(n)); | ||
} | ||
} else if (node.type === 'comment') { | ||
this.queue.push({ type: 'comment', content: node.content }); | ||
} else { | ||
@@ -299,2 +312,8 @@ throw new TypstWriterError(`Unimplemented node type to append: ${node.type}`, node); | ||
break; | ||
case 'comment': | ||
str = `//${node.content}`; | ||
break; | ||
case 'newline': | ||
str = '\n'; | ||
break; | ||
default: | ||
@@ -358,3 +377,5 @@ throw new TypstWriterError(`Unexpected node type to stringify: ${node.type}`, node) | ||
} else if (token === '\\\\') { | ||
return '\\\n'; | ||
return '\\'; | ||
} else if (token == '/') { | ||
return '\\/'; | ||
} else if (['\\$', '\\#', '\\&', '\\_'].includes(token)) { | ||
@@ -361,0 +382,0 @@ return token; |
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
1314617
30636
0