simple-customize-markdown-converter 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lexer.d.ts CHANGED
@@ -20,4 +20,8 @@ export default class Lexer {
20
20
  private handleItalic;
21
21
  private handleBold;
22
22
  private handleInlineBlock;
23
+ private handleQuoteBlock;
24
+ private handleLink;
25
+ private handleImage;
26
+ private readUntil;
23
27
  }
package/dist/lexer.js CHANGED
@@ -17,6 +17,9 @@ class Lexer {
17
17
  { match: (lex) => lex.peek() === "`", emit: (lex) => lex.handleInlineBlock() },
18
18
  { match: (lex) => lex.peek() === "#", emit: (lex) => lex.handleHeader() },
19
19
  { match: (lex) => lex.peek() === "*" || lex.peek() === "_", emit: (lex) => lex.handleItalic() },
20
+ { match: (lex) => lex.peek() === ">", emit: (lex) => lex.handleQuoteBlock() },
21
+ { match: (lex) => lex.peek() === "[", emit: (lex) => lex.handleLink() },
22
+ { match: (lex) => lex.peek() === "!" && lex.peek(1) === "[", emit: (lex) => lex.handleImage() },
20
23
  { match: (lex) => lex.peek() === "\n", emit: (lex) => lex.listToken.push({ type: "NewLine" }) },
21
24
  ];
22
25
  while (!this.isEndOfFile()) {
@@ -56,18 +59,16 @@ class Lexer {
56
59
  return this.listToken[this.listToken.length - 1];
57
60
  }
58
61
  handleHeader() {
59
- const lastToken = this.getLastToken();
60
- if (!lastToken || lastToken.type === "NewLine") {
61
- this.listToken.push({ type: "Header", level: 1 });
62
- }
63
- else if (lastToken.type === "Header") {
64
- lastToken.level++;
62
+ let level = 0;
63
+ while (this.peek() === "#") {
64
+ level++;
65
+ this.next();
65
66
  }
66
- this.next();
67
67
  if (this.peek() === " ") {
68
68
  this.next();
69
69
  this.pos--;
70
70
  }
71
+ this.listToken.push({ type: "Header", level });
71
72
  }
72
73
  handleCodeBlock() {
73
74
  let lang = "";
@@ -83,7 +84,7 @@ class Lexer {
83
84
  this.next();
84
85
  }
85
86
  this.next(2); //Skip close block (due to next() after each tokenize iteration)
86
- this.listToken.push({ "type": "CodeBlock", lang: lang.trim(), content: content });
87
+ this.listToken.push({ "type": "CodeBlock", lang: lang.trim(), content: content.trimEnd() });
87
88
  }
88
89
  handleTextBlock() {
89
90
  const currentChar = this.peek();
@@ -112,5 +113,45 @@ class Lexer {
112
113
  // this.next() //Skip close block
113
114
  this.listToken.push({ "type": "InlineCode", content: content });
114
115
  }
116
+ handleQuoteBlock() {
117
+ this.listToken.push({ type: "Quote" });
118
+ }
119
+ handleLink() {
120
+ this.next(); //Skip [
121
+ const text = this.readUntil("]");
122
+ this.next(); //Skip ]
123
+ if (this.peek() === "(") {
124
+ this.next(); //Skip (
125
+ const url = this.readUntil(")");
126
+ //Don't skip ) due to auto skip on while loop
127
+ this.listToken.push({ type: "Link", text: text, href: url });
128
+ }
129
+ else
130
+ this.listToken.push({ type: "Text", value: `[${text}]` });
131
+ }
132
+ handleImage() {
133
+ this.next(); //Skip !
134
+ if (this.peek() !== "[")
135
+ return;
136
+ this.next(); //Skip [
137
+ const alt = this.readUntil("]");
138
+ this.next(); //Skip ]
139
+ if (this.peek() === "(") {
140
+ this.next(); //Skip (
141
+ const src = this.readUntil(")");
142
+ this.next(); //Skip )
143
+ this.listToken.push({ type: "Image", alt: alt, src: src });
144
+ }
145
+ else
146
+ this.listToken.push({ type: "Text", value: `![${alt}]` });
147
+ }
148
+ readUntil(char) {
149
+ let result = "";
150
+ while (this.peek() !== char) {
151
+ result += this.peek();
152
+ this.next();
153
+ }
154
+ return result;
155
+ }
115
156
  }
116
157
  exports.default = Lexer;
package/dist/parser.d.ts CHANGED
@@ -19,5 +19,8 @@ export declare class Parser {
19
19
  private parseBold;
20
20
  private parseItalic;
21
21
  private parseInlineCode;
22
+ private parseQuote;
23
+ private parseLink;
24
+ private parseImage;
22
25
  private parseInlineUntil;
23
26
  }
package/dist/parser.js CHANGED
@@ -37,12 +37,18 @@ class Parser {
37
37
  listNode.push(this.parseHeader());
38
38
  break;
39
39
  }
40
- case "CodeBlock":
41
- {
42
- listNode.push(this.parseCodeBlock());
43
- this.next();
44
- }
40
+ case "CodeBlock": {
41
+ listNode.push(this.parseCodeBlock());
45
42
  break;
43
+ }
44
+ case "Quote": {
45
+ listNode.push(this.parseQuote());
46
+ break;
47
+ }
48
+ case "Image": {
49
+ listNode.push(this.parseImage());
50
+ break;
51
+ }
46
52
  case "NewLine": {
47
53
  this.next(); // skip
48
54
  break;
@@ -60,6 +66,7 @@ class Parser {
60
66
  }
61
67
  parseCodeBlock() {
62
68
  const tok = this.peek();
69
+ this.next();
63
70
  return {
64
71
  type: "CodeBlock",
65
72
  lang: tok?.type === "CodeBlock" ? tok.lang : "",
@@ -91,6 +98,35 @@ class Parser {
91
98
  content: tok?.type === "InlineCode" ? tok.content : ""
92
99
  };
93
100
  }
101
+ parseQuote() {
102
+ this.next(); //skip marker
103
+ return { type: "Quote", children: [{ type: "Paragraph", children: this.parseInlineUntil("NewLine") }] };
104
+ }
105
+ parseLink() {
106
+ const tok = this.peek();
107
+ this.next();
108
+ if (tok?.type === "Link") {
109
+ return {
110
+ type: "Link",
111
+ href: tok.href,
112
+ text: tok.text
113
+ };
114
+ }
115
+ return { type: "Link", href: "", text: "" };
116
+ }
117
+ parseImage() {
118
+ const tok = this.peek();
119
+ this.next();
120
+ if (tok?.type === "Image") {
121
+ return {
122
+ type: "Image",
123
+ src: tok.src,
124
+ alt: tok.alt
125
+ };
126
+ }
127
+ else
128
+ return { type: "Image", src: "", alt: "" };
129
+ }
94
130
  parseInlineUntil(stopType) {
95
131
  const listNode = [];
96
132
  while (!this.isEnd() && this.peek()?.type !== stopType) {
@@ -112,6 +148,12 @@ class Parser {
112
148
  }
113
149
  case "Text": {
114
150
  listNode.push({ type: "Text", value: currentNode.value });
151
+ this.next();
152
+ break;
153
+ }
154
+ case "Link": {
155
+ listNode.push(this.parseLink());
156
+ break;
115
157
  }
116
158
  default: this.next();
117
159
  }
package/dist/renderer.js CHANGED
@@ -26,7 +26,10 @@ class Renderer {
26
26
  CodeBlock: (node) => `<pre><code class="lang-${node.lang}">${this.escapeHtml(node.content)}</code></pre>`,
27
27
  Bold: (_node, children) => `<strong>${children.join("")}</strong>`,
28
28
  Italic: (_node, children) => `<em>${children.join("")}</em>`,
29
- Text: (node) => node.value
29
+ Quote: (_node, children) => `<blockquote>${children.join("")}</blockquote>`,
30
+ Link: (node) => `<a href="${node.href}">${node.text}</a>`,
31
+ Image: (node) => `<img src="${node.src}" alt="${node.alt}"/>`,
32
+ Text: (node) => node.value,
30
33
  };
31
34
  return this.option.elements?.[type] ?? defaultRender[type];
32
35
  }
@@ -10,8 +10,11 @@
10
10
  * - Header: A header with given `level` (1-6)
11
11
  * - Bold: Bold text
12
12
  * - Italic: Italic text
13
- * - InlineCode: Inline code snippet, with `content`
14
- * - CodeBlock: A code block, with `lang` and `content`
13
+ * - InlineCode: Inline code snippet, with it's `content`
14
+ * - Quote: A quote block
15
+ * - CodeBlock: A code block, with it's `lang` and `content`
16
+ * - Link: A link, with it's `text` and `href`
17
+ * - Image: An image, with it's `src` and `alt`
15
18
  * - Text: Raw text content.
16
19
  */
17
20
  export type Node = {
@@ -37,6 +40,17 @@ export type Node = {
37
40
  type: "CodeBlock";
38
41
  lang: string;
39
42
  content: string;
43
+ } | {
44
+ type: "Quote";
45
+ children: Node[];
46
+ } | {
47
+ type: "Link";
48
+ href: string;
49
+ text: string;
50
+ } | {
51
+ type: "Image";
52
+ src: string;
53
+ alt: string;
40
54
  } | {
41
55
  type: "Text";
42
56
  value: string;
@@ -12,6 +12,9 @@
12
12
  * - Bold: Bold marker (`**`).
13
13
  * - Italic: Italic marker (`*` or `_`).
14
14
  * - InlineCode: Inline code snippet (`` ` ``), with its `content`.
15
+ * - Quote: A quote block (`>`).
16
+ * - Link: A link (`[text](url)`)
17
+ * - Image: An image (`![alt](url)`)
15
18
  * - EOF: A special token, this is the end of input.
16
19
  */
17
20
  export type Token = {
@@ -33,6 +36,16 @@ export type Token = {
33
36
  } | {
34
37
  type: "InlineCode";
35
38
  content: string;
39
+ } | {
40
+ type: "Quote";
41
+ } | {
42
+ type: "Link";
43
+ text: string;
44
+ href: string;
45
+ } | {
46
+ type: "Image";
47
+ src: string;
48
+ alt: string;
36
49
  } | {
37
50
  type: "EOF";
38
51
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-customize-markdown-converter",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Convert Markdown to your customize HTML",
5
5
  "keywords": [
6
6
  "markdown",