···2020 // all state is stored in these vars (and REGEX.lastIndex)
2121 let current, brackets
22222323+ // About __proto__ in object literals:
2424+ // https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-runtime-semantics-propertydefinitionevaluation
2525+2326 // elements which can survive an eol (without a body)
2427 const IS_BLOCK = {__proto__:null, code:1, divider:1, ROOT:1, heading:1, quote:1, table:1, table_cell:1, image:1, video:1, audio:1, spoiler:1, align:1, list:1, list_item:1, youtube:1}
2528···7174 const ARGS_CODE = // ... ```
7275 /(?: *([-\w.+#$ ]+?) *(?:\n|$))?([^]*?)(?:```|$)/y
73767474- // problem with improving style parsing:
7575- // sometimes a style tag might be valid as both a start and end tag?
7676- // and we don't know until we also check the previous char
7777 PAT`[\n]?[}]${{ BLOCK_END: 0}}`
7878 PAT`[\n]${{ NEWLINE: 0}}`
7979 PAT`{BOL}[#]{1,4}${{ HEADING: ARGS_HEADING}}`
···150150 }
151151 TEXT(token)
152152 } break; case 'BLOCK_END': {
153153- if (brackets<=0) {
153153+ if (brackets>0) {
154154+ while (!current.body)
155155+ CANCEL()
156156+ if ('invalid'===current.type) {
157157+ if ("\n}"==token)
158158+ NEWLINE(false) // false since we already closed everything
159159+ TEXT("}")
160160+ }
161161+ CLOSE()
162162+ } else {
154163 // hack:
155164 if ("\n}"==token)
156165 NEWLINE(true)
157166 TEXT("}")
158158- return
159167 }
160160- // only runs if at least 1 element has a body, so this won't fail:
161161- while (!current.body)
162162- CANCEL()
163163- if ('invalid'===current.type)
164164- TEXT("}")
165165- CLOSE()
166168 } break; case 'NULL_ENV': {
167169 OPEN('null_env', token, null, true)
168170 current.prev = current.parent.prev
···469471 }
470472471473 function parse(text) {
472472- let tree = {type: 'ROOT', token: "", content: [], prev: 'all_newline'}
474474+ let tree = {type: 'ROOT', content: [], prev: 'all_newline'}
473475 current = tree
474476 brackets = 0
475477