amateras 0.7.4 → 0.10.0

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.
Files changed (257) hide show
  1. package/README.md +76 -85
  2. package/package.json +29 -33
  3. package/tsconfig.json +4 -3
  4. package/packages/core/package.json +0 -32
  5. package/packages/core/src/env.browser.ts +0 -21
  6. package/packages/core/src/env.node.ts +0 -21
  7. package/packages/core/src/global.ts +0 -18
  8. package/packages/core/src/index.ts +0 -96
  9. package/packages/core/src/lib/assignNodeProperties.ts +0 -11
  10. package/packages/core/src/lib/assignProperties.ts +0 -57
  11. package/packages/core/src/lib/chain.ts +0 -17
  12. package/packages/core/src/lib/dom.ts +0 -20
  13. package/packages/core/src/main.ts +0 -4
  14. package/packages/core/src/node/$Element.ts +0 -366
  15. package/packages/core/src/node/$EventTarget.ts +0 -48
  16. package/packages/core/src/node/$HTMLElement.ts +0 -99
  17. package/packages/core/src/node/$Node.ts +0 -201
  18. package/packages/core/src/node/$Virtual.ts +0 -65
  19. package/packages/css/README.md +0 -128
  20. package/packages/css/package.json +0 -17
  21. package/packages/css/src/ext/colors/amber.ts +0 -25
  22. package/packages/css/src/ext/colors/blackwhite.ts +0 -13
  23. package/packages/css/src/ext/colors/blue.ts +0 -25
  24. package/packages/css/src/ext/colors/cyan.ts +0 -25
  25. package/packages/css/src/ext/colors/emerald.ts +0 -25
  26. package/packages/css/src/ext/colors/fuchsia.ts +0 -25
  27. package/packages/css/src/ext/colors/gray.ts +0 -25
  28. package/packages/css/src/ext/colors/green.ts +0 -25
  29. package/packages/css/src/ext/colors/indigo.ts +0 -25
  30. package/packages/css/src/ext/colors/lime.ts +0 -25
  31. package/packages/css/src/ext/colors/neutral.ts +0 -25
  32. package/packages/css/src/ext/colors/orange.ts +0 -25
  33. package/packages/css/src/ext/colors/pink.ts +0 -25
  34. package/packages/css/src/ext/colors/purple.ts +0 -25
  35. package/packages/css/src/ext/colors/red.ts +0 -25
  36. package/packages/css/src/ext/colors/rose.ts +0 -25
  37. package/packages/css/src/ext/colors/sky.ts +0 -25
  38. package/packages/css/src/ext/colors/slate.ts +0 -25
  39. package/packages/css/src/ext/colors/stone.ts +0 -25
  40. package/packages/css/src/ext/colors/teal.ts +0 -25
  41. package/packages/css/src/ext/colors/violet.ts +0 -25
  42. package/packages/css/src/ext/colors/yellow.ts +0 -25
  43. package/packages/css/src/ext/colors/zinc.ts +0 -25
  44. package/packages/css/src/ext/colors.ts +0 -23
  45. package/packages/css/src/ext/container.ts +0 -32
  46. package/packages/css/src/ext/keyframes.ts +0 -54
  47. package/packages/css/src/ext/media.ts +0 -32
  48. package/packages/css/src/ext/property.ts +0 -48
  49. package/packages/css/src/ext/variable.ts +0 -51
  50. package/packages/css/src/index.ts +0 -436
  51. package/packages/css/src/lib/colorAssign.ts +0 -6
  52. package/packages/css/src/lib/utils.ts +0 -11
  53. package/packages/css/src/structure/$CSSContainerRule.ts +0 -13
  54. package/packages/css/src/structure/$CSSDeclaration.ts +0 -16
  55. package/packages/css/src/structure/$CSSKeyframesRule.ts +0 -13
  56. package/packages/css/src/structure/$CSSMediaRule.ts +0 -10
  57. package/packages/css/src/structure/$CSSProperty.ts +0 -19
  58. package/packages/css/src/structure/$CSSRule.ts +0 -13
  59. package/packages/css/src/structure/$CSSStyleRule.ts +0 -14
  60. package/packages/css/src/structure/$CSSVariable.ts +0 -30
  61. package/packages/dom/package.json +0 -20
  62. package/packages/dom/src/lib/HTMLElementMap.ts +0 -213
  63. package/packages/dom/src/lib/assignAttributes.ts +0 -16
  64. package/packages/dom/src/structure/CSS.ts +0 -7
  65. package/packages/dom/src/structure/CSSStyleSheet.ts +0 -10
  66. package/packages/dom/src/structure/DOMTokenList.ts +0 -19
  67. package/packages/dom/src/structure/Document.ts +0 -36
  68. package/packages/dom/src/structure/Element.ts +0 -106
  69. package/packages/dom/src/structure/HTMLElement.ts +0 -34
  70. package/packages/dom/src/structure/History.ts +0 -11
  71. package/packages/dom/src/structure/Location.ts +0 -9
  72. package/packages/dom/src/structure/Node.ts +0 -51
  73. package/packages/dom/src/structure/NodeList.ts +0 -10
  74. package/packages/dom/src/structure/Storage.ts +0 -8
  75. package/packages/dom/src/structure/Text.ts +0 -20
  76. package/packages/dom/src/structure/Window.ts +0 -14
  77. package/packages/dom/src/structure/html/HTMLAbbrElement.ts +0 -16
  78. package/packages/dom/src/structure/html/HTMLAddressElement.ts +0 -16
  79. package/packages/dom/src/structure/html/HTMLAnchorElement.ts +0 -25
  80. package/packages/dom/src/structure/html/HTMLAreaElement.ts +0 -26
  81. package/packages/dom/src/structure/html/HTMLArticleElement.ts +0 -16
  82. package/packages/dom/src/structure/html/HTMLAsideElement.ts +0 -16
  83. package/packages/dom/src/structure/html/HTMLAudioElement.ts +0 -16
  84. package/packages/dom/src/structure/html/HTMLBDIElement.ts +0 -16
  85. package/packages/dom/src/structure/html/HTMLBDOElement.ts +0 -16
  86. package/packages/dom/src/structure/html/HTMLBElement.ts +0 -16
  87. package/packages/dom/src/structure/html/HTMLBRElement.ts +0 -17
  88. package/packages/dom/src/structure/html/HTMLBaseElement.ts +0 -18
  89. package/packages/dom/src/structure/html/HTMLBodyElement.ts +0 -22
  90. package/packages/dom/src/structure/html/HTMLButtonElement.ts +0 -26
  91. package/packages/dom/src/structure/html/HTMLCanvasElement.ts +0 -18
  92. package/packages/dom/src/structure/html/HTMLCiteElement.ts +0 -16
  93. package/packages/dom/src/structure/html/HTMLCodeElement.ts +0 -16
  94. package/packages/dom/src/structure/html/HTMLDDElement.ts +0 -16
  95. package/packages/dom/src/structure/html/HTMLDFNElement.ts +0 -16
  96. package/packages/dom/src/structure/html/HTMLDListElement.ts +0 -17
  97. package/packages/dom/src/structure/html/HTMLDTElement.ts +0 -16
  98. package/packages/dom/src/structure/html/HTMLDataElement.ts +0 -17
  99. package/packages/dom/src/structure/html/HTMLDataListElement.ts +0 -16
  100. package/packages/dom/src/structure/html/HTMLDetailsElement.ts +0 -17
  101. package/packages/dom/src/structure/html/HTMLDialogElement.ts +0 -18
  102. package/packages/dom/src/structure/html/HTMLDivElement.ts +0 -17
  103. package/packages/dom/src/structure/html/HTMLEMElement.ts +0 -16
  104. package/packages/dom/src/structure/html/HTMLEmbedElement.ts +0 -20
  105. package/packages/dom/src/structure/html/HTMLFieldSetElement.ts +0 -19
  106. package/packages/dom/src/structure/html/HTMLFigCaptionElement.ts +0 -16
  107. package/packages/dom/src/structure/html/HTMLFigureElement.ts +0 -16
  108. package/packages/dom/src/structure/html/HTMLFooterElement.ts +0 -16
  109. package/packages/dom/src/structure/html/HTMLFormElement.ts +0 -24
  110. package/packages/dom/src/structure/html/HTMLHGroupElement.ts +0 -16
  111. package/packages/dom/src/structure/html/HTMLHRElement.ts +0 -21
  112. package/packages/dom/src/structure/html/HTMLHeadElement.ts +0 -16
  113. package/packages/dom/src/structure/html/HTMLHeaderElement.ts +0 -16
  114. package/packages/dom/src/structure/html/HTMLHeadingElement.ts +0 -17
  115. package/packages/dom/src/structure/html/HTMLHtmlElement.ts +0 -18
  116. package/packages/dom/src/structure/html/HTMLIElement.ts +0 -16
  117. package/packages/dom/src/structure/html/HTMLIFrameElement.ts +0 -31
  118. package/packages/dom/src/structure/html/HTMLImageElement.ts +0 -38
  119. package/packages/dom/src/structure/html/HTMLInputElement.ts +0 -55
  120. package/packages/dom/src/structure/html/HTMLKBDElement.ts +0 -16
  121. package/packages/dom/src/structure/html/HTMLLIElement.ts +0 -18
  122. package/packages/dom/src/structure/html/HTMLLabelElement.ts +0 -18
  123. package/packages/dom/src/structure/html/HTMLLegendElement.ts +0 -17
  124. package/packages/dom/src/structure/html/HTMLLinkElement.ts +0 -31
  125. package/packages/dom/src/structure/html/HTMLMainElement.ts +0 -16
  126. package/packages/dom/src/structure/html/HTMLMapElement.ts +0 -17
  127. package/packages/dom/src/structure/html/HTMLMarkElement.ts +0 -16
  128. package/packages/dom/src/structure/html/HTMLMediaElement.ts +0 -48
  129. package/packages/dom/src/structure/html/HTMLMenuElement.ts +0 -18
  130. package/packages/dom/src/structure/html/HTMLMetaElement.ts +0 -22
  131. package/packages/dom/src/structure/html/HTMLMeterElement.ts +0 -23
  132. package/packages/dom/src/structure/html/HTMLModElement.ts +0 -18
  133. package/packages/dom/src/structure/html/HTMLNavElement.ts +0 -16
  134. package/packages/dom/src/structure/html/HTMLNoscriptElement.ts +0 -16
  135. package/packages/dom/src/structure/html/HTMLOListElement.ts +0 -20
  136. package/packages/dom/src/structure/html/HTMLObjectElement.ts +0 -34
  137. package/packages/dom/src/structure/html/HTMLOptGroupElement.ts +0 -18
  138. package/packages/dom/src/structure/html/HTMLOptionElement.ts +0 -20
  139. package/packages/dom/src/structure/html/HTMLOutputElement.ts +0 -20
  140. package/packages/dom/src/structure/html/HTMLParagraphElement.ts +0 -17
  141. package/packages/dom/src/structure/html/HTMLPictureElement.ts +0 -16
  142. package/packages/dom/src/structure/html/HTMLPreElement.ts +0 -17
  143. package/packages/dom/src/structure/html/HTMLProgressElement.ts +0 -19
  144. package/packages/dom/src/structure/html/HTMLQuoteElement.ts +0 -17
  145. package/packages/dom/src/structure/html/HTMLRPElement.ts +0 -16
  146. package/packages/dom/src/structure/html/HTMLRTElement.ts +0 -16
  147. package/packages/dom/src/structure/html/HTMLRubyElement.ts +0 -16
  148. package/packages/dom/src/structure/html/HTMLSElement.ts +0 -16
  149. package/packages/dom/src/structure/html/HTMLSampElement.ts +0 -16
  150. package/packages/dom/src/structure/html/HTMLScriptElement.ts +0 -27
  151. package/packages/dom/src/structure/html/HTMLSectionElement.ts +0 -16
  152. package/packages/dom/src/structure/html/HTMLSelectElement.ts +0 -27
  153. package/packages/dom/src/structure/html/HTMLSlotElement.ts +0 -17
  154. package/packages/dom/src/structure/html/HTMLSmallElement.ts +0 -16
  155. package/packages/dom/src/structure/html/HTMLSourceElement.ts +0 -21
  156. package/packages/dom/src/structure/html/HTMLSpanElement.ts +0 -16
  157. package/packages/dom/src/structure/html/HTMLStrongElement.ts +0 -16
  158. package/packages/dom/src/structure/html/HTMLStyleElement.ts +0 -18
  159. package/packages/dom/src/structure/html/HTMLSubElement.ts +0 -16
  160. package/packages/dom/src/structure/html/HTMLSummaryElement.ts +0 -16
  161. package/packages/dom/src/structure/html/HTMLSupElement.ts +0 -16
  162. package/packages/dom/src/structure/html/HTMLTableCaptionElement.ts +0 -17
  163. package/packages/dom/src/structure/html/HTMLTableCellElement.ts +0 -31
  164. package/packages/dom/src/structure/html/HTMLTableColElement.ts +0 -23
  165. package/packages/dom/src/structure/html/HTMLTableElement.ts +0 -26
  166. package/packages/dom/src/structure/html/HTMLTableRowElement.ts +0 -23
  167. package/packages/dom/src/structure/html/HTMLTableSectionElement.ts +0 -20
  168. package/packages/dom/src/structure/html/HTMLTemplateElement.ts +0 -17
  169. package/packages/dom/src/structure/html/HTMLTextAreaElement.ts +0 -33
  170. package/packages/dom/src/structure/html/HTMLTimeElement.ts +0 -17
  171. package/packages/dom/src/structure/html/HTMLTitleElement.ts +0 -17
  172. package/packages/dom/src/structure/html/HTMLTrackElement.ts +0 -21
  173. package/packages/dom/src/structure/html/HTMLUElement.ts +0 -16
  174. package/packages/dom/src/structure/html/HTMLUListElement.ts +0 -18
  175. package/packages/dom/src/structure/html/HTMLVarElement.ts +0 -16
  176. package/packages/dom/src/structure/html/HTMLVideoElement.ts +0 -22
  177. package/packages/dom/src/structure/html/HTMLWBRElement.ts +0 -16
  178. package/packages/html/package.json +0 -18
  179. package/packages/html/src/index.ts +0 -13
  180. package/packages/html/src/node/$Anchor.ts +0 -49
  181. package/packages/html/src/node/$Canvas.ts +0 -38
  182. package/packages/html/src/node/$Dialog.ts +0 -16
  183. package/packages/html/src/node/$Form.ts +0 -16
  184. package/packages/html/src/node/$Image.ts +0 -72
  185. package/packages/html/src/node/$Input.ts +0 -193
  186. package/packages/html/src/node/$Label.ts +0 -25
  187. package/packages/html/src/node/$Media.ts +0 -16
  188. package/packages/html/src/node/$OptGroup.ts +0 -23
  189. package/packages/html/src/node/$Option.ts +0 -40
  190. package/packages/html/src/node/$Select.ts +0 -76
  191. package/packages/html/src/node/$TextArea.ts +0 -16
  192. package/packages/i18n/README.md +0 -73
  193. package/packages/i18n/package.json +0 -19
  194. package/packages/i18n/src/index.ts +0 -140
  195. package/packages/i18n/src/structure/I18n.ts +0 -44
  196. package/packages/i18n/src/structure/I18nDictionary.ts +0 -31
  197. package/packages/i18n/src/structure/I18nTranslation.ts +0 -41
  198. package/packages/idb/README.md +0 -127
  199. package/packages/idb/package.json +0 -19
  200. package/packages/idb/src/core.ts +0 -6
  201. package/packages/idb/src/index.ts +0 -17
  202. package/packages/idb/src/lib/$IDBRequest.ts +0 -8
  203. package/packages/idb/src/structure/$IDB.ts +0 -63
  204. package/packages/idb/src/structure/$IDBCursor.ts +0 -34
  205. package/packages/idb/src/structure/$IDBIndex.ts +0 -48
  206. package/packages/idb/src/structure/$IDBStore.ts +0 -103
  207. package/packages/idb/src/structure/$IDBStoreBase.ts +0 -30
  208. package/packages/idb/src/structure/$IDBTransaction.ts +0 -38
  209. package/packages/idb/src/structure/builder/$IDBBuilder.ts +0 -229
  210. package/packages/idb/src/structure/builder/$IDBStoreBuilder.ts +0 -100
  211. package/packages/markdown/README.md +0 -53
  212. package/packages/markdown/package.json +0 -19
  213. package/packages/markdown/src/index.ts +0 -3
  214. package/packages/markdown/src/lib/type.ts +0 -26
  215. package/packages/markdown/src/lib/util.ts +0 -21
  216. package/packages/markdown/src/structure/Markdown.ts +0 -54
  217. package/packages/markdown/src/structure/MarkdownLexer.ts +0 -111
  218. package/packages/markdown/src/structure/MarkdownParser.ts +0 -34
  219. package/packages/markdown/src/syntax/alert.ts +0 -46
  220. package/packages/markdown/src/syntax/blockquote.ts +0 -35
  221. package/packages/markdown/src/syntax/bold.ts +0 -11
  222. package/packages/markdown/src/syntax/code.ts +0 -11
  223. package/packages/markdown/src/syntax/codeblock.ts +0 -44
  224. package/packages/markdown/src/syntax/heading.ts +0 -14
  225. package/packages/markdown/src/syntax/horizontalRule.ts +0 -11
  226. package/packages/markdown/src/syntax/image.ts +0 -23
  227. package/packages/markdown/src/syntax/italic.ts +0 -11
  228. package/packages/markdown/src/syntax/link.ts +0 -46
  229. package/packages/markdown/src/syntax/list.ts +0 -121
  230. package/packages/markdown/src/syntax/table.ts +0 -67
  231. package/packages/markdown/src/syntax/text.ts +0 -19
  232. package/packages/router/README.md +0 -175
  233. package/packages/router/package.json +0 -19
  234. package/packages/router/src/index.ts +0 -68
  235. package/packages/router/src/node/Page.ts +0 -38
  236. package/packages/router/src/node/Router.ts +0 -212
  237. package/packages/router/src/node/RouterAnchor.ts +0 -24
  238. package/packages/router/src/structure/PageBuilder.ts +0 -24
  239. package/packages/router/src/structure/Route.ts +0 -105
  240. package/packages/signal/README.md +0 -93
  241. package/packages/signal/package.json +0 -18
  242. package/packages/signal/src/index.ts +0 -221
  243. package/packages/signal/src/structure/Signal.ts +0 -38
  244. package/packages/ui/lib/VirtualScroll.ts +0 -25
  245. package/packages/ui/node/Accordian.ts +0 -97
  246. package/packages/ui/node/Carousel.ts +0 -20
  247. package/packages/ui/node/Form.ts +0 -54
  248. package/packages/ui/node/Grid.ts +0 -0
  249. package/packages/ui/node/Modal.ts +0 -45
  250. package/packages/ui/node/Table.ts +0 -43
  251. package/packages/ui/node/Tabs.ts +0 -129
  252. package/packages/ui/node/Toast.ts +0 -16
  253. package/packages/ui/node/Waterfall.ts +0 -94
  254. package/packages/ui/package.json +0 -21
  255. package/packages/utils/package.json +0 -17
  256. package/packages/utils/src/global.ts +0 -25
  257. package/packages/utils/src/index.ts +0 -90
@@ -1,54 +0,0 @@
1
- import { alertProcessor, alertTokenizer } from "../syntax/alert";
2
- import { blockquoteProcessor, blockquoteTokenizer } from "../syntax/blockquote";
3
- import { boldProcessor, boldTokenizer } from "../syntax/bold";
4
- import { codeProcessor, codeTokenizer } from "../syntax/code";
5
- import { codeblockProcessor, codeblockTokenizer } from "../syntax/codeblock";
6
- import { headingProcessor, headingTokenizer } from "../syntax/heading";
7
- import { horizontalRuleProcessor, horizontalRuleTokenizer } from "../syntax/horizontalRule";
8
- import { imageProcessor, imageTokenizer } from "../syntax/image";
9
- import { italicProcessor, italicTokenizer } from "../syntax/italic";
10
- import { linkProcessor, linkTokenizer } from "../syntax/link";
11
- import { listProcessor, listTokenizer } from "../syntax/list";
12
- import { textLineProcessor, textProcessor } from "../syntax/text";
13
- import { MarkdownLexer } from "./MarkdownLexer";
14
- import { MarkdownParser } from "./MarkdownParser";
15
-
16
- export class Markdown {
17
- lexer = new MarkdownLexer();
18
- parser = new MarkdownParser();
19
- constructor() {
20
- this.lexer.use(
21
- headingTokenizer,
22
- codeblockTokenizer,
23
- listTokenizer,
24
- alertTokenizer,
25
- blockquoteTokenizer,
26
- horizontalRuleTokenizer,
27
- imageTokenizer, // image tokenizer must before link
28
- linkTokenizer, // link tokenizer must before bold and italic and code
29
- codeTokenizer,
30
- boldTokenizer,
31
- italicTokenizer,
32
- )
33
-
34
- this.parser.use(
35
- textProcessor,
36
- imageProcessor,
37
- linkProcessor,
38
- codeProcessor,
39
- italicProcessor,
40
- boldProcessor,
41
- textLineProcessor,
42
- headingProcessor,
43
- codeblockProcessor,
44
- listProcessor,
45
- alertProcessor,
46
- blockquoteProcessor,
47
- horizontalRuleProcessor
48
- )
49
- }
50
-
51
- parseHTML(str: string) {
52
- return this.parser.parse(this.lexer.blockTokenize(str));
53
- }
54
- }
@@ -1,111 +0,0 @@
1
- import { BLOCK, EMPTY_LINE, INLINE_CONTENT, INLINE_TEXT, TEXT_LINE } from "#lib/type";
2
- import { forEach, isString } from "@amateras/utils";
3
-
4
- export class MarkdownLexer {
5
- blockTokenizers = new Map<string, BlockTokenizer>();
6
- inlineTokenizers = new Map<string, InlineTokenizer>();
7
-
8
- blockTokenize(str: string) {
9
- const lines = str?.split(/\r?\n/) ?? [];
10
- const tokens: BlockToken[] = [];
11
- let lineIndex = 0;
12
- lineLoop: while (lineIndex < lines.length) {
13
- let line = lines[lineIndex];
14
- if (line === undefined) throw 'LINE ERROR';
15
- let token: BlockToken | undefined;
16
- for (const [type, tokenizer] of this.blockTokenizers) {
17
- const matched = line.match(tokenizer.regex);
18
- if (matched) {
19
- const {content, multiLine, data} = tokenizer.handle(matched, lineIndex, lines);
20
- token = { layout: BLOCK, type, content, data }
21
- if (multiLine) {
22
- tokens.push(token);
23
- tokens.push(...multiLine.tokens)
24
- lineIndex = multiLine.skip;
25
- continue lineLoop;
26
- }
27
- break;
28
- }
29
- }
30
- if (!token) token = {
31
- layout: BLOCK,
32
- ...(
33
- line.length
34
- ? { type: TEXT_LINE, content: this.inlineTokenize(line) }
35
- : { type: EMPTY_LINE, content: [] }
36
- )
37
- };
38
- tokens.push(token);
39
- lineIndex++;
40
- }
41
- return tokens;
42
- }
43
-
44
- inlineTokenize(str: string): InlineToken[] {
45
- const tokens: InlineToken[] = [];
46
- let remainStr = str;
47
- while (remainStr.length) {
48
- let token: InlineToken | undefined;
49
- for (const [type, tokenizer] of this.inlineTokenizers) {
50
- const matched = remainStr.match(tokenizer.regex);
51
- if (matched) {
52
- const {index, 0: matchStr} = matched;
53
- // handle before matched string
54
- if (index != 0) tokens.push(...this.inlineTokenize(remainStr.substring(0, index)));
55
- // handle matched string
56
- const {content, data} = tokenizer.handle(matched);
57
- token = { type, ...(isString(content) ? { layout: INLINE_TEXT, text: content } : { layout: INLINE_CONTENT, content })};
58
- if (data) token.data = data;
59
- remainStr = remainStr.substring(index! + matchStr.length);
60
- break;
61
- }
62
- }
63
- if (!token) {
64
- token = { type: 'TEXT', layout: INLINE_TEXT, text: remainStr };
65
- remainStr = '';
66
- }
67
- tokens.push(token);
68
- }
69
- return tokens;
70
- }
71
-
72
- use(...handle: ((parser: this) => void)[]) {
73
- forEach(handle, fn => fn(this));
74
- return this;
75
- }
76
- }
77
-
78
- export type BlockTokenizer = {
79
- regex: RegExp;
80
- handle: (matches: RegExpMatchArray, position: number, lines: string[]) => { content: (InlineToken | BlockToken)[], multiLine?: BlockTokenizerMultiLine, data?: {[key: string]: any} };
81
- }
82
- export type BlockTokenizerMultiLine = {
83
- skip: number;
84
- tokens: BlockToken[];
85
- }
86
- export type InlineTokenizer = {
87
- regex: RegExp;
88
- handle: (matches: RegExpMatchArray) => { content: InlineToken[] | string, data?: {[key: string]: any} }
89
- }
90
-
91
- export interface TokenBase {
92
- type: string;
93
- layout: 'BLOCK' | 'INLINE_CONTENT' | 'INLINE_TEXT';
94
- content?: Token[];
95
- text?: string;
96
- data?: {[key: string]: any};
97
- }
98
- export interface BlockToken extends TokenBase {
99
- layout: 'BLOCK'
100
- content: Token[];
101
- }
102
- export interface InlineTextToken extends TokenBase {
103
- layout: 'INLINE_TEXT'
104
- text: string;
105
- }
106
- export interface InlineContentToken extends TokenBase {
107
- layout: 'INLINE_CONTENT'
108
- content: (InlineToken)[];
109
- }
110
- export type InlineToken = InlineTextToken | InlineContentToken;
111
- export type Token = BlockToken | InlineToken;
@@ -1,34 +0,0 @@
1
- import { forEach, isString } from "@amateras/utils";
2
- import { type Token } from "./MarkdownLexer";
3
-
4
- export class MarkdownParser {
5
- processors = new Map<string, MarkdownParseProcessor>();
6
-
7
- parse(tokens: (Token)[]) {
8
- let html = '';
9
- let i = 0;
10
- if (!tokens) return html;
11
- while (i < tokens.length) {
12
- const token = tokens[i]!;
13
- const processor = this.processors.get(token.type);
14
- if (processor) {
15
- const result = processor(token, tokens.slice(i));
16
- if (isString(result)) {
17
- html += result;
18
- } else {
19
- html += result.html;
20
- i += result.skipTokens;
21
- }
22
- }
23
- i++;
24
- }
25
- return html;
26
- }
27
-
28
- use(...handle: ((parser: this) => void)[]) {
29
- forEach(handle, fn => fn(this));
30
- return this;
31
- }
32
- }
33
-
34
- export type MarkdownParseProcessor = (token: Token, tokens: Token[]) => (string | { html: string, skipTokens: number })
@@ -1,46 +0,0 @@
1
- import { ALERT, ALERT_LINE, BLOCK } from "#lib/type";
2
- import { setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { BlockToken, MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
- import { uppercase } from "@amateras/utils";
6
-
7
- export const alertProcessor = (parser: MarkdownParser) => setProcessor(parser, ALERT, (token, tokens) => {
8
- let html = '';
9
- let i = 1;
10
- while (i < tokens.length) {
11
- const token = tokens[i]!;
12
- if (token.type !== ALERT_LINE) break;
13
- html += parser.parse(token.content![0]!.content!);
14
- i++;
15
- }
16
- const alertType = token.data?.alertType as string;
17
- return {
18
- html: `<blockquote class="alert alert-${alertType}"><p class="alert-title">${uppercase(alertType, 0, 1)}</p>${html}</blockquote>`,
19
- skipTokens: i
20
- }
21
- })
22
-
23
- export const alertTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, ALERT, {
24
- regex: /^> ?\[!(?:(?:NOTE)|(?:TIP)|(?:IMPORTANT)|(?:WARNING)|(?:CAUTION))\]/,
25
- handle(_, position, lines) {
26
- const tokens: BlockToken[] = [];
27
- const match = lines[position]!.match(/> ?\[!(.+?)\]/);
28
- const alertType = match?.[1]?.toLowerCase();
29
- position++
30
- while (position < lines.length) {
31
- const line = lines[position]!;
32
- const match = line.match(/^> ?(.+)/);
33
- if (match) tokens.push({ layout: BLOCK, type: ALERT_LINE, content: lexer.blockTokenize(match[1]!) });
34
- else break;
35
- position++;
36
- }
37
- return {
38
- content: [],
39
- data: { alertType },
40
- multiLine: {
41
- skip: position,
42
- tokens
43
- }
44
- }
45
- },
46
- })
@@ -1,35 +0,0 @@
1
- import { BLOCKQUOTE } from "#lib/type";
2
- import { htmltag, setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const blockquoteProcessor = (parser: MarkdownParser) => setProcessor(parser, BLOCKQUOTE, (token, tokens) => {
7
- let i = 0;
8
- const blockquote = (deep: number) => {
9
- let html = '';
10
- while (i < tokens.length) {
11
- const {type, content, data} = tokens[i]!;
12
- if (type !== BLOCKQUOTE) break;
13
- if (data!.deep > deep) html += blockquote(data!.deep);
14
- else if (data!.deep < deep) break;
15
- else { html += parser.parse(content!); i++ }
16
- }
17
- return htmltag('blockquote', html)
18
- }
19
- return {
20
- html: blockquote(token.data!.deep),
21
- skipTokens: i
22
- }
23
- })
24
-
25
- export const blockquoteTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, BLOCKQUOTE, {
26
- regex: /^(>+) ?(.+)?/,
27
- handle(matches) {
28
- return {
29
- content: lexer.blockTokenize(matches[2] ?? ''),
30
- data: {
31
- deep: (matches[1]!.length - 1)
32
- }
33
- }
34
- }
35
- })
@@ -1,11 +0,0 @@
1
- import { BOLD } from "#lib/type";
2
- import { htmltag, setInlineTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const boldProcessor = (parser: MarkdownParser) => setProcessor(parser, BOLD, token => htmltag('b', parser.parse(token.content!)))
7
-
8
- export const boldTokenizer = (lexer: MarkdownLexer) => setInlineTokenizer(lexer, BOLD, {
9
- regex: /\*\*(.+?\*?)\*\*/,
10
- handle: matches => ({ content: lexer.inlineTokenize(matches[1]!) })
11
- })
@@ -1,11 +0,0 @@
1
- import { CODE } from "#lib/type";
2
- import { htmlEscapeChar, htmltag, setInlineTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const codeProcessor = (parser: MarkdownParser) => setProcessor(parser, CODE, token => htmltag('code', htmlEscapeChar(token.text!)))
7
-
8
- export const codeTokenizer = (lexer: MarkdownLexer) => setInlineTokenizer(lexer, CODE, {
9
- regex: /`(.+?)`/,
10
- handle: matches => ({ content: matches[1]! })
11
- })
@@ -1,44 +0,0 @@
1
- import { BLOCK, CODE_END, CODE_LINE, CODE_START } from "#lib/type";
2
- import { htmlEscapeChar, setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { BlockToken, MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const codeblockProcessor = (parser: MarkdownParser) => setProcessor(parser, CODE_START, (token, tokens) => {
7
- let html = '';
8
- let i = 1;
9
- while (i < tokens.length) {
10
- const token = tokens[i]!;
11
- if (token.type === CODE_END) break;
12
- html += token.content![0]!.text;
13
- i++;
14
- }
15
- return {
16
- html: `<pre><code${token.data?.lang ? ` lang="${token.data.lang}"` : ''}>${htmlEscapeChar(html)}</code></pre>`,
17
- skipTokens: i
18
- }
19
- })
20
-
21
- export const codeblockTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, CODE_START, {
22
- regex: /^```(\w+)?/,
23
- handle: (matches, position, lines) => {
24
- const tokens: BlockToken[] = [];
25
- position++;
26
- while (position < lines.length) {
27
- const line = lines[position]!;
28
- position++;
29
- if (line.includes('```')) {
30
- tokens.push({ layout: BLOCK, type: CODE_END, content: [] })
31
- break;
32
- }
33
- tokens.push({ layout: BLOCK, type: CODE_LINE, content: [{ layout: "INLINE_TEXT", type: 'CODE_TEXT', text: `${line}\n` }] });
34
- }
35
- return {
36
- content: [],
37
- data: { lang: matches[1] },
38
- multiLine: {
39
- skip: position,
40
- tokens
41
- }
42
- }
43
- }
44
- })
@@ -1,14 +0,0 @@
1
- import { HEADING } from "#lib/type";
2
- import { htmltag, setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const headingProcessor = (parser: MarkdownParser) => setProcessor(parser, HEADING, token => {
7
- const tagname = `h${token.data!.level}`;
8
- return htmltag(tagname, parser.parse(token.content!))
9
- })
10
-
11
- export const headingTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, HEADING, {
12
- regex: /^(#+) (.+)/,
13
- handle: matches => ({ content: lexer.inlineTokenize(matches[2]!), data: { level: matches[1]!.length } })
14
- })
@@ -1,11 +0,0 @@
1
- import { HORIZONTAL_RULE } from "#lib/type";
2
- import { setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const horizontalRuleProcessor = (parser: MarkdownParser) => setProcessor(parser, HORIZONTAL_RULE, _ => `<hr>`)
7
-
8
- export const horizontalRuleTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, HORIZONTAL_RULE, {
9
- regex: /^---/,
10
- handle: _ => ({ content: [] })
11
- })
@@ -1,23 +0,0 @@
1
- import { IMAGE } from "#lib/type";
2
- import { setInlineTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const imageProcessor = (parser: MarkdownParser) => setProcessor(parser, IMAGE, token => {
7
- const { url, title } = token.data!;
8
- return `<img alt="${parser.parse(token.content!)}" src="${url}"${title ? ` title="${title}"` : ''}>`
9
- })
10
-
11
- export const imageTokenizer = (lexer: MarkdownLexer) => setInlineTokenizer(lexer, IMAGE, {
12
- regex: /^!\[(.+?)\]\((.+?)\)/,
13
- handle: matches => {
14
- const [_, alt, detail] = matches as [string, string, string];
15
- const [__, url, title] = detail.match(/(\w\w+?:\/\/[^\s]+)(?: "(.+?)")?/) as [string, string, string];
16
- return {
17
- content: lexer.inlineTokenize(alt),
18
- data: {
19
- url, title
20
- }
21
- }
22
- }
23
- })
@@ -1,11 +0,0 @@
1
- import { ITALIC } from "#lib/type";
2
- import { setInlineTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
-
6
- export const italicProcessor = (parser: MarkdownParser) => setProcessor(parser, ITALIC, token => `<i>${parser.parse(token.content!)}</i>`)
7
-
8
- export const italicTokenizer = (lexer: MarkdownLexer) => setInlineTokenizer(lexer, ITALIC, {
9
- regex: /\*(.+?)\*/,
10
- handle: matches => ({ content: lexer.inlineTokenize(matches[1]!) })
11
- })
@@ -1,46 +0,0 @@
1
- import { LINK, QUICK_LINK } from "#lib/type";
2
- import { setInlineTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer, Token } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
- import { isUndefined } from "@amateras/utils";
6
-
7
- export const linkProcessor = (parser: MarkdownParser) => {
8
- const linkProcessor = (token: Token) => {
9
- const {href, email, title} = token.data!;
10
- return `<a href="${isUndefined(href) ? `mailto:${email}` : href}"${title ? ` title="${title}"` : ''}>${token.text ?? parser.parse(token.content!)}</a>`
11
- }
12
- setProcessor(parser, QUICK_LINK, linkProcessor)
13
- setProcessor(parser, LINK, linkProcessor)
14
- }
15
-
16
- export const linkTokenizer = (lexer: MarkdownLexer) => {
17
-
18
- setInlineTokenizer(lexer, LINK, {
19
- regex: /\[(.+?)\]\(((?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:[^\s)]+))(?: "(.+)?")?\)/,
20
- handle: matches => {
21
- const [_, alt, detail, title] = matches as [string, string, string, string];
22
- const match = detail.match(/(?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:\/\/[^\s]+)/);
23
- const [resolver] = match!;
24
- const email_or_href = resolver.includes('@') ? { email: resolver }: { href: resolver };
25
- return {
26
- content: lexer.inlineTokenize(alt),
27
- data: {
28
- title, ...email_or_href
29
- }
30
- }
31
- }
32
- })
33
- setInlineTokenizer(lexer, QUICK_LINK, {
34
- regex: /<((?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:[^\s>]+))>/,
35
- handle: matches => {
36
- const [_, detail] = matches as [string, string];
37
- const match = detail.match(/(?:\w+?@(?:\w|\.\w)+)|(?:\w\w+?:\/\/[^\s]+)/);
38
- const [resolver] = match!;
39
- const email_or_href = resolver.includes('@') ? { email: resolver }: { href: resolver };
40
- return {
41
- content: resolver,
42
- data: email_or_href
43
- }
44
- }
45
- })
46
- }
@@ -1,121 +0,0 @@
1
- import { EMPTY_LINE, ORDERED_LIST_ITEM, TEXT_LINE, UNORDERED_LIST_ITEM } from "#lib/type";
2
- import { htmltag, setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { MarkdownLexer, Token } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
- import { equal, isString } from "@amateras/utils";
6
-
7
- export const listProcessor = (parser: MarkdownParser) => {
8
- const listType = (type: string) => type === ORDERED_LIST_ITEM ? 'ol' : 'ul'
9
- const listProcessor = (token: Token, tokens: Token[]) => {
10
- let i = 0;
11
- // cache the list by deep number
12
- const deepListMap = new Map<number, List>();
13
-
14
- const listGenerator = (type: string, deep: number) => {
15
- const getList = deepListMap.get(deep)
16
- const list = getList && listType(type) === getList.tagname ? getList : List(listType(type), []);
17
- deepListMap.set(deep, list);
18
-
19
- while (i < tokens.length) {
20
- const token = tokens[i]!;
21
- const tokenType = token.type;
22
- // if token type not equal list item / empty line / text line, then finish loop
23
- if (!equal(tokenType, ORDERED_LIST_ITEM, UNORDERED_LIST_ITEM, EMPTY_LINE, TEXT_LINE)) { i--; break};
24
- // if token type equal text line
25
- if (tokenType === TEXT_LINE) {
26
- const text = token.content![0]?.text;
27
- // if text start with double space
28
- if (text?.match(/^\s\s/)) {
29
- const match = text.match(/^(\s+)(.+)?/)!;
30
- // if no content, then next token
31
- if (!match[2]) { i++; continue }
32
- token.data = { deep: Math.trunc(match[1]!.length / 2) - 1 }
33
- }
34
- // if text start with tab
35
- else if (text?.match(/^\t/)) {
36
- const match = text.match(/^(\t+)(.+)?/)!;
37
- // if no content, then next token
38
- if (!match[2]) { i++; continue }
39
- token.data = { deep: match[1]!.length - 1 }
40
- }
41
- // else break
42
- else {i--; break};
43
- }
44
- // if token type equal empty line, jump to next token
45
- if (tokenType === EMPTY_LINE) i++;
46
- // if token deep number not equal latest deep of list
47
- else if (token.data!.deep !== deep) {
48
- // if bigger, push deeper list into current list item
49
- if (token.data!.deep > deep) deepListMap.get(deep)?.items.at(-1)?.content.push(listGenerator(tokenType, token.data!.deep))
50
- // else delete current deep cache and return to upper list
51
- else { deepListMap.delete(deep); break; }
52
- }
53
- // if token type equal text line, convert this list to paragraph mode
54
- else if (tokenType === TEXT_LINE) {
55
- list.paragraph = true;
56
- list.items.at(-1)?.content.push(parser.parse(token.content!))
57
- i++
58
- }
59
- // if list type not equal, then finish loop
60
- else if (tokenType !== type) {
61
- deepListMap.delete(deep);
62
- break;
63
- }
64
- // push list item
65
- else {
66
- list.items.push(ListItem([parser.parse(token.content!)]));
67
- i++
68
- }
69
- }
70
- return list;
71
- }
72
-
73
- return {
74
- html: `${listGenerator(token.type, token.data!.deep)}`,
75
- skipTokens: i
76
- }
77
- }
78
-
79
- interface ListItem { content: (string | List)[], toString(): string }
80
- const ListItem = (content: (string | List)[]): ListItem => ({
81
- content: content,
82
- toString() { return htmltag('li', this.content.join('')) }
83
- })
84
-
85
- interface List { tagname: string, items: ListItem[], paragraph: boolean, toString(): string }
86
- const List = (tagname: 'ul' | 'ol', items: ListItem[]): List => ({
87
- tagname: tagname,
88
- items: items,
89
- paragraph: false,
90
- toString() {
91
- if (this.paragraph) this.items.forEach(item => item.content.forEach((text, i) => isString(text) && (item.content[i] = htmltag('p', text))))
92
- return htmltag(this.tagname, this.items.join(''))
93
- }
94
- })
95
-
96
- setProcessor(parser, UNORDERED_LIST_ITEM, listProcessor);
97
- setProcessor(parser, ORDERED_LIST_ITEM, listProcessor);
98
- }
99
-
100
- export const listTokenizer = (lexer: MarkdownLexer) => {
101
- const listHandle = (matches: RegExpMatchArray) => {
102
- const prefix = matches[0].split(/[-*]/)[0]!;
103
- const spaces = prefix.match(/\s/)?.length ?? 0;
104
- const tabs = prefix.match(/\t/)?.length ?? 0;
105
- return ({
106
- content: lexer.inlineTokenize(matches[1]!),
107
- data: {
108
- deep: Math.trunc(tabs + spaces / 2)
109
- }
110
- })
111
- }
112
- setBlockTokenizer(lexer, UNORDERED_LIST_ITEM, {
113
- regex: /^(?:[\s\t]+)?[-*] (.+)/,
114
- handle: listHandle
115
- })
116
-
117
- setBlockTokenizer(lexer, ORDERED_LIST_ITEM, {
118
- regex: /^(?:[\s\t]+)?\d+\. (.+)/,
119
- handle: listHandle
120
- })
121
- }
@@ -1,67 +0,0 @@
1
- import { BLOCK, TABLE, TABLE_COLUMN, TABLE_ROW } from "#lib/type";
2
- import { htmltag, setBlockTokenizer, setProcessor } from "#lib/util";
3
- import type { BlockToken, MarkdownLexer } from "#structure/MarkdownLexer";
4
- import type { MarkdownParser } from "#structure/MarkdownParser";
5
- import { _Array_from } from "@amateras/utils";
6
-
7
- export const tableProcessor = (parser: MarkdownParser) => setProcessor(parser, TABLE, (token) => {
8
- let thead = '';
9
- let tbody = '';
10
- let rowIndex = 0;
11
- for (const row of token.content!) {
12
- let rowHTML = '';
13
- for (let i = 0; i < row.content!.length; i++) {
14
- const col = row.content![i]!;
15
- const align = token.data!.align[i];
16
- const tagname = rowIndex === 0 ? 'th' : 'td';
17
- rowHTML += `<${tagname} align="${align ?? 'left'}">${parser.parse(col.content!)}</${tagname}>`
18
- }
19
- if (rowIndex === 0) thead += htmltag('thead', htmltag('tr', rowHTML));
20
- else tbody += htmltag('tr', rowHTML);
21
- rowIndex++
22
- }
23
- tbody = htmltag('tbody', tbody);
24
- return htmltag('table', thead + tbody)
25
- })
26
-
27
- export const tableTokenizer = (lexer: MarkdownLexer) => setBlockTokenizer(lexer, TABLE, {
28
- regex: /\|(?:.+\|)+/,
29
- handle(_, position, lines) {
30
- const tokens: BlockToken[] = [];
31
- const align = []
32
- while (position < lines.length) {
33
- const row: BlockToken = {
34
- type: TABLE_ROW,
35
- layout: BLOCK,
36
- content: []
37
- }
38
- const line = lines[position]!;
39
- const matches = _Array_from(line.matchAll(/\| ([^|]+)/g));
40
- if (!matches.length) break;
41
- for (const match of matches) {
42
- const text = match[1]!;
43
- const separator = text.match(/(:)?---+(:)?/);
44
- if (separator) {
45
- const [_, LEFT, RIGHT] = separator;
46
- align.push(RIGHT ? LEFT ? 'center' : 'right' : 'left');
47
- continue;
48
- }
49
- row.content.push({
50
- type: TABLE_COLUMN,
51
- content: lexer.inlineTokenize(text.trim()),
52
- layout: BLOCK
53
- })
54
- }
55
- if (row.content.length) tokens.push(row);
56
- position++
57
- }
58
- return {
59
- content: tokens,
60
- data: { align },
61
- multiLine: {
62
- skip: position,
63
- tokens: []
64
- }
65
- }
66
- },
67
- })