this repo has no description

FIX STYLE TAGS (and fix tests)

12Me21 19ac33f7 84ed8d85

+66 -39
+55 -32
parse.js
··· 72 72 /(?:\[([^\]\n]*)\])? */y 73 73 74 74 const ARGS_CODE = // ... ``` 75 - /(?: *([-\w.+#$ ]+?) *(?:\n|$))?([^]*?)(?:```|$)/y 75 + /(?: *([-\w.+#$ ]+?) *(?=\n|$))?\n?([^]*?)(?:```|$)/y 76 76 77 77 PAT`[\n]?[}]${{ BLOCK_END: 0}}` 78 78 PAT`[\n]${{ NEWLINE: 0}}` 79 79 PAT`{BOL}[#]{1,4}${{ HEADING: ARGS_HEADING}}` 80 80 PAT`{BOL}[-]{3,}{EOL}${{ DIVIDER: 0}}` 81 - PAT`([*][*]|[_][_]|[~][~]|[/])(?=[\w]${{ STYLE_START: 0}}|${{ STYLE_END: 0}})` 81 + PAT`([*][*]|[_][_]|[~][~]|[/])${{ STYLE: 0}}` 82 82 PAT`[\\][a-z]+(?![a-zA-Z0-9])${{ TAG: 0}}` 83 83 PAT`[\\][{][\n]?${{ NULL_ENV: 0}}` 84 84 PAT`[\\]{ANY}${{ ESCAPED: 0}}` ··· 95 95 96 96 //todo: org tables separators? 97 97 98 - //[\`]{2}[^\n]*${{ LINE_CODE: 0}} 99 - //[\`]{2}[^\`\n]*([\`][^\`\n]+)*[\`]{0,3}${{ INLINE_CODE_2: 0}} 100 - 101 98 // TokenType -> ArgRegex 102 99 const TAGS = { 103 100 __proto__:null, ··· 114 111 '\\key': ARGS_WORD, 115 112 } 116 113 114 + function find_style(token) { 115 + for (let c=current; 'style'===c.type; c=c.parent) 116 + if (c.token===token) 117 + return c 118 + } 119 + 117 120 // process a token 118 121 // 📥 _token_type 🏷 TokenType 📝 119 122 // 📥 token 🏷 Text 📝 token text, including arguments ··· 133 136 OPEN('heading', token, args, body) 134 137 } break; case 'DIVIDER': { 135 138 BLOCK('divider') 136 - } break; case 'STYLE_START': { 137 - OPEN('style', token) 138 - } break; case 'STYLE_END': { 139 - while ('style'===current.type) { 140 - if (token===current.token) { // found opening 141 - current.type = { 142 - __proto__:null, 143 - '**': 'bold', '__': 'underline', 144 - '~~': 'strikethrough', '/': 'italic', 145 - }[current.token] 146 - CLOSE() 147 - return 148 - } 149 - CANCEL() // different style (kill) 150 - } 151 - TEXT(token) 152 139 } break; case 'BLOCK_END': { 153 140 if (brackets>0) { 154 141 while (!current.body) ··· 372 359 CLOSE() 373 360 } else 374 361 CLOSE() 362 + // todo: maybe also cancel rows with just 1 unclosed cell? 363 + // like `| abc` -> text 375 364 } 376 365 377 366 function get_last(block) { ··· 478 467 // MAIN LOOP // 479 468 let prev = -1 480 469 let last = REGEX.lastIndex = 0 481 - for (let match; match=REGEX.exec(text); ) { 470 + let match 471 + function nevermind() { 472 + REGEX.lastIndex = match.index+1 473 + last = match.index 474 + } 475 + function accept(i) { 476 + last = i 477 + } 478 + main: while (match = REGEX.exec(text)) { 482 479 // check for infinite loops 483 480 if (match.index===prev) 484 481 throw ["INFINITE LOOP", match] 485 482 prev = match.index 486 483 // 1: insert the text from after previous token 484 + // idea: defer this until we actually KNOW we matched a token 487 485 TEXT(text.substring(last, match.index)) 488 486 // 2: figure out which token type was matched 489 487 let token_text = match[0] ··· 500 498 type = 'INVALID_TAG' 501 499 argregex = ARGS_NORMAL 502 500 } 501 + } else if ('STYLE'===type) { 502 + let before = text.charAt(match.index-1) 503 + let after = text.charAt(REGEX.lastIndex) 504 + // try close? 505 + if ('style'===current.type && !` \t\n,'"`.includes(before) && `- \t\n.,:;!?'")}`.includes(after)) { 506 + let c = find_style(token_text) 507 + if (c) { 508 + accept(REGEX.lastIndex) 509 + while (current != c) 510 + CANCEL() 511 + current.type = { 512 + __proto__:null, 513 + '**': 'bold', '__': 'underline', 514 + '~~': 'strikethrough', '/': 'italic', 515 + }[current.token] 516 + CLOSE() 517 + continue main 518 + } 519 + } 520 + // open? 521 + if (` \t\n({'"`.includes(before) && !` \t\n,'"`.includes(after)) { 522 + accept(REGEX.lastIndex) 523 + OPEN('style', token_text) 524 + continue main 525 + } 526 + nevermind() 527 + continue main 503 528 } else if ('TABLE_CELL'===type && !in_table()) { 504 - REGEX.lastIndex = match.index+1 505 - last = match.index 506 - continue 529 + nevermind() 530 + continue main 507 531 } else { 508 532 argregex = ARGTYPES[group_num] 509 533 } 510 - 511 534 // 4: parse args and { 512 535 let start_line = false 513 536 if (!argregex) { 537 + accept(REGEX.lastIndex) 514 538 let body = 'NULL_ENV'===type //h 515 539 PROCESS(type, token_text, null, body, token_text) 516 - last = REGEX.lastIndex 517 540 if (body || 'NEWLINE'===type) 518 541 start_line = true 519 542 } else { 520 543 // try to match arguments 521 544 argregex.lastIndex = REGEX.lastIndex 522 545 let argmatch = argregex.exec(text) 523 - if (null===argmatch) { // INVALID! skip 1 char 524 - REGEX.lastIndex = match.index+1 525 - last = match.index 526 - continue 546 + if (null===argmatch) { 547 + nevermind() 548 + continue main 527 549 } 528 550 let full_token = token_text+argmatch[0] 529 551 let args = argmatch[1] ··· 534 556 args = parse_args(args) 535 557 start_line = body 536 558 } 559 + accept(REGEX.lastIndex = argregex.lastIndex) 560 + 537 561 PROCESS(type, full_token, args, body, token_text) 538 562 // word 539 563 if (undefined!==word) { ··· 541 565 CLOSE() 542 566 start_line = false 543 567 } 544 - last = REGEX.lastIndex = argregex.lastIndex 545 568 } 546 569 // 5: handle start-of-line 547 570 if (start_line) {
+11 -7
testing/index.html
··· 49 49 🟩 unclosed table cell 50 50 |[red] hack|a 51 51 bcdefa 52 - 🟩 {"type":"ROOT","content":[{"type":"table","content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","content":["hack"],"args":{"color":"red"}}]}]},"a","\n","bcdefa"]} 52 + 🟩 {"type":"ROOT","content":[{"type":"table","args":null,"content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{"color":"red"},"content":["hack"]},{"type":"table_cell","args":{},"content":["a"]}]}]},"bcdefa"],"prev":"text"} 53 53 54 54 🟩 unclosed icode 55 55 `eabcn ··· 178 178 codeblock 179 179 abc 180 180 ``` 181 + missing start linebreak: 182 + ```x=1 183 + x=x+1 184 + ``` 181 185 ``` c++ 11 182 186 lang 183 187 aaa 184 188 ``` 185 189 ```inline``` 186 190 ```js 187 - no lb``` 191 + missing end linebreak (todo: idk about this)``` 188 192 ``` 189 193 190 194 blank lines ··· 197 201 ``` 198 202 unclosed 199 203 200 - 🟩 {"type":"ROOT","content":[{"type":"code","args":{"text":"normal\ncodeblock\nabc\n"}},{"type":"code","args":{"text":"lang\naaa\n","lang":"c++ 11"}},{"type":"code","args":{"text":"inline"}},{"type":"code","args":{"text":"no lb","lang":"js"}},{"type":"code","args":{"text":"\nblank lines\n\n"}},"not at start ","`","`",{"type":"icode","args":{"text":"abc"}},"`","`","\n",{"type":"code","args":{"text":"end not at start\nheck"}},"abc","\n",{"type":"code","args":{"text":"unclosed\n"}}]} 204 + 🟩 {"type":"ROOT","content":[{"type":"code","args":{"text":"normal\ncodeblock\nabc\n"}},"missing start linebreak:","\n",{"type":"code","args":{"text":"x=1\nx=x+1\n"}},{"type":"code","args":{"text":"lang\naaa\n","lang":"c++ 11"}},{"type":"icode","args":{"text":"`inline`"}},"\n",{"type":"code","args":{"text":"missing end linebreak (todo: idk about this)","lang":"js"}},{"type":"code","args":{"text":"\nblank lines\n\n"}},"not at start ",{"type":"icode","args":{"text":"`abc`"}},"\n",{"type":"code","args":{"text":"end not at start\nheck"}},"abc","\n",{"type":"code","args":{"text":"unclosed\n"}}],"prev":"block"} 201 205 202 206 🟩 paragraphs 203 207 paragraph1 ··· 243 247 `abc 244 248 def` 245 249 246 - 🟩 {"type":"ROOT","content":["\n","\n",{"type":"table","content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","content":["abc"],"args":{"color":"gray"}},{"type":"table_cell","content":["abc"],"args":{"color":"blue"}}]}]}," ",{"type":"icode","args":{"text":"test"}}," ","\n",{"type":"image","args":{"url":"https://qcs.shsbs.xyz/api/file/raw/31760?size=30&crop=true"}},"the sand can be eatena","\n","\tabc","\n",{"type":"spoiler","content":["abc defaaaa ",{"type":"spoiler","content":["a"],"args":{"label":"spoiler"}}],"args":{"label":"spoiler"}},"aaaaaa","\n",{"type":"align","content":["heck"],"args":{"align":"right"}},{"type":"align","content":["| ","table"," |"],"args":{"align":"center"}},{"type":"divider"},{"type":"key","content":[{"type":"key","content":["a"]},{"type":"key","content":["b"]},"\n",{"type":"key","content":["ctrl"]},{"type":"invalid","content":[" ha","}"],"args":{"text":"\\abcdef[aaa]{","reason":"invalid tag"}},"\n",{"type":"key","content":["shift"]},"\n",{"type":"key","content":["ctrl"]},"+",{"type":"key","content":["shift"]},"+",{"type":"key","content":["M"]}]},"\n",{"type":"spoiler","content":["abc"],"args":{"label":"spoiler"}},"/","test","\n","a","/","\n",{"type":"icode","args":{"text":"abc"}},"\n","def","`","\n","\n"]} 250 + 🟩 {"type":"ROOT","content":["\n","\n",{"type":"table","args":null,"content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{"color":"gray"},"content":["abc"]},{"type":"table_cell","args":{"color":"blue"},"content":["abc"]},{"type":"table_cell","args":{},"content":[{"type":"icode","args":{"text":"test"}}," "]}]}]},{"type":"image","args":{"url":"https://qcs.shsbs.xyz/api/file/raw/31760?size=30&crop=true"}},"the sand can be eatena","\n","\tabc","\n",{"type":"spoiler","args":{"label":"spoiler"},"content":["abc defaaaa ",{"type":"spoiler","args":{"label":"spoiler"},"content":["a"]}]},"aaaaaa","\n",{"type":"align","args":{"align":"right"},"content":["heck"]},{"type":"align","args":{"align":"center"},"content":["| table"," ","|"]},{"type":"divider"},{"type":"key","args":null,"content":[{"type":"key","args":null,"content":["a"]},{"type":"key","args":null,"content":["b"]},"\n",{"type":"key","args":null,"content":["ctrl"]},{"type":"invalid","args":{"text":"\\abcdef[aaa]{","reason":"invalid tag"},"content":[" ha","}"]},"\n",{"type":"key","args":null,"content":["shift"]},"\n",{"type":"key","args":null,"content":["ctrl"]},"+",{"type":"key","args":null,"content":["shift"]},"+",{"type":"key","args":null,"content":["M"]}]},"\n",{"type":"spoiler","args":{"label":"spoiler"},"content":["abc"]},"/","test","\n","a","/","\n",{"type":"icode","args":{"text":"abc"}},"\n","def",{"type":"icode","args":{"text":""}},"\n","\n"],"prev":"newline"} 247 251 248 252 🟩 idk..env close 249 253 >{ ··· 270 274 /italic | abc/ 271 275 | table /test | /italic | abc/ | 272 276 abc /heck | 273 - 🟩 {"type":"ROOT","content":[{"type":"italic","content":["italic"," | ","abc"]},"\n",{"type":"table","content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{},"content":["table ","/","test"]},{"type":"table_cell","args":{},"content":["/","italic"]},{"type":"table_cell","args":{},"content":["abc","/"]}]}]},"abc ","/","heck"," |"]} 277 + 🟩 {"type":"ROOT","content":[{"type":"italic","content":["italic"," ","| abc"]},"\n",{"type":"table","args":null,"content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{},"content":["table ","/","test"]},{"type":"table_cell","args":{},"content":["/","italic"]},{"type":"table_cell","args":{},"content":["abc","/"]}]}]},"abc ","/","heck"," ","|"],"prev":"text"} 274 278 275 279 🟩 list 276 280 - abc ··· 327 331 |abc|abc 328 332 the sand | can be eaten | 329 333 heck | 330 - 🟩 {"type":"ROOT","content":["|","\n","wow"," |\n|","abc","\n",{"type":"table","content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{},"content":["abc"]},{"type":"table_cell","args":{},"content":["abc","\n","the sand"]},{"type":"table_cell","args":{},"content":["can be eaten"]}]}]},"heck"," |"]} 334 + 🟩 {"type":"ROOT","content":["|","\n","wow"," ","|","\n",{"type":"table","args":null,"content":[{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{},"content":["abc"]}]},{"type":"table_row","args":{},"content":[{"type":"table_cell","args":{},"content":["abc"]},{"type":"table_cell","args":{},"content":["abc"]}]}]},"the sand"," ","| can be eaten"," ","|","\n","heck"," ","|"],"prev":"text"} 331 335 332 336 🟩 urls 333 337 aaahttp://example.com ··· 336 340 (http://example.com/heck(123)) 337 341 http://example.com/heck(123)abc; 338 342 339 - 🟩 {"type":"ROOT","content":["aaahttp:","/","/","example.com","\n",{"type":"simple_link","args":{"url":"http://example.com"}},"?","\n","(",{"type":"simple_link","args":{"url":"http://example.com"}},")","\n","(",{"type":"simple_link","args":{"url":"http://example.com/heck(123)"}},")","\n",{"type":"simple_link","args":{"url":"http://example.com/heck(123)abc"}},";","\n","\n"]} 343 + 🟩 {"type":"ROOT","content":["aaahttp:","/","/example.com","\n",{"type":"simple_link","args":{"url":"http://example.com"}},"?","\n","(",{"type":"simple_link","args":{"url":"http://example.com"}},")","\n","(",{"type":"simple_link","args":{"url":"http://example.com/heck(123)"}},")","\n",{"type":"simple_link","args":{"url":"http://example.com/heck(123)abc"}},";","\n","\n"]}