markdown-latex 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #!/usr/bin/env php
  2. <?php
  3. /**
  4. * @copyright Copyright (c) 2014 Carsten Brandt
  5. * @license https://github.com/cebe/markdown/blob/master/LICENSE
  6. * @link https://github.com/cebe/markdown#readme
  7. */
  8. $composerAutoload = [
  9. __DIR__ . '/../vendor/autoload.php', // standalone with "composer install" run
  10. __DIR__ . '/../../../autoload.php', // script is installed as a composer binary
  11. ];
  12. foreach ($composerAutoload as $autoload) {
  13. if (file_exists($autoload)) {
  14. require($autoload);
  15. break;
  16. }
  17. }
  18. // Send all errors to stderr
  19. ini_set('display_errors', 'stderr');
  20. $linkStyle = 'footnote';
  21. $flavor = 'cebe\\markdown\\latex\\Markdown';
  22. $flavors = [
  23. 'gfm' => ['cebe\\markdown\\latex\\GithubMarkdown', __DIR__ . '/../GithubMarkdown.php'],
  24. 'extra' => ['cebe\\markdown\\latex\\MarkdownExtra', __DIR__ . '/../MarkdownExtra.php'],
  25. ];
  26. $full = false;
  27. $src = [];
  28. foreach($argv as $k => $arg) {
  29. if ($k == 0) {
  30. continue;
  31. }
  32. if ($arg[0] == '-') {
  33. $arg = explode('=', $arg);
  34. switch($arg[0]) {
  35. case '--flavor':
  36. if (isset($arg[1])) {
  37. if (isset($flavors[$arg[1]])) {
  38. require($flavors[$arg[1]][1]);
  39. $flavor = $flavors[$arg[1]][0];
  40. } else {
  41. error("Unknown flavor: " . $arg[1], "usage");
  42. }
  43. } else {
  44. error("Incomplete argument --flavor!", "usage");
  45. }
  46. break;
  47. case '--link-style':
  48. if (isset($arg[1])) {
  49. if ($arg[1] === 'href' || $arg[1] === 'footnote') {
  50. $linkStyle = $arg[1];
  51. } else {
  52. error("Unknown link style: " . $arg[1], "usage");
  53. }
  54. } else {
  55. error("Incomplete argument --link-style!", "usage");
  56. }
  57. break;
  58. case '--full':
  59. $full = true;
  60. break;
  61. case '-h':
  62. case '--help':
  63. echo "PHP Markdown to LaTeX converter\n";
  64. echo "------------------------------\n\n";
  65. echo "by Carsten Brandt <mail@cebe.cc>\n\n";
  66. usage();
  67. break;
  68. default:
  69. error("Unknown argument " . $arg[0], "usage");
  70. }
  71. } else {
  72. $src[] = $arg;
  73. }
  74. }
  75. if (empty($src)) {
  76. $markdown = file_get_contents("php://stdin");
  77. } elseif (count($src) == 1) {
  78. $file = reset($src);
  79. if (!file_exists($file)) {
  80. error("File does not exist:" . $file);
  81. }
  82. $markdown = file_get_contents($file);
  83. } else {
  84. error("Converting multiple files is not yet supported.", "usage");
  85. }
  86. /** @var cebe\markdown\Parser $md */
  87. $md = new $flavor();
  88. $md->linkStyle = $linkStyle;
  89. $tex = $md->parse($markdown);
  90. if ($full) {
  91. echo <<<'TEX'
  92. \documentclass[a4paper, 12pt]{article}
  93. % english and utf8
  94. \usepackage[british]{babel}
  95. \usepackage[utf8]{inputenc}
  96. % url support
  97. \usepackage{url}
  98. % make links clickable
  99. \usepackage{hyperref}
  100. % code listings
  101. \usepackage{listings}
  102. \usepackage{color}
  103. \definecolor{codebg}{rgb}{0.9,0.9,0.9}
  104. \definecolor{mygreen}{rgb}{0,0.6,0}
  105. \definecolor{mygray}{rgb}{0.5,0.5,0.5}
  106. \definecolor{mymauve}{rgb}{0.58,0,0.82}
  107. \lstset{%
  108. backgroundcolor=\color{codebg}, % choose the background color; you must add \usepackage{color} or \usepackage{xcolor}
  109. basicstyle=\footnotesize, % the size of the fonts that are used for the code
  110. breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace
  111. breaklines=true, % sets automatic line breaking
  112. captionpos=b, % sets the caption-position to bottom
  113. commentstyle=\color{mygreen}, % comment style
  114. % deletekeywords={...}, % if you want to delete keywords from the given language
  115. escapeinside={\%*}{*)}, % if you want to add LaTeX within your code
  116. extendedchars=true, % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8
  117. % frame=single, % adds a frame around the code
  118. keepspaces=true, % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible)
  119. keywordstyle=\color{blue}, % keyword style
  120. % language=Octave, % the language of the code
  121. % morekeywords={*,...}, % if you want to add more keywords to the set
  122. numbers=left, % where to put the line-numbers; possible values are (none, left, right)
  123. numbersep=5pt, % how far the line-numbers are from the code
  124. numberstyle=\tiny\color{mygray}, % the style that is used for the line-numbers
  125. rulecolor=\color{black}, % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here))
  126. showspaces=false, % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
  127. showstringspaces=false, % underline spaces within strings only
  128. showtabs=false, % show tabs within strings adding particular underscores
  129. stepnumber=1, % the step between two line-numbers. If it's 1, each line will be numbered
  130. stringstyle=\color{mymauve}, % string literal style
  131. tabsize=2, % sets default tabsize to 2 spaces
  132. title=\lstname % show the filename of files included with \lstinputlisting; also try caption instead of title
  133. }
  134. \lstdefinelanguage{json}{
  135. morekeywords={},
  136. sensitive=false,
  137. morestring=[b]",
  138. }
  139. % include images
  140. \usepackage{graphicx}
  141. % support github markdown strikethrough
  142. % http://tex.stackexchange.com/questions/23711/strikethrough-text
  143. \usepackage{ulem}
  144. \begin{document}
  145. TEX;
  146. echo $tex;
  147. echo '\end{document}' . "\n";
  148. } else {
  149. echo $tex;
  150. }
  151. // functions
  152. /**
  153. * Display usage information
  154. */
  155. function usage() {
  156. global $argv;
  157. $cmd = $argv[0];
  158. echo <<<EOF
  159. Usage:
  160. $cmd [--flavor=<flavor>] [--full] [file.md]
  161. --flavor specifies the markdown flavor to use. If omitted the original markdown by John Gruber [1] will be used.
  162. Available flavors:
  163. gfm - Github flavored markdown [2]
  164. extra - Markdown Extra [3]
  165. --link-style specifies how links are being rendered:
  166. footnote (default) - render all links with a footnote, which contains the full URL of the link. This is good for printing the PDF.
  167. href - render all links with a hyperref, similar to HTML, the link target is not visible in this case.
  168. --full ouput a full TEX document with document class, begin and end document. If not given, only the parsed markdown will be output.
  169. --help shows this usage information.
  170. If no file is specified input will be read from STDIN.
  171. Examples:
  172. Render a file with original markdown:
  173. $cmd README.md > README.tex
  174. Render a file using gihtub flavored markdown:
  175. $cmd --flavor=gfm README.md > README.tex
  176. Convert the original markdown description to html using STDIN:
  177. curl http://daringfireball.net/projects/markdown/syntax.text | $cmd > md.tex
  178. [1] http://daringfireball.net/projects/markdown/syntax
  179. [2] https://help.github.com/articles/github-flavored-markdown
  180. [3] http://michelf.ca/projects/php-markdown/extra/
  181. EOF;
  182. exit(1);
  183. }
  184. /**
  185. * Send custom error message to stderr
  186. * @param $message string
  187. * @param $callback mixed called before script exit
  188. * @return void
  189. */
  190. function error($message, $callback = null) {
  191. $fe = fopen("php://stderr", "w");
  192. fwrite($fe, "Error: " . $message . "\n");
  193. if (is_callable($callback)) {
  194. call_user_func($callback);
  195. }
  196. exit(1);
  197. }