Compare commits

1 Commits
npm ... master

Author SHA1 Message Date
stjet
b32fe228d2 add strikethroughs 2024-02-08 22:44:47 +00:00
6 changed files with 128 additions and 26 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,2 @@
*.js
tsconfig.json
tsconfig-node.json
tsconfig-web.json

View File

@@ -40,6 +40,7 @@ Some example CSS to style the HTML output can be found in `styles/makoto.css`.
- `italic-not-closed`
- `bold-not-closed`
- `superscript-not-closed`
- `strikethrough-not-closed`
- `blockquote-broken`
- `code-block-not-closed`
- `unordered-list-broken`

View File

@@ -104,6 +104,8 @@ test_assert_equal(parse_md_to_html("1. uno\n2. dos\n3. tres\n4. cuatro\n5. cinco
test_assert_equal(parse_md_to_html("a ^ace^ base\n```js\n^sup^\n```\ne=mc^2\n^ea^"), "<p>a <sup>ace</sup> base</p>\n<div class=\"code-block code-js\">\n^sup^<br>\n</div>\n<p>e=mc^2</p>\n<p><sup>ea</sup></p>", "superscript test");
test_assert_equal(parse_md_to_html("~~asdf~~ testing ~~is this thing on?~~ this will not be ~~struck through\n~~wee\n~~**a a a**\n~~*aloha~~*"), "<p><s>asdf</s> testing <s>is this thing on?</s> this will not be ~~struck through</p>\n<p>~~wee</p>\n<p>~~<b>a a a</b></p>\n<p><s>*aloha</s>*</p>", "strikethrough test");
//I don't care about table edgecases.
test_assert_equal(parse_md_to_html("|a|b|c|\n|d|e|f|\n# a"), "<table>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n<tr>\n<td>d</td>\n<td>e</td>\n<td>f</td>\n</tr>\n</table>\n<h1 id=\"header-0\">a</h1>", "basic table test");

109
makoto.ts
View File

@@ -5,6 +5,22 @@ export type ParseResult = {
warnings: Warning[]
}
function replace_last_element(html_line: string, html_element: string, replace_string: string): string {
let split: string[] = html_line.split(html_element);
html_line = "";
for (let ii=0; ii < split.length; ii++) {
html_line += split[ii];
if (ii !== split.length-1) {
if (ii === split.length-2) {
html_line += replace_string;
} else {
html_line += html_element;
}
}
}
return html_line;
}
//some minor differences with markdown spec?
export function parse_md_to_html_with_warnings(md: string): ParseResult {
let html: string = "";
@@ -22,6 +38,8 @@ export function parse_md_to_html_with_warnings(md: string): ParseResult {
let asterisk_num: number = 0;
let asterisk_out_num: number = 0;
let in_asterisk: boolean = false;
let tilde_num: number = 0;
let in_strikethrough: boolean = false;
let horizontal_num: number = 0;
let horizontal_rule: boolean = false;
let was_image: boolean = false;
@@ -185,6 +203,16 @@ export function parse_md_to_html_with_warnings(md: string): ParseResult {
if (chars[i-1] === "\n") {
html_line = "<p>";
}
//ending strikethrough
if (in_strikethrough && char === "~" && tilde_num === 1) {
in_strikethrough = false;
html_line += "</s>";
tilde_num = 0;
add_char = false;
//
} else if (tilde_num === 1) {
html_line += "~";
}
//ending a bold/italic?
if (in_asterisk && char === "*") {
if (asterisk_num === 2 && chars[i-1] === "*") {
@@ -209,22 +237,22 @@ export function parse_md_to_html_with_warnings(md: string): ParseResult {
html_line += char;
}
}
if (in_strikethrough) {
//strikethrough never ended
//remove the last <s> and replace it with a ~~
in_strikethrough = false;
html_line = replace_last_element(html_line, "<s>", "~~");
warnings.push({
type: "strikethrough-not-closed",
message: "Strikethrough not closed, may be missing closing '~~'? Backslash the '~'s if this is intentional",
line_number,
});
}
if (in_asterisk) {
//bold/italic never ended
if (asterisk_num === 1) {
//remove the last <i> and replace it with a *
let split: string[] = html_line.split("<i>");
html_line = "";
for (let ii=0; ii < split.length; ii++) {
html_line += split[ii];
if (ii !== split.length-1) {
if (ii === split.length-2) {
html_line += "*";
} else {
html_line += "<i>";
}
}
}
html_line = replace_last_element(html_line, "<i>", "*");
warnings.push({
type: "italic-not-closed",
message: "Italic not closed, may be missing closing '*'? Backslash the '*' if this is intentional",
@@ -232,18 +260,7 @@ export function parse_md_to_html_with_warnings(md: string): ParseResult {
});
} else if (asterisk_num === 2) {
//remove the last <b> and replace it with a **
let split: string[] = html_line.split("<b>");
html_line = "";
for (let ii=0; ii < split.length; ii++) {
html_line += split[ii];
if (ii !== split.length-1) {
if (ii === split.length-2) {
html_line += "**";
} else {
html_line += "<b>";
}
}
}
html_line = replace_last_element(html_line, "<b>", "**");
warnings.push({
type: "bold-not-closed",
message: "Bold not closed, may be missing closing '**'? Backslash the '**' if this is intentional",
@@ -707,6 +724,50 @@ export function parse_md_to_html_with_warnings(md: string): ParseResult {
if (i === 0 || chars[i-1] === "\n") {
html_line = "<p>"+html_line;
}
//handle strikethrough
if (char === "~") {
tilde_num++;
if (tilde_num === 2) {
if (in_strikethrough) {
//end strikethrough
html_line += "</s>";
in_strikethrough = false;
//end italics and bolds if not ended
if (in_asterisk) {
//bold/italic never ended
if (asterisk_num === 1) {
//remove the last <i> and replace it with a *
html_line = replace_last_element(html_line, "<i>", "*");
warnings.push({
type: "italic-not-closed",
message: "Italic not closed, may be missing closing '*'? Backslash the '*' if this is intentional",
line_number,
});
} else if (asterisk_num === 2) {
//remove the last <b> and replace it with a **
html_line = replace_last_element(html_line, "<b>", "**");
warnings.push({
type: "bold-not-closed",
message: "Bold not closed, may be missing closing '**'? Backslash the '**' if this is intentional",
line_number,
});
}
asterisk_num = 0;
asterisk_out_num = 0;
in_asterisk = false;
}
} else {
//start strikethrough
html_line += "<s>";
in_strikethrough = true;
}
tilde_num = 0;
}
continue;
} else if (tilde_num > 0) {
html_line += "~".repeat(tilde_num);
tilde_num = 0;
}
//handle italics and bolds
if (char === "*" && asterisk_num < 2 && !in_asterisk) {
asterisk_num++;

18
tsconfig-node.json Normal file
View File

@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"strict": true,
"moduleResolution": "node",
"typeRoots": [
"./node_modules/@types",
],
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"exclude": [
"node_modules",
".build"
]
}

22
tsconfig-web.json Normal file
View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"moduleResolution": "classic",
"typeRoots": [
"./node_modules/@types",
],
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"lib": [
"ESNext",
"DOM"
],
"exclude": [
"node_modules",
".build"
]
}