add strikethroughs
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,2 @@
|
|||||||
*.js
|
*.js
|
||||||
tsconfig.json
|
tsconfig.json
|
||||||
tsconfig-node.json
|
|
||||||
tsconfig-web.json
|
|
||||||
@@ -40,6 +40,7 @@ Some example CSS to style the HTML output can be found in `styles/makoto.css`.
|
|||||||
- `italic-not-closed`
|
- `italic-not-closed`
|
||||||
- `bold-not-closed`
|
- `bold-not-closed`
|
||||||
- `superscript-not-closed`
|
- `superscript-not-closed`
|
||||||
|
- `strikethrough-not-closed`
|
||||||
- `blockquote-broken`
|
- `blockquote-broken`
|
||||||
- `code-block-not-closed`
|
- `code-block-not-closed`
|
||||||
- `unordered-list-broken`
|
- `unordered-list-broken`
|
||||||
|
|||||||
2
index.ts
2
index.ts
@@ -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("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.
|
//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");
|
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
109
makoto.ts
@@ -5,6 +5,22 @@ export type ParseResult = {
|
|||||||
warnings: Warning[]
|
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?
|
//some minor differences with markdown spec?
|
||||||
export function parse_md_to_html_with_warnings(md: string): ParseResult {
|
export function parse_md_to_html_with_warnings(md: string): ParseResult {
|
||||||
let html: string = "";
|
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_num: number = 0;
|
||||||
let asterisk_out_num: number = 0;
|
let asterisk_out_num: number = 0;
|
||||||
let in_asterisk: boolean = false;
|
let in_asterisk: boolean = false;
|
||||||
|
let tilde_num: number = 0;
|
||||||
|
let in_strikethrough: boolean = false;
|
||||||
let horizontal_num: number = 0;
|
let horizontal_num: number = 0;
|
||||||
let horizontal_rule: boolean = false;
|
let horizontal_rule: boolean = false;
|
||||||
let was_image: 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") {
|
if (chars[i-1] === "\n") {
|
||||||
html_line = "<p>";
|
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?
|
//ending a bold/italic?
|
||||||
if (in_asterisk && char === "*") {
|
if (in_asterisk && char === "*") {
|
||||||
if (asterisk_num === 2 && chars[i-1] === "*") {
|
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;
|
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) {
|
if (in_asterisk) {
|
||||||
//bold/italic never ended
|
//bold/italic never ended
|
||||||
if (asterisk_num === 1) {
|
if (asterisk_num === 1) {
|
||||||
//remove the last <i> and replace it with a *
|
//remove the last <i> and replace it with a *
|
||||||
let split: string[] = html_line.split("<i>");
|
html_line = replace_last_element(html_line, "<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>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
warnings.push({
|
warnings.push({
|
||||||
type: "italic-not-closed",
|
type: "italic-not-closed",
|
||||||
message: "Italic not closed, may be missing closing '*'? Backslash the '*' if this is intentional",
|
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) {
|
} else if (asterisk_num === 2) {
|
||||||
//remove the last <b> and replace it with a **
|
//remove the last <b> and replace it with a **
|
||||||
let split: string[] = html_line.split("<b>");
|
html_line = replace_last_element(html_line, "<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>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
warnings.push({
|
warnings.push({
|
||||||
type: "bold-not-closed",
|
type: "bold-not-closed",
|
||||||
message: "Bold not closed, may be missing closing '**'? Backslash the '**' if this is intentional",
|
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") {
|
if (i === 0 || chars[i-1] === "\n") {
|
||||||
html_line = "<p>"+html_line;
|
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
|
//handle italics and bolds
|
||||||
if (char === "*" && asterisk_num < 2 && !in_asterisk) {
|
if (char === "*" && asterisk_num < 2 && !in_asterisk) {
|
||||||
asterisk_num++;
|
asterisk_num++;
|
||||||
|
|||||||
18
tsconfig-node.json
Normal file
18
tsconfig-node.json
Normal 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
22
tsconfig-web.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user