go back and tweak the effing fenced code disaster area so that it will break fenced code out into its own div and consume html & footnotes at the top level.

This commit is contained in:
jessica parsons
2026-05-31 14:12:03 -07:00
parent ff09a191cd
commit 39be61ef2c
6 changed files with 105 additions and 98 deletions
+1
View File
@@ -22,6 +22,7 @@ Pptype(int typ)
switch (typ) {
case WHITESPACE: return "whitespace";
case CODE : return "code";
case FENCEDCODE: return "fenced code";
case QUOTE : return "quote";
case MARKUP : return "markup";
case HTML : return "html";
+5 -5
View File
@@ -1867,11 +1867,7 @@ printblock(Paragraph *pp, MMIOT *f)
Qstring(Begin[align], f);
do {
if ( t->is_fenced ) {
text(f);
t = printfenced(t, f);
}
else if ( S(t->text) ) {
if ( S(t->text) ) {
if ( t->next && S(t->text) > 2
&& T(t->text)[S(t->text)-2] == ' '
&& T(t->text)[S(t->text)-1] == ' ' ) {
@@ -2060,6 +2056,10 @@ display(Paragraph *p, MMIOT *f)
printhtml(p->text, f);
break;
case FENCEDCODE:
printfenced(p->text, f);
break;
case CODE:
printcode(p->text, p->lang, f);
break;
+54 -22
View File
@@ -632,8 +632,10 @@ codeblock(Paragraph *p)
static int
iscodefence(Line *r, int size, line_type kind, mkd_flag_t *flags)
iscodefence(Line *r, Line *orig, mkd_flag_t *flags)
{
int kind = 0, size = 2, dle = 0;
if ( !is_flag_set(flags, MKD_FENCEDCODE) || is_flag_set(flags, MKD_STRICT) )
return 0;
@@ -644,6 +646,15 @@ iscodefence(Line *r, int size, line_type kind, mkd_flag_t *flags)
return 0;
if ( orig ) {
kind = orig->kind;
size = orig->count;
dle = orig->dle;
}
if ( (dle>>2) != (r->dle>>2) )
return 0;
if ( kind )
return (r->kind == kind) && (r->count >= size);
else
@@ -652,19 +663,20 @@ iscodefence(Line *r, int size, line_type kind, mkd_flag_t *flags)
static Line *
fencedcodechunk(Line *first, mkd_flag_t *flags)
fencedcodechunk(Line *first, mkd_flag_t *flags, int *yes)
{
Line *r, *q;
/* don't allow zero-length code fences
*/
if ( (first->next == 0) || iscodefence(first->next, first->count, first->kind, flags) ) {
if ( (first->next == 0) || iscodefence(first->next, first, flags) ) {
first->kind = chk_text;
first->is_fenced = 0;
if ( first->next) {
first->next->kind = chk_text;
first->next->is_fenced = 0;
}
*yes = 0;
return first->next;
}
@@ -672,7 +684,7 @@ fencedcodechunk(Line *first, mkd_flag_t *flags)
* past the closing fence
*/
for ( r = first->next; r; r = r->next ) {
if ( iscodefence(r, first->count, first->kind, flags) ) {
if ( iscodefence(r, first, flags) ) {
if (S(first->text) - first->count > 0) {
char *lang_attr = T(first->text) + first->count;
@@ -689,9 +701,13 @@ fencedcodechunk(Line *first, mkd_flag_t *flags)
S(first->text) = S(r->text) = 0;
r->is_fenced = 0;
return r->next;
*yes = 1;
q = r->next;
r->next = 0;
return q;
}
}
*yes = 0;
first->is_fenced = 0;
first->kind = chk_text;
return first;
@@ -742,9 +758,7 @@ textblock(Paragraph *p, int toplevel, mkd_flag_t *flags)
Line *t, *next;
for ( t = p->text; t ; t = next ) {
if ( iscodefence(t, t->count, 0, flags) )
next = fencedcodechunk(t, flags);
else if ( ((next = t->next) == 0) || endoftextblock(next, toplevel, flags) ) {
if ( ((next = t->next) == 0) || endoftextblock(next, toplevel, flags) ) {
p->align = centered(p->text, t);
t->next = 0;
return next;
@@ -1296,24 +1310,31 @@ compile_document(Line *ptr, MMIOT *f)
ptr = consume(addfootnote(ptr, f), &eaten);
previous_was_break = 1;
}
else if (iscodefence(ptr, 2, 0, &(f->flags))) {
Line *more = ptr;
else if ( previous_was_break && iscodefence(ptr, 0, &(f->flags)) ) {
/* scoop up _everything_ in a fenced code block, including html & footnotes
*/
int yes = 0;
Line *last = fencedcodechunk(ptr, &(f->flags), &yes );
ATTACH(source,more);
if ( yes ) {
int dummy;
{ Cache checkpoint = source;
while ( (more = more->next) && !iscodefence(more, ptr->count, ptr->kind, &(f->flags)) )
ATTACH(source,more);
/* dump out any previously cached text
*/
uncache(&source, &d, f);
if ( more )
ptr = more;
else {
source = checkpoint;
ptr = ptr->next;
p = Pp(&d, ptr, FENCEDCODE);
ptr = consume(last, &dummy);
previous_was_break = 1;
}
else {
/* unterminated fenced code; treat as regular markdown & cache until the next
* fenced code, htl, or style block
*/
ATTACH(source, ptr);
previous_was_break = 0;
ptr = ptr->next;
}
}
else {
@@ -1474,15 +1495,26 @@ compile(Line *ptr, int toplevel, MMIOT *f)
ptr = htmlblock(p, tag, &unclosed);
if ( ! unclosed ) {
p->typ = HTML;
continue;
}
}
if ( unclosed ) {
if ( iscodefence(p->text, 0, &(f->flags)) ) {
int yes = 0;
ptr = fencedcodechunk(p->text, &(f->flags), &yes);
if ( yes ) {
p->typ = FENCEDCODE;
continue;
}
}
ptr = textblock(p, toplevel, &(f->flags) );
/* tables are a special kind of paragraph */
if ( actually_a_table(f, p->text) )
p->typ = TABLE;
}
}
if ( (para||toplevel) && !p->align )
p->align = PARA;
+1 -1
View File
@@ -102,7 +102,7 @@ typedef struct paragraph {
char *label; /* toc label, uniqued */
char *ident; /* %id% tag for QUOTE */
char *lang; /* lang attribute for CODE */
enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
enum { WHITESPACE=0, CODE, FENCEDCODE, QUOTE, MARKUP,
HTML, STYLE, DL, UL, OL, AL, LISTITEM,
HDR, HR, TABLE, SOURCE } typ;
enum { IMPLICIT=0, PARA, CENTER} align;
+36 -51
View File
@@ -50,19 +50,17 @@ code!
still code!
~~~' \
'<p><pre><code>code!
'<pre><code>code!
still code!
</code></pre>
</p>'
</code></pre>'
try -ffencedcode 'fenced code block' \
'~~~
code!
~~~' \
'<p><pre><code>code!
</code></pre>
</p>'
'<pre><code>code!
</code></pre>'
try -ffencedcode 'fenced code block in list' \
'1. ~~~
@@ -78,9 +76,9 @@ try -ffencedcode 'fenced code block in blockquote' \
'>~~~
code
~~~' \
'<blockquote><p><pre><code>code
'<blockquote><pre><code>code
</code></pre>
</p></blockquote>'
</blockquote>'
try -ffencedcode 'unterminated fenced code block' \
'~~~
@@ -94,11 +92,10 @@ try -ffencedcode 'fenced code block with tildes' \
code with tildes
~~~
~~~~~' \
'<p><pre><code>~~~
'<pre><code>~~~
code with tildes
~~~
</code></pre>
</p>'
</code></pre>'
try -ffencedcode 'paragraph with trailing fenced block' \
'text text text
@@ -108,17 +105,16 @@ code code code?
~~~' \
'<p>text text text
text text text
<pre><code>code code code?
</code></pre>
</p>'
~~~
code code code?
~~~</p>'
try -ffencedcode 'fenced code blocks with backtick delimiters' \
'```
code
```' \
'<p><pre><code>code
</code></pre>
</p>'
'<pre><code>code
</code></pre>'
try -ffencedcode 'fenced code block with mismatched delimters' \
'```
@@ -132,57 +128,50 @@ try -ffencedcode 'fenced code block with lang attribute' \
'```lang
code
```' \
'<p><pre><code class="lang">code
</code></pre>
</p>'
'<pre><code class="lang">code
</code></pre>'
try -ffencedcode 'fenced code block with lang-name attribute' \
'```lang-name
code
```' \
'<p><pre><code class="lang-name">code
</code></pre>
</p>'
'<pre><code class="lang-name">code
</code></pre>'
try -ffencedcode 'fenced code block with lang_name attribute' \
'```lang_name
code
```' \
'<p><pre><code class="lang_name">code
</code></pre>
</p>'
'<pre><code class="lang_name">code
</code></pre>'
try -ffencedcode 'fenced code block with lang attribute and space' \
'``` lang
code
```' \
'<p><pre><code class="lang">code
</code></pre>
</p>'
'<pre><code class="lang">code
</code></pre>'
try -ffencedcode 'fenced code block with lang attribute and multiple spaces' \
'``` lang
code
```' \
'<p><pre><code class="lang">code
</code></pre>
</p>'
'<pre><code class="lang">code
</code></pre>'
try -ffencedcode 'fenced code block with lang-name attribute and space' \
'``` lang-name
code
```' \
'<p><pre><code class="lang-name">code
</code></pre>
</p>'
'<pre><code class="lang-name">code
</code></pre>'
try -ffencedcode 'fenced code block with lang_name attribute and space' \
'``` lang_name
code
```' \
'<p><pre><code class="lang_name">code
</code></pre>
</p>'
'<pre><code class="lang_name">code
</code></pre>'
try -ffencedcode 'fenced code block with blank line in the middle' \
'```
@@ -190,20 +179,18 @@ hello
sailor
```' \
'<p><pre><code>hello
'<pre><code>hello
sailor
</code></pre>
</p>'
</code></pre>'
try -ffencedcode 'fenced code block with html in the middle' \
'~~~~
<h1>hello, sailor</h1>
~~~~' \
'<p><pre><code>&lt;h1&gt;hello, sailor&lt;/h1&gt;
</code></pre>
</p>'
'<pre><code>&lt;h1&gt;hello, sailor&lt;/h1&gt;
</code></pre>'
try -ffencedcode 'fenced code block with trailing spaces in list item' \
'1. ~~~~
@@ -229,9 +216,8 @@ bar
~~~~' \
'<p>foo</p>
<p><pre><code>bar
</code></pre>
</p>'
<pre><code>bar
</code></pre>'
try -ffencedcode 'checkline misparse as fenced code' \
@@ -241,10 +227,9 @@ content
```
' \
'<p><a href="#code"><code>label</code></a>
<pre><code class="class">content
</code></pre>
</p>'
<code>class
content
</code></p>'
summary $0
exit $rc
+4 -15
View File
@@ -76,21 +76,10 @@ RESULT='<ul>
./rep '#header' ' ' 400 | try -T 'a header with a bunch of trailing spaces' -heredoc "$RESULT"
RESULT='<table>
<thead>
<tr>
<th>: Y:</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>'
RESULT='<p>: Y:|
<code>|
|
</code>|</p>'
cat << \EOF | try '-F 0x03000000' 'random input that looks like a table' -heredoc "$RESULT"
: Y:|