Fossil

Check-in [c7600da4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further work on the fenced code blocks of markdown. Allow blank lines in the middle of a fenced code block. And also allow ~ character (three or more) to serve as the delimiter for fenced code blocks.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c7600da4893b5ea2875bc4bb8617114e498e833c28a07c41e3233c0dddf3def8
User & Date: drh 2019-08-09 15:57:25
Context
2019-08-09
16:37
Fix up the markdown rules to include recent enhancements to fenced code blocks. On "Markup Style:" entry boxes, provide a hyperlink for easy access to the rule sheets. check-in: 18a84ed8 user: drh tags: trunk
15:57
Further work on the fenced code blocks of markdown. Allow blank lines in the middle of a fenced code block. And also allow ~ character (three or more) to serve as the delimiter for fenced code blocks. check-in: c7600da4 user: drh tags: trunk
12:15
Added an aside in fossil-v-git about Git's minority use of high-level scripting languages aside from its dominant one, POSIX shell, with a comparison to Fossil's own use of high-level scripting. check-in: 1296ee46 user: wyoung tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/markdown.c.

723
724
725
726
727
728
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
....
1194
1195
1196
1197
1198
1199
1200












1201
1202
1203
1204
1205
1206
1207
....
2011
2012
2013
2014
2015
2016
2017


2018
2019
2020
2021
2022
2023
2024
  struct Blob *ob,
  struct render *rndr,
  char *data,
  size_t offset,
  size_t size
){
  size_t end, nb = 0, i, f_begin, f_end;


  /* counting the number of backticks in the delimiter */
  while( nb<size && data[nb]=='`' ){ nb++; }

  /* finding the next delimiter */
  i = 0;
  for(end=nb; end<size && i<nb; end++){
    if( data[end]=='`' ) i++; else i = 0;
  }
  if( i<nb && end>=size ) return 0; /* no matching delimiter */

  /* trimming outside whitespaces */
  f_begin = nb;
  while( f_begin<end && (data[f_begin]==' ' || data[f_begin]=='\t') ){
    f_begin++;
................................................................................
static size_t prefix_code(char *data, size_t size){
  if( size>0 && data[0]=='\t' ) return 1;
  if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){
    return 4;
  }
  return 0;
}













/* prefix_oli -- returns ordered list item prefix */
static size_t prefix_oli(char *data, size_t size){
  size_t i = 0;
  if( i<size && data[i]==' ') i++;
  if( i<size && data[i]==' ') i++;
  if( i<size && data[i]==' ') i++;
................................................................................
      beg += parse_blockcode(ob, rndr, txt_data, end);
    }else if( prefix_uli(txt_data, end) ){
      beg += parse_list(ob, rndr, txt_data, end, 0);
    }else if( prefix_oli(txt_data, end) ){
      beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED);
    }else if( has_table && is_tableline(txt_data, end) ){
      beg += parse_table(ob, rndr, txt_data, end);


    }else{
      beg += parse_paragraph(ob, rndr, txt_data, end);
    }
  }
}









>


|




|







 







>
>
>
>
>
>
>
>
>
>
>
>







 







>
>







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
....
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
....
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
  struct Blob *ob,
  struct render *rndr,
  char *data,
  size_t offset,
  size_t size
){
  size_t end, nb = 0, i, f_begin, f_end;
  char delim = data[0];

  /* counting the number of backticks in the delimiter */
  while( nb<size && data[nb]==delim ){ nb++; }

  /* finding the next delimiter */
  i = 0;
  for(end=nb; end<size && i<nb; end++){
    if( data[end]==delim ) i++; else i = 0;
  }
  if( i<nb && end>=size ) return 0; /* no matching delimiter */

  /* trimming outside whitespaces */
  f_begin = nb;
  while( f_begin<end && (data[f_begin]==' ' || data[f_begin]=='\t') ){
    f_begin++;
................................................................................
static size_t prefix_code(char *data, size_t size){
  if( size>0 && data[0]=='\t' ) return 1;
  if( size>3 && data[0]==' ' && data[1]==' ' && data[2]==' ' && data[3]==' ' ){
    return 4;
  }
  return 0;
}

/* Return the number of characters in the delimiter of a fenced code
** block. */
static size_t prefix_fencedcode(char *data, size_t size){
  char c = data[0];
  int nb;
  if( c!='`' && c!='~' ) return 0;
  for(nb=1; nb<size-3 && data[nb]==c; nb++){}
  if( nb<3 ) return 0;
  if( nb>=size-nb ) return 0;
  return nb;
}

/* prefix_oli -- returns ordered list item prefix */
static size_t prefix_oli(char *data, size_t size){
  size_t i = 0;
  if( i<size && data[i]==' ') i++;
  if( i<size && data[i]==' ') i++;
  if( i<size && data[i]==' ') i++;
................................................................................
      beg += parse_blockcode(ob, rndr, txt_data, end);
    }else if( prefix_uli(txt_data, end) ){
      beg += parse_list(ob, rndr, txt_data, end, 0);
    }else if( prefix_oli(txt_data, end) ){
      beg += parse_list(ob, rndr, txt_data, end, MKD_LIST_ORDERED);
    }else if( has_table && is_tableline(txt_data, end) ){
      beg += parse_table(ob, rndr, txt_data, end);
    }else if( prefix_fencedcode(txt_data, end) ){
      beg += char_codespan(ob, rndr, txt_data, 0, end);
    }else{
      beg += parse_paragraph(ob, rndr, txt_data, end);
    }
  }
}


Changes to src/markdown_html.c.

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  }else{
    /* Three or more graves: a fenced code block */
    int n = blob_size(text);
    const char *z = blob_buffer(text);
    int i;
    for(i=0; i<n && z[i]!='\n'; i++){}
    if( i>=n ){
      blob_appendf(ob, "<pre><code>%.*s</code></pre>", n, z);
    }else{
      int k, j;
      i++;
      for(k=0; k<i && fossil_isspace(z[k]); k++){}
      if( k==i ){
        blob_appendf(ob, "<pre><code>%.*s</code></pre>", n-i, z+i);
      }else{
        for(j=k+1; j<i && !fossil_isspace(z[j]); j++){}
        blob_appendf(ob, "<pre><code class='language-%#h'>%.*s</code></pre>",
                          j-k, z+k, n-i, z+i);
      }
    }
  }
  return 1;
}








|





|


|







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  }else{
    /* Three or more graves: a fenced code block */
    int n = blob_size(text);
    const char *z = blob_buffer(text);
    int i;
    for(i=0; i<n && z[i]!='\n'; i++){}
    if( i>=n ){
      blob_appendf(ob, "<pre><code>%#h</code></pre>", n, z);
    }else{
      int k, j;
      i++;
      for(k=0; k<i && fossil_isspace(z[k]); k++){}
      if( k==i ){
        blob_appendf(ob, "<pre><code>%#h</code></pre>", n-i, z+i);
      }else{
        for(j=k+1; j<i && !fossil_isspace(z[j]); j++){}
        blob_appendf(ob, "<pre><code class='language-%#h'>%#h</code></pre>",
                          j-k, z+k, n-i, z+i);
      }
    }
  }
  return 1;
}