public
Description: An implementation of markdown in C, using a PEG grammar
Clone URL: git://github.com/jgm/peg-markdown.git
Search Repo:
Added -x/--extensions command-line option.
Also added Ellipses as a test case for an extension.
jgm (author)
Tue May 06 22:14:14 -0700 2008
commit  66c29ef982d99a375f98d7f741bb4f2619fd9d26
tree    2d09ff9c07c8539a8647f2aecaf52733ce7ae665
parent  8a59c5dee96c51a4099a63f84e70fbf347a38827
...
23
24
25
26
 
27
28
29
...
104
105
106
 
 
 
107
108
109
110
111
...
216
217
218
219
 
220
221
 
222
223
224
225
226
227
228
 
229
230
231
...
304
305
306
 
 
 
307
308
309
310
311
...
382
383
384
385
 
386
387
 
388
389
390
391
 
392
393
394
...
454
455
456
 
 
 
457
458
459
460
...
553
554
555
556
 
557
558
559
 
560
561
562
...
564
565
566
567
 
568
569
570
...
617
618
619
620
621
622
623
624
 
 
 
 
 
 
 
625
626
627
...
640
641
642
643
 
 
644
645
646
...
650
651
652
653
 
654
655
656
657
...
659
660
661
 
662
663
664
665
666
 
 
667
668
669
670
...
671
672
673
674
 
675
676
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
677
678
679
...
764
765
766
767
768
 
 
769
770
771
...
23
24
25
 
26
27
28
29
...
104
105
106
107
108
109
110
111
112
113
114
...
219
220
221
 
222
223
 
224
225
226
227
228
229
230
 
231
232
233
234
...
307
308
309
310
311
312
313
314
315
316
317
...
388
389
390
 
391
392
 
393
394
395
396
 
397
398
399
400
...
460
461
462
463
464
465
466
467
468
469
...
562
563
564
 
565
566
567
 
568
569
570
571
...
573
574
575
 
576
577
578
579
...
626
627
628
 
 
 
 
 
629
630
631
632
633
634
635
636
637
638
...
651
652
653
 
654
655
656
657
658
...
662
663
664
 
665
666
667
668
669
...
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
...
686
687
688
 
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
...
796
797
798
 
 
799
800
801
802
803
0
@@ -23,7 +23,7 @@
0
 #include "my_getopt-1.5/getopt.h"
0
 
0
 extern char *strdup(const char *string);
0
-static int extensions = 0;
0
+static int extensions;
0
 
0
 /**********************************************************************
0
 
0
@@ -104,6 +104,9 @@
0
     case STR:
0
         print_html_string(elt.contents.str, obfuscate);
0
         break;
0
+ case ELLIPSIS:
0
+ printf("…");
0
+ break;
0
     case CODE:
0
         printf("<code>");
0
         print_html_string(elt.contents.str, obfuscate);
0
0
0
@@ -216,16 +219,16 @@
0
          * is no blank line. We split the string by \001 and parse
0
          * each chunk separately. */
0
         contents = strtok(elt.contents.str, "\001");
0
- print_html_element(markdown(extensions, contents), obfuscate);
0
+ print_html_element(markdown(contents, extensions), obfuscate);
0
         while ((contents = strtok(NULL, "\001")))
0
- print_html_element(markdown(extensions, contents), obfuscate);
0
+ print_html_element(markdown(contents, extensions), obfuscate);
0
         printf("</li>");
0
         padded = 0;
0
         break;
0
     case BLOCKQUOTE:
0
         pad(2);
0
         printf("<blockquote>");
0
- print_html_element(markdown(extensions, elt.contents.str), obfuscate);
0
+ print_html_element(markdown(elt.contents.str, extensions), obfuscate);
0
         printf("</blockquote>");
0
         padded = 0;
0
         break;
0
@@ -304,6 +307,9 @@
0
     case STR:
0
         print_latex_string(elt.contents.str);
0
         break;
0
+ case ELLIPSIS:
0
+ printf("\\ldots{}");
0
+ break;
0
     case CODE:
0
         printf("\\texttt{");
0
         print_latex_string(elt.contents.str);
0
0
0
@@ -382,13 +388,13 @@
0
          * is no blank line. We split the string by \001 and parse
0
          * each chunk separately. */
0
         contents = strtok(elt.contents.str, "\001");
0
- print_latex_element(markdown(extensions, contents));
0
+ print_latex_element(markdown(contents, extensions));
0
         while ((contents = strtok(NULL, "\001")))
0
- print_latex_element(markdown(extensions, contents));
0
+ print_latex_element(markdown(contents, extensions));
0
         break;
0
     case BLOCKQUOTE:
0
         printf("\\begin{quote}");
0
- print_latex_element(markdown(extensions, elt.contents.str));
0
+ print_latex_element(markdown(elt.contents.str, extensions));
0
         printf("\\end{quote}\n\n");
0
         break;
0
     case REFERENCE:
0
@@ -454,6 +460,9 @@
0
         print_groff_string(elt.contents.str);
0
         padded = 0;
0
         break;
0
+ case ELLIPSIS:
0
+ printf("...");
0
+ break;
0
     case CODE:
0
         printf("\\fC");
0
         print_groff_string(elt.contents.str);
0
0
@@ -553,10 +562,10 @@
0
          * each chunk separately. */
0
         contents = strtok(elt.contents.str, "\001");
0
         padded = 2;
0
- print_groff_mm_element(markdown(extensions, contents), 1);
0
+ print_groff_mm_element(markdown(contents, extensions), 1);
0
         while ((contents = strtok(NULL, "\001"))) {
0
             padded = 2;
0
- print_groff_mm_element(markdown(extensions, contents), 1);
0
+ print_groff_mm_element(markdown(contents, extensions), 1);
0
         }
0
         in_list_item = false;
0
         break;
0
@@ -564,7 +573,7 @@
0
         pad(1);
0
         printf(".DS I\n");
0
         padded = 2;
0
- print_groff_mm_element(markdown(extensions, elt.contents.str), 1);
0
+ print_groff_mm_element(markdown(elt.contents.str, extensions), 1);
0
         pad(1);
0
         printf(".DE");
0
         padded = 0;
0
@@ -617,11 +626,13 @@
0
 {
0
   printf("Usage: %s [options] [FILE]...\n"
0
          "Options:\n"
0
- "-t FORMAT or --to FORMAT convert to FORMAT (default is html)\n"
0
- " FORMAT = html|latex|groff-mm\n"
0
- "-o FILE or --output FILE send output to FILE (default is stdout)\n"
0
- "-V or --version print program version and exit\n"
0
- "-h or --help show this message and exit\n",
0
+ "-t FORMAT or --to FORMAT convert to FORMAT (default is html)\n"
0
+ " FORMAT = html|latex|groff-mm\n"
0
+ "-o FILE or --output FILE send output to FILE (default is stdout)\n"
0
+ "-x[EXTS] or --extensions [EXTS] use syntax extensions (all if EXTS not specified)\n"
0
+ " EXTS = smart, ...\n"
0
+ "-V or --version print program version and exit\n"
0
+ "-h or --help show this message and exit\n",
0
          progname);
0
 }
0
 
0
@@ -640,7 +651,8 @@
0
     /* the output filename is initially 0 (a.k.a. stdout) */
0
     char *outfilename = 0;
0
     char *format = 0;
0
-
0
+ char *exts = 0;
0
+
0
     /* Output formats. */
0
     enum formats { HTML_FORMAT,
0
                    LATEX_FORMAT,
0
@@ -650,7 +662,7 @@
0
  
0
     int output_format = HTML_FORMAT;
0
 
0
- char *shortopts = "Vho:t:";
0
+ char *shortopts = "Vhx::o:t:";
0
     /* long options list */
0
     struct option longopts[] =
0
     {
0
0
@@ -659,11 +671,14 @@
0
       { "help", no_argument, 0, 'h' }, /* 1 */
0
       { "output", required_argument, 0, 'o' }, /* 2 */
0
       { "to", required_argument, 0, 't' }, /* 3 */
0
+ { "extensions", optional_argument, 0, 'x' }, /* 3 */
0
       /* end-of-list marker */
0
       { 0, 0, 0, 0 }
0
     };
0
     /* long option list index */
0
     int longind = 0;
0
+
0
+ extensions = 0;
0
 
0
     /* parse all options from the command line */
0
     while ((opt = getopt_long_only(argc, argv, shortopts, longopts, &longind)) != -1)
0
0
@@ -671,9 +686,26 @@
0
         case 'V': /* -version */
0
             version(progname);
0
             return 0;
0
- case 'h': /* -version */
0
+ case 'h': /* -help */
0
             help(progname);
0
             return 0;
0
+ case 'x': /* -extended */
0
+ exts = optarg;
0
+ if (exts == NULL) {
0
+ extensions = 0xFFFFFF; /* turn on all extensions */
0
+ break;
0
+ }
0
+ exts = strtok(optarg, ",");
0
+ while (exts != NULL) {
0
+ if (strcmp(exts, "smart") == 0)
0
+ extensions = extensions | EXT_SMART;
0
+ else {
0
+ fprintf(stderr, "%s: Unknown extension '%s'\n", progname, exts);
0
+ exit(EXIT_FAILURE);
0
+ }
0
+ exts = strtok(NULL, ",");
0
+ }
0
+ break;
0
         case 't': /* -to */
0
             format = optarg;
0
             if (strcmp(format, "html") == 0)
0
@@ -764,8 +796,8 @@
0
     }
0
 
0
     strcat(inputbuf, strdup("\n\n")); /* add newlines to end to match Markdown.pl behavior */
0
-
0
- element parsed_input = markdown(extensions, inputbuf);
0
+
0
+ element parsed_input = markdown(inputbuf, extensions);
0
 
0
     switch (output_format) {
0
     case HTML_FORMAT:
...
28
29
30
 
31
32
33
34
...
65
66
67
68
69
 
70
71
72
 
...
28
29
30
31
32
33
34
35
...
66
67
68
 
 
69
70
71
 
72
0
@@ -28,6 +28,7 @@
0
 enum keys { LIST, /* A generic list of values. For ordered and bullet lists, see below. */
0
             SPACE,
0
             LINEBREAK,
0
+ ELLIPSIS,
0
             STR,
0
             LINK,
0
             IMAGE,
0
0
@@ -65,9 +66,8 @@
0
 typedef struct ElementListItem item;
0
 
0
 enum markdown_extensions {
0
- EXT_SMART_QUOTES = 1,
0
- EXT_SMART_DASHES = 2
0
+ EXT_SMART = 1
0
 };
0
 
0
-element markdown(int extensions, char *string);
0
+element markdown(char *string, int extensions);
...
88
89
90
 
91
92
93
...
534
535
536
 
537
538
539
...
715
716
717
718
 
719
720
721
722
723
...
743
744
745
 
 
 
 
 
 
 
 
746
747
748
 
749
750
 
 
 
751
752
753
...
88
89
90
91
92
93
94
...
535
536
537
538
539
540
541
...
717
718
719
 
720
721
722
723
724
725
...
745
746
747
748
749
750
751
752
753
754
755
756
757
 
758
759
760
761
762
763
764
765
766
0
@@ -88,6 +88,7 @@
0
 static item *references; /* List of link references found. */
0
 static int output_format;
0
 static element parse_result; /* Results of parse. */
0
+static int syntax_extensions; /* Syntax extensions selected. */
0
 
0
 /**********************************************************************
0
 
0
@@ -534,6 +535,7 @@
0
         | RawHtml
0
         | Entity
0
         | EscapedChar
0
+ | Smart
0
         | Symbol
0
 
0
 Space = Spacechar+
0
@@ -715,7 +717,7 @@
0
 Newline = '\n' | '\r' '\n'?
0
 Sp = Spacechar*
0
 Spnl = Sp (Newline Sp)?
0
-SpecialChar = '*' | '_' | '`' | '&' | '[' | ']' | '<' | '!' | '\\'
0
+SpecialChar = '*' | '_' | '`' | '&' | '[' | ']' | '<' | '!' | '\\' | ExtendedSpecialChar
0
 NormalChar = !( SpecialChar | Spacechar | Newline ) .
0
 Alphanumeric = [A-Za-z0-9]
0
 
0
0
0
@@ -743,11 +745,22 @@
0
 SkipBlock = ( !BlankLine Line )+ BlankLine*
0
           | BlankLine+
0
 
0
+# Syntax extensions
0
+
0
+ExtendedSpecialChar = (&{ (syntax_extensions & EXT_SMART) } '.')
0
+
0
+Smart = &{ (syntax_extensions & EXT_SMART) } Ellipses
0
+
0
+Ellipses = ("..." | ". . .") { $$.key = ELLIPSIS; }
0
+
0
 %%
0
 
0
-element markdown(int extensions, char *string) {
0
+element markdown(char *string, int extensions) {
0
 
0
     char *oldcharbuf;
0
+
0
+ syntax_extensions = extensions;
0
+
0
     oldcharbuf = charbuf;
0
     charbuf = string;
0
     yyparsefrom(yy_References); /* first pass, just to collect references */

Comments

    No one has commented yet.