Fossil

Check-in [1f525713]
Login

Check-in [1f525713]

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

Overview
Comment:Add --lint-footnotes option to the test-markdown-render command. If this flag is given and footnotes in the input have issues, then print to stderr the counters of "misrefs", "strays" and "split-defs" and exit with error. This should partially address a concern raised at the forum.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | markdown-footnotes
Files: files | file ages | folders
SHA3-256: 1f525713ff85cf5fc1ef0c61521c298bbb330eef69e073f01fc194c27ad2067a
User & Date: george 2022-02-18 01:33:29
References
2022-04-20
11:39 Wiki page "branch/markdown-footnotes" ... (artifact: db11e160 user: drh)
Context
2022-02-19
01:00
Handle some corner cases more thoroughly: dismiss empty footnotes, passthrough (more carefully) user-provided classlist if the token is not followed by a blank character or if a footnote's text consists just of such token and blank characters. Also simplify a little bit a few places inside of is_footnote() function. ... (check-in: fe315780 user: george tags: markdown-footnotes)
2022-02-18
01:33
Add --lint-footnotes option to the test-markdown-render command. If this flag is given and footnotes in the input have issues, then print to stderr the counters of "misrefs", "strays" and "split-defs" and exit with error. This should partially address a concern raised at the forum. ... (check-in: 1f525713 user: george tags: markdown-footnotes)
2022-02-17
22:09
If a footnote's text starts with a token of the special form then use this token to derive a set of CSS classes that are added to that footnote and its references. This enables users to style elements of a particular footnote provided that the administrator provisioned and documented some special CSS classes in a custum skin. Default skin does not provide any of such special classes which makes this feature an "opt-in". ... (check-in: 92516ced user: george tags: markdown-footnotes)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

322
323
324
325
326
327
328

329
330
331
332
333
334
335
      cson_value *v;
      cson_object *o;
    } reqPayload;              /* request payload object (if any) */
    cson_array *warnings;      /* response warnings */
    int timerId;               /* fetched from fossil_timer_start() */
  } json;
#endif /* FOSSIL_ENABLE_JSON */

  int diffCnt[3];         /* Counts for DIFF_NUMSTAT: files, ins, del */
};

/*
** Macro for debugging:
*/
#define CGIDEBUG(X)  if( g.fDebug ) cgi_debug X







>







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
      cson_value *v;
      cson_object *o;
    } reqPayload;              /* request payload object (if any) */
    cson_array *warnings;      /* response warnings */
    int timerId;               /* fetched from fossil_timer_start() */
  } json;
#endif /* FOSSIL_ENABLE_JSON */
  int ftntsIssues[3];     /* Counts for misref, strayed, joined */
  int diffCnt[3];         /* Counts for DIFF_NUMSTAT: files, ins, del */
};

/*
** Macro for debugging:
*/
#define CGIDEBUG(X)  if( g.fDebug ) cgi_debug X

Changes to src/markdown.c.

2711
2712
2713
2714
2715
2716
2717

2718
2719
2720
2721
2722
2723
2724
          blob_append(&filtered, (char*)(fn+i), sizeof(struct footnote));
        }
      }
      blob_reset( allNotes );
      rndr.notes.all = filtered;
      rndr.notes.nLbled = n;
      assert( COUNT_FOOTNOTES(allNotes) == rndr.notes.nLbled );

    }
  }
  fn = CAST_AS_FOOTNOTES( allNotes );
  for(i=0; i<rndr.notes.nLbled; i++){
    fn[i].index = i;
  }
  assert( rndr.notes.nMarks==0 );







>







2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
          blob_append(&filtered, (char*)(fn+i), sizeof(struct footnote));
        }
      }
      blob_reset( allNotes );
      rndr.notes.all = filtered;
      rndr.notes.nLbled = n;
      assert( COUNT_FOOTNOTES(allNotes) == rndr.notes.nLbled );
      g.ftntsIssues[2] += nDups;
    }
  }
  fn = CAST_AS_FOOTNOTES( allNotes );
  for(i=0; i<rndr.notes.nLbled; i++){
    fn[i].index = i;
  }
  assert( rndr.notes.nMarks==0 );
2778
2779
2780
2781
2782
2783
2784

2785
2786
2787
2788
2789
2790
2791
2792

2793
2794
2795
2796
2797
2798
2799
                                  x->nUsed, rndr.make.opaque);
          j = i;
        }
      }
      if( rndr.notes.misref.nUsed ){
        rndr.make.footnote_item(all_items, 0, -1,
                    rndr.notes.misref.nUsed, rndr.make.opaque);

      }
      while( ++j < COUNT_FOOTNOTES(notes) ){
        const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
        assert( !x->nUsed );
        assert( !x->bRndred );
        assert( (&x->id) + 1 == &x->text ); /* see html_footnote_item() */
        assert( (&x->upc)- 1 == &x->text );
        rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);

      }
      rndr.make.footnotes(ob, all_items, rndr.make.opaque);
      release_work_buffer(&rndr, all_items);
    }
    release_work_buffer(&rndr, notes);
  }
  if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);







>








>







2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
                                  x->nUsed, rndr.make.opaque);
          j = i;
        }
      }
      if( rndr.notes.misref.nUsed ){
        rndr.make.footnote_item(all_items, 0, -1,
                    rndr.notes.misref.nUsed, rndr.make.opaque);
        g.ftntsIssues[0] += rndr.notes.misref.nUsed;
      }
      while( ++j < COUNT_FOOTNOTES(notes) ){
        const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
        assert( !x->nUsed );
        assert( !x->bRndred );
        assert( (&x->id) + 1 == &x->text ); /* see html_footnote_item() */
        assert( (&x->upc)- 1 == &x->text );
        rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);
        g.ftntsIssues[1]++;
      }
      rndr.make.footnotes(ob, all_items, rndr.make.opaque);
      release_work_buffer(&rndr, all_items);
    }
    release_work_buffer(&rndr, notes);
  }
  if( rndr.make.epilog ) rndr.make.epilog(ob, rndr.make.opaque);

Changes to src/wikiformat.c.

1891
1892
1893
1894
1895
1896
1897
1898

1899
1900
1901
1902
1903
1904
1905

1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918









1919
1920
1921
1922
1923
1924
1925
** COMMAND: test-markdown-render
**
** Usage: %fossil test-markdown-render FILE ...
**
** Render markdown in FILE as HTML on stdout.
** Options:
**
**    --safe           Restrict the output to use only "safe" HTML

*/
void test_markdown_render(void){
  Blob in, out;
  int i;
  int bSafe = 0;
  db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
  bSafe = find_option("safe",0,0)!=0;

  verify_all_options();
  for(i=2; i<g.argc; i++){
    blob_zero(&out);
    blob_read_from_file(&in, g.argv[i], ExtFILE);
    if( g.argc>3 ){
      fossil_print("<!------ %h ------->\n", g.argv[i]);
    }
    markdown_to_html(&in, 0, &out);
    safe_html_context( bSafe ? DOCSRC_UNTRUSTED : DOCSRC_TRUSTED );
    safe_html(&out);
    blob_write_to_file(&out, "-");
    blob_reset(&in);
    blob_reset(&out);









  }
}

/*
** Search for a <title>...</title> at the beginning of a wiki page.
** Return true (nonzero) if a title is found.  Return zero if there is
** not title.







|
>




|


>













>
>
>
>
>
>
>
>
>







1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
** COMMAND: test-markdown-render
**
** Usage: %fossil test-markdown-render FILE ...
**
** Render markdown in FILE as HTML on stdout.
** Options:
**
**    --safe            Restrict the output to use only "safe" HTML
**    --lint-footnotes  Print stats for footnotes-related issues
*/
void test_markdown_render(void){
  Blob in, out;
  int i;
  int bSafe = 0, bFnLint = 0;
  db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
  bSafe = find_option("safe",0,0)!=0;
  bFnLint = find_option("lint-footnotes",0,0)!=0;
  verify_all_options();
  for(i=2; i<g.argc; i++){
    blob_zero(&out);
    blob_read_from_file(&in, g.argv[i], ExtFILE);
    if( g.argc>3 ){
      fossil_print("<!------ %h ------->\n", g.argv[i]);
    }
    markdown_to_html(&in, 0, &out);
    safe_html_context( bSafe ? DOCSRC_UNTRUSTED : DOCSRC_TRUSTED );
    safe_html(&out);
    blob_write_to_file(&out, "-");
    blob_reset(&in);
    blob_reset(&out);
  }
  if( bFnLint && (g.ftntsIssues[0] || g.ftntsIssues[1] || g.ftntsIssues[2])){
    fossil_fatal("There were issues with footnotes:\n"
                  " %8i misreference%s\n"
                  " %8i unreferenced\n"
                  " %8i splitted",
                  g.ftntsIssues[0], g.ftntsIssues[0]==1?"":"s",
                  g.ftntsIssues[1],
                  g.ftntsIssues[2]);
  }
}

/*
** Search for a <title>...</title> at the beginning of a wiki page.
** Return true (nonzero) if a title is found.  Return zero if there is
** not title.