132html 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #! /usr/bin/perl -w
  2. # Script to turn PCRE2 man pages into HTML
  3. # Subroutine to handle font changes and other escapes
  4. sub do_line {
  5. my($s) = $_[0];
  6. $s =~ s/</&#60;/g; # Deal with < and >
  7. $s =~ s/>/&#62;/g;
  8. $s =~ s"\\fI(.*?)\\f[RP]"<i>$1</i>"g;
  9. $s =~ s"\\fB(.*?)\\f[RP]"<b>$1</b>"g;
  10. $s =~ s"\\e"\\"g;
  11. $s =~ s/(?<=Copyright )\(c\)/&copy;/g;
  12. $s;
  13. }
  14. # Subroutine to ensure not in a paragraph
  15. sub end_para {
  16. if ($inpara)
  17. {
  18. print TEMP "</PRE>\n" if ($inpre);
  19. print TEMP "</P>\n";
  20. }
  21. $inpara = $inpre = 0;
  22. $wrotetext = 0;
  23. }
  24. # Subroutine to start a new paragraph
  25. sub new_para {
  26. &end_para();
  27. print TEMP "<P>\n";
  28. $inpara = 1;
  29. }
  30. # Main program
  31. $innf = 0;
  32. $inpara = 0;
  33. $inpre = 0;
  34. $wrotetext = 0;
  35. $toc = 0;
  36. $ref = 1;
  37. while ($#ARGV >= 0 && $ARGV[0] =~ /^-/)
  38. {
  39. $toc = 1 if $ARGV[0] eq "-toc";
  40. shift;
  41. }
  42. # Initial output to STDOUT
  43. print <<End ;
  44. <html>
  45. <head>
  46. <title>$ARGV[0] specification</title>
  47. </head>
  48. <body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
  49. <h1>$ARGV[0] man page</h1>
  50. <p>
  51. Return to the <a href="index.html">PCRE2 index page</a>.
  52. </p>
  53. <p>
  54. This page is part of the PCRE2 HTML documentation. It was generated
  55. automatically from the original man page. If there is any nonsense in it,
  56. please consult the man page, in case the conversion went wrong.
  57. <br>
  58. End
  59. print "<ul>\n" if ($toc);
  60. open(TEMP, ">/tmp/$$") || die "Can't open /tmp/$$ for output\n";
  61. while (<STDIN>)
  62. {
  63. # Handle lines beginning with a dot
  64. if (/^\./)
  65. {
  66. # Some of the PCRE2 man pages used to contain instances of .br. However,
  67. # they should have all been removed because they cause trouble in some
  68. # (other) automated systems that translate man pages to HTML. Complain if
  69. # we find .br or .in (another macro that is deprecated).
  70. if (/^\.br/ || /^\.in/)
  71. {
  72. print STDERR "\n*** Deprecated macro encountered - rewrite needed\n";
  73. print STDERR "*** $_\n";
  74. die "*** Processing abandoned\n";
  75. }
  76. # Instead of .br, relevent "literal" sections are enclosed in .nf/.fi.
  77. elsif (/^\.nf/)
  78. {
  79. $innf = 1;
  80. }
  81. elsif (/^\.fi/)
  82. {
  83. $innf = 0;
  84. }
  85. # Handling .sp is subtle. If it is inside a literal section, do nothing if
  86. # the next line is a non literal text line; similarly, if not inside a
  87. # literal section, do nothing if a literal follows, unless we are inside
  88. # a .nf/.fi section or about to enter one. The point being that the <pre>
  89. # and </pre> that delimit literal sections will do the spacing. Always skip
  90. # if no previous output.
  91. elsif (/^\.sp/)
  92. {
  93. if ($wrotetext)
  94. {
  95. $_ = <STDIN>;
  96. if ($inpre)
  97. {
  98. print TEMP "\n" if (/^[\s.]/);
  99. }
  100. else
  101. {
  102. print TEMP "<br>\n<br>\n" if ($innf || /^\.nf/ || !/^[\s.]/);
  103. }
  104. redo; # Now process the lookahead line we just read
  105. }
  106. }
  107. elsif (/^\.TP/ || /^\.PP/ || /^\.P/)
  108. {
  109. &new_para();
  110. }
  111. elsif (/^\.SH\s*("?)(.*)\1/)
  112. {
  113. # Ignore the NAME section
  114. if ($2 =~ /^NAME\b/)
  115. {
  116. <STDIN>;
  117. next;
  118. }
  119. &end_para();
  120. my($title) = &do_line($2);
  121. if ($toc)
  122. {
  123. printf("<li><a name=\"TOC%d\" href=\"#SEC%d\">$title</a>\n",
  124. $ref, $ref);
  125. printf TEMP ("<br><a name=\"SEC%d\" href=\"#TOC1\">$title</a><br>\n",
  126. $ref);
  127. $ref++;
  128. }
  129. else
  130. {
  131. print TEMP "<br><b>\n$title\n</b><br>\n";
  132. }
  133. }
  134. elsif (/^\.SS\s*("?)(.*)\1/)
  135. {
  136. &end_para();
  137. my($title) = &do_line($2);
  138. print TEMP "<br><b>\n$title\n</b><br>\n";
  139. }
  140. elsif (/^\.B\s*(.*)/)
  141. {
  142. &new_para() if (!$inpara);
  143. $_ = &do_line($1);
  144. s/"(.*?)"/$1/g;
  145. print TEMP "<b>$_</b>\n";
  146. $wrotetext = 1;
  147. }
  148. elsif (/^\.I\s*(.*)/)
  149. {
  150. &new_para() if (!$inpara);
  151. $_ = &do_line($1);
  152. s/"(.*?)"/$1/g;
  153. print TEMP "<i>$_</i>\n";
  154. $wrotetext = 1;
  155. }
  156. # A comment that starts "HREF" takes the next line as a name that
  157. # is turned into a hyperlink, using the text given, which might be
  158. # in a special font. If it ends in () or (digits) or punctuation, they
  159. # aren't part of the link.
  160. elsif (/^\.\\"\s*HREF/)
  161. {
  162. $_=<STDIN>;
  163. chomp;
  164. $_ = &do_line($_);
  165. $_ =~ s/\s+$//;
  166. $_ =~ /^(?:<.>)?([^<(]+)(?:\(\))?(?:<\/.>)?(?:\(\d+\))?[.,;:]?$/;
  167. print TEMP "<a href=\"$1.html\">$_</a>\n";
  168. }
  169. # A comment that starts "HTML" inserts literal HTML
  170. elsif (/^\.\\"\s*HTML\s*(.*)/)
  171. {
  172. print TEMP $1;
  173. }
  174. # A comment that starts < inserts that HTML at the end of the
  175. # *next* input line - so as not to get a newline between them.
  176. elsif (/^\.\\"\s*(<.*>)/)
  177. {
  178. my($markup) = $1;
  179. $_=<STDIN>;
  180. chomp;
  181. $_ = &do_line($_);
  182. $_ =~ s/\s+$//;
  183. print TEMP "$_$markup\n";
  184. }
  185. # A comment that starts JOIN joins the next two lines together, with one
  186. # space between them. Then that line is processed. This is used in some
  187. # displays where two lines are needed for the "man" version. JOINSH works
  188. # the same, except that it assumes this is a shell command, so removes
  189. # continuation backslashes.
  190. elsif (/^\.\\"\s*JOIN(SH)?/)
  191. {
  192. my($one,$two);
  193. $one = <STDIN>;
  194. $two = <STDIN>;
  195. $one =~ s/\s*\\e\s*$// if (defined($1));
  196. chomp($one);
  197. $two =~ s/^\s+//;
  198. $_ = "$one $two";
  199. redo; # Process the joined lines
  200. }
  201. # .EX/.EE are used in the pcre2demo page to bracket the entire program,
  202. # which is unmodified except for turning backslash into "\e".
  203. elsif (/^\.EX\s*$/)
  204. {
  205. print TEMP "<PRE>\n";
  206. while (<STDIN>)
  207. {
  208. last if /^\.EE\s*$/;
  209. s/\\e/\\/g;
  210. s/&/&amp;/g;
  211. s/</&lt;/g;
  212. s/>/&gt;/g;
  213. print TEMP;
  214. }
  215. }
  216. # Ignore anything not recognized
  217. next;
  218. }
  219. # Line does not begin with a dot. Replace blank lines with new paragraphs
  220. if (/^\s*$/)
  221. {
  222. &end_para() if ($wrotetext);
  223. next;
  224. }
  225. # Convert fonts changes and output an ordinary line. Ensure that indented
  226. # lines are marked as literal.
  227. $_ = &do_line($_);
  228. &new_para() if (!$inpara);
  229. if (/^\s/)
  230. {
  231. if (!$inpre)
  232. {
  233. print TEMP "<pre>\n";
  234. $inpre = 1;
  235. }
  236. }
  237. elsif ($inpre)
  238. {
  239. print TEMP "</pre>\n";
  240. $inpre = 0;
  241. }
  242. # Add <br> to the end of a non-literal line if we are within .nf/.fi
  243. $_ .= "<br>\n" if (!$inpre && $innf);
  244. print TEMP;
  245. $wrotetext = 1;
  246. }
  247. # The TOC, if present, will have been written - terminate it
  248. print "</ul>\n" if ($toc);
  249. # Copy the remainder to the standard output
  250. close(TEMP);
  251. open(TEMP, "/tmp/$$") || die "Can't open /tmp/$$ for input\n";
  252. print while (<TEMP>);
  253. print <<End ;
  254. <p>
  255. Return to the <a href="index.html">PCRE2 index page</a>.
  256. </p>
  257. End
  258. close(TEMP);
  259. unlink("/tmp/$$");
  260. # End