pgm_options.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* markdown: a C implementation of John Gruber's Markdown markup language.
  2. *
  3. * Copyright (C) 2007-2011 David L Parsons.
  4. * The redistribution terms are provided in the COPYRIGHT file that must
  5. * be distributed with this source code.
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <limits.h>
  10. #include <unistd.h>
  11. #include <mkdio.h>
  12. #include <errno.h>
  13. #include <string.h>
  14. #include <stdarg.h>
  15. #include "config.h"
  16. #include "amalloc.h"
  17. #if HAVE_LIBGEN_H
  18. #include <libgen.h>
  19. #endif
  20. static struct _opt {
  21. char *name;
  22. char *desc;
  23. int off;
  24. int skip; /* this opt is a synonym */
  25. int sayenable;
  26. mkd_flag_t flag;
  27. } opts[] = {
  28. { "tabstop", "default (4-space) tabstops", 0, 0, 1, MKD_TABSTOP },
  29. { "image", "images", 1, 0, 1, MKD_NOIMAGE },
  30. { "links", "links", 1, 0, 1, MKD_NOLINKS },
  31. { "relax", "emphasis inside words", 1, 1, 1, MKD_STRICT },
  32. { "strict", "emphasis inside words", 0, 0, 1, MKD_STRICT },
  33. { "tables", "tables", 1, 0, 1, MKD_NOTABLES },
  34. { "header", "pandoc-style headers", 1, 0, 1, MKD_NOHEADER },
  35. { "html", "raw html", 1, 0, 1, MKD_NOHTML },
  36. { "ext", "extended protocols", 1, 0, 1, MKD_NO_EXT },
  37. { "cdata", "generate cdata", 0, 0, 0, MKD_CDATA },
  38. { "smarty", "smartypants", 1, 0, 1, MKD_NOPANTS },
  39. { "pants", "smartypants", 1, 1, 1, MKD_NOPANTS },
  40. { "toc", "tables of contents", 0, 0, 1, MKD_TOC },
  41. { "autolink", "autolinking", 0, 0, 1, MKD_AUTOLINK },
  42. { "safelink", "safe links", 0, 0, 1, MKD_SAFELINK },
  43. { "strikethrough", "strikethrough", 1, 0, 1, MKD_NOSTRIKETHROUGH },
  44. { "del", "strikethrough", 1, 1, 1, MKD_NOSTRIKETHROUGH },
  45. { "superscript", "superscript", 1, 0, 1, MKD_NOSUPERSCRIPT },
  46. { "emphasis", "emphasis inside words", 0, 0, 1, MKD_NORELAXED },
  47. { "divquote", ">%class% blockquotes", 1, 0, 1, MKD_NODIVQUOTE },
  48. { "alphalist", "alpha lists", 1, 0, 1, MKD_NOALPHALIST },
  49. { "definitionlist","definition lists", 1, 0, 1, MKD_NODLIST },
  50. { "1.0", "markdown 1.0 compatibility", 0, 0, 1, MKD_1_COMPAT },
  51. { "footnotes", "markdown extra footnotes", 0, 0, 1, MKD_EXTRA_FOOTNOTE },
  52. { "footnote", "markdown extra footnotes", 0, 1, 1, MKD_EXTRA_FOOTNOTE },
  53. { "style", "extract style blocks", 1, 0, 1, MKD_NOSTYLE },
  54. { "dldiscount", "discount-style definition lists", 1, 0, 1, MKD_NODLDISCOUNT },
  55. { "dlextra", "extra-style definition lists", 0, 0, 1, MKD_DLEXTRA },
  56. { "fencedcode", "fenced code blocks", 0, 0, 1, MKD_FENCEDCODE },
  57. { "idanchor", "id= anchors in TOC", 0, 0, 1, MKD_IDANCHOR },
  58. { "githubtags", "permit - and _ in element names", 0, 0, 0, MKD_GITHUBTAGS },
  59. { "urlencodedanchor", "urlencode special chars in TOC links", 0, 0, 0, MKD_URLENCODEDANCHOR },
  60. } ;
  61. #define NR(x) (sizeof x / sizeof x[0])
  62. typedef int (*stfu)(const void *, const void *);
  63. int
  64. sort_by_name(struct _opt *a, struct _opt *b)
  65. {
  66. return strcmp(a->name,b->name);
  67. }
  68. int
  69. sort_by_flag(struct _opt *a, struct _opt *b)
  70. {
  71. return a->flag - b->flag;
  72. }
  73. void
  74. show_flags(int byname)
  75. {
  76. int i;
  77. if ( byname ) {
  78. qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name);
  79. for (i=0; i < NR(opts); i++)
  80. if ( ! opts[i].skip )
  81. fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
  82. }
  83. else {
  84. qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag);
  85. for (i=0; i < NR(opts); i++)
  86. if ( ! opts[i].skip ) {
  87. fprintf(stderr, "%08lx : ", (long)opts[i].flag);
  88. if ( opts[i].sayenable )
  89. fprintf(stderr, opts[i].off ? "disable " : "enable ");
  90. fprintf(stderr, "%s\n", opts[i].desc);
  91. }
  92. }
  93. }
  94. int
  95. set_flag(mkd_flag_t *flags, char *optionstring)
  96. {
  97. int i;
  98. int enable;
  99. char *arg;
  100. for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) {
  101. if ( *arg == '+' || *arg == '-' )
  102. enable = (*arg++ == '+') ? 1 : 0;
  103. else if ( strncasecmp(arg, "no", 2) == 0 ) {
  104. arg += 2;
  105. enable = 0;
  106. }
  107. else
  108. enable = 1;
  109. for ( i=0; i < NR(opts); i++ )
  110. if ( strcasecmp(arg, opts[i].name) == 0 )
  111. break;
  112. if ( i < NR(opts) ) {
  113. if ( opts[i].off )
  114. enable = !enable;
  115. if ( enable )
  116. *flags |= opts[i].flag;
  117. else
  118. *flags &= ~opts[i].flag;
  119. }
  120. else
  121. return 0;
  122. }
  123. return 1;
  124. }