Articles I've written for customers on IT issues.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1308 lines
30 KiB

4 years ago
  1. #!/usr/bin/env perl
  2. # File : makejmlrbook
  3. # Author : Nicola L C Talbot
  4. # Date : 22nd March 2010
  5. # Last Modified : 30 May 2012
  6. # Version : 0.32
  7. # Description : Given the name of a document using the
  8. # jmlrbook class file, this script runs
  9. # pdflatex (and possibly bibtex) on the
  10. # imported articles and the main document.
  11. # http://theoval.cmp.uea.ac.uk/~nlct/
  12. #
  13. # This file is distributed as part of the jmlr LaTeX bundle.
  14. #
  15. # Copyright (c) 2006 Nicola L.C. Talbot
  16. # This work may be distributed and/or modified under the
  17. # conditions of the LaTeX Project Public License, either version 1.3
  18. # of this license or any later version.
  19. # The latest version of this license is in
  20. # http://www.latex-project.org/lppl.txt
  21. # and version 1.3 or later is part of all distributions of LaTeX
  22. # version 2005/12/01 or later.
  23. #
  24. # This work has the LPPL maintenance status `maintained'.
  25. #
  26. # The Current Maintainer of this work is Nicola Talbot.
  27. use Getopt::Long;
  28. use File::Basename;
  29. use File::Copy;
  30. use Cwd;
  31. use strict;
  32. my $version = "0.32 (2012-05-28)";
  33. my $eol = "\n";
  34. my $dd = '/';
  35. if ($^O eq 'MSWin32')
  36. {
  37. $eol = "\r\n";
  38. $dd = "\\";
  39. }
  40. my $showversion = 0;
  41. my $showhelp = 0;
  42. my $quiet = 0;
  43. my $batchtex = 0;
  44. my $online = 1;
  45. my $print = 1;
  46. my $html = 1;
  47. my $latexapp = 'pdflatex';
  48. my $bibtexapp = 'bibtex';
  49. my $latexopts = '';
  50. my $bibtexopts = '';
  51. my $format = 'pdf';
  52. my $logourl = '';
  53. my $extractpreface = 0; # v0.3 added
  54. # execute system calls (--noexecute will just list the system calls
  55. # without executing them)
  56. my $execute = 1; # v0.31 added
  57. unless(&GetOptions(
  58. "online!" => \$online,
  59. "print!" => \$print,
  60. "html!" => \$html,
  61. "extractpreface!" => \$extractpreface,
  62. "logourl=s" => \$logourl,
  63. "format=s" => \$format,
  64. "latexapp=s" => \$latexapp,
  65. "bibtexapp=s" => \$bibtexapp,
  66. "latexopts=s" => \$latexopts,
  67. "bibtexopts=s" => \$bibtexopts,
  68. "quieter!" => \$quiet,
  69. "batchtex!" => \$batchtex,
  70. "execute!" => \$execute,
  71. "version" => \$showversion,
  72. "help" => \$showhelp))
  73. {
  74. die "Use --help for help\n";
  75. }
  76. my $appname = basename($0);
  77. if ($showhelp)
  78. {
  79. die "$appname version $version Copyright (c) 2010 Nicola L C Talbot\n",
  80. "Distributed under the LaTeX Project Public License.\n\n",
  81. "Syntax: $appname [options] <filename>\n\n",
  82. "<filename> should be the name of the master document for a LaTeX \n",
  83. "file that uses the jmlrbook class. The .tex extension may be\n",
  84. "omitted.\n\n",
  85. "Basic options:\n",
  86. "--online\t\tGenerate the color on-line version (default)\n",
  87. "--noonline\t\tDon't generate the color on-line version\n",
  88. "--print\t\t\tGenerate the grayscale print version (default)\n",
  89. "--noprint\t\tDon't generate the grayscale print version\n",
  90. "--html\t\t\tGenerate the HTML version (default)\n",
  91. "--nohtml\t\tDon't generate the HTML version\n",
  92. "--extractpreface\tParse document for preface environment\n",
  93. "--noextractpreface\tDon't parse document for preface environment\n",
  94. "--logourl <url>\tMake the logo on the HTML index page link to <url>\n",
  95. "--batchtex\t\tRun TeX in batch mode\n",
  96. "--nobatchtex\t\tDon't run TeX in batch mode\n",
  97. "--quieter\t\tReduce messages to stdout and run TeX in batch mode\n",
  98. "--noquieter\t\tDon't reduce messages to stdout\n",
  99. "--execute\t\tExecute system calls (default)\n",
  100. "--noexecute\t\tDon't execute system calls, just list the\n",
  101. "\t\t\tcommands.\n",
  102. "--version\t\tDisplay version number and exit\n",
  103. "--help\t\t\tDisplay help message and exit\n",
  104. "\nAdvanced options:\n",
  105. "--latexapp <name>\tApplication used to call LaTeX\n",
  106. "\t\t\t(Defaults to 'pdflatex')\n",
  107. "--format <string>\tOutput format (default: 'pdf')\n",
  108. "--bibtexapp <name>\tApplication used to call BibTeX\n",
  109. "\t\t\t(Defaults to 'bibtex')\n",
  110. "--latexopt <string>\tOptions to pass to LaTeX\n",
  111. "--bibtexopt <string>\tOptions to pass to BibTeX\n";
  112. }
  113. if ($showversion)
  114. {
  115. die "$appname version $version copyright (c) 2010 Nicola L C Talbot\n",
  116. "Distributed under the LaTeX Project Public License.\n";
  117. }
  118. unless ($#ARGV == 0)
  119. {
  120. die "$appname: missing filename\n",
  121. "use --help for help\n";
  122. }
  123. if ($quiet or $batchtex)
  124. {
  125. $latexopts = '-interaction=batchmode '.$latexopts;
  126. }
  127. if ($quiet)
  128. {
  129. $bibtexopts = '-terse '.$bibtexopts;
  130. }
  131. my ($main_name, $main_path, $main_suffix)
  132. = fileparse($ARGV[0], '\.(tex|ltx)');
  133. $main_suffix = '.tex' unless $main_suffix;
  134. my $org_dir = cwd();
  135. &chdirordie($main_path);
  136. my $mainaux = "$main_name.aux";
  137. # If the aux file doesn't exist or the aux file is older than
  138. # the main file, run latex
  139. if (not -e $mainaux or (-M $mainaux > -M "$main_name$main_suffix"))
  140. {
  141. &latex($main_name);
  142. }
  143. my $main_bibdata = 0;
  144. my @imports = ();
  145. my %pagerefs = ();
  146. my $preface_data; # v0.3 new
  147. my @preface_editors = ();
  148. # Parse aux file
  149. &parsemainaux($mainaux);
  150. # Replace any instances of \articlepagesref
  151. foreach my $import (@imports)
  152. {
  153. my $label = $import->{'label'};
  154. my $pages = $pagerefs{$label}->{'start'}.'--'
  155. . $pagerefs{$label}->{'end'};
  156. $import->{'author'}=~s/\\articlepagesref\s*{$label}/$pages/;
  157. }
  158. if ($html)
  159. {
  160. # If the html files need to be created, make the directory
  161. # html-src, if it doesn't already exist
  162. unless (-d 'html-src')
  163. {
  164. &mkdirordie('html-src');
  165. }
  166. unless (-d 'html')
  167. {
  168. &mkdirordie('html');
  169. }
  170. if ($extractpreface) # v0.3 new
  171. {
  172. # If the preface needs to be extract, make a directory for it if
  173. # it doesn't already exist
  174. my $prefdir = &fname("html-src", $preface_data->{'OutFile'});
  175. unless (-d $prefdir)
  176. {
  177. &mkdirordie($prefdir);
  178. }
  179. my $prefbase = &fname($prefdir, $preface_data->{'OutFile'});
  180. &createprefacefile($prefdir, $prefbase);
  181. # Create the cfg file
  182. &createjmlrcfg("html-src", $preface_data->{'OutFile'});
  183. &chdirordie($prefdir);
  184. &latex($preface_data->{'OutFile'});
  185. &htlatex($preface_data->{'OutFile'}, 'jmlr');
  186. &chdirordie($org_dir, $main_path);
  187. # Check the appropriate subdirectory is in html directory
  188. my $outname = &fname('html', $preface_data->{'OutFile'});
  189. unless (-d $outname)
  190. {
  191. &mkdirordie($outname);
  192. }
  193. # Copy pdf file
  194. &copyordie("$prefbase.$format",
  195. &fname($outname, "$preface_data->{OutFile}.$format"));
  196. # Copy html file
  197. &copyhtml($preface_data->{'OutFile'}, $preface_data->{'OutFile'});
  198. }
  199. }
  200. # Iterate through each imported article
  201. foreach my $import (@imports)
  202. {
  203. my $label = $import->{'label'};
  204. my $importbase = &fname($import->{'path'}, $import->{'name'});
  205. # Check the aux file of this article
  206. my $aux = "$importbase.aux";
  207. # The aux file should exist because running LaTeX on the
  208. # main file will create the aux file.
  209. my $bibdata = 0;
  210. if (open AUX, $aux)
  211. {
  212. &message("Reading '$aux'...\n");
  213. while (<AUX>)
  214. {
  215. if (/\\bibdata\b/)
  216. {
  217. $bibdata = 1;
  218. }
  219. }
  220. close AUX;
  221. }
  222. elsif (not $execute)
  223. {
  224. warn "Can't open '$aux' - skipping\n";
  225. }
  226. else
  227. {
  228. die "$appname: Can't open '$aux' $!\n";
  229. }
  230. # Do we need a bibtex run?
  231. if ($bibdata)
  232. {
  233. my $log = "$importbase.log";
  234. # If the log file doesn't exist, run LaTeX
  235. unless (-e $log)
  236. {
  237. &chdirordie($import->{'path'});
  238. &latex($import->{'name'});
  239. &chdirordie($org_dir, $main_path);
  240. }
  241. open LOGFD, $log or die "$appname: Can't open '$log' $!\n";
  242. &message("Reading '$log'...\n");
  243. my $runbibtex = 0;
  244. while (<LOGFD>)
  245. {
  246. if (/There were undefined citations\./)
  247. {
  248. # Run bibtex and latex
  249. $runbibtex = 1;
  250. last;
  251. }
  252. }
  253. close LOGFD;
  254. if ($runbibtex)
  255. {
  256. &chdirordie($import->{'path'});
  257. &bibtex($import->{'name'});
  258. &latex($import->{'name'});
  259. &chdirordie($org_dir, $main_path);
  260. }
  261. }
  262. if ($html)
  263. {
  264. # If html is required, we also need pdf versions of the
  265. # individual articles.
  266. # v0.2 run latex even if pdf file exists to ensure start page
  267. # number is correct.
  268. &chdirordie($import->{'path'});
  269. &latexstartpage($import->{'name'}, $pagerefs{$label}->{'start'});
  270. &chdirordie($org_dir, $main_path);
  271. # Do we need a rerun?
  272. if (&needs_rerun($importbase))
  273. {
  274. &chdirordie($import->{'path'});
  275. &latexstartpage($import->{'name'}, $pagerefs{$label}->{'start'});
  276. &chdirordie($org_dir,$main_path);
  277. }
  278. my $importdir = $import->{'path'};
  279. if ($importdir = '.')
  280. {
  281. $importdir = $import->{'name'};
  282. }
  283. # Check the appropriate subdirectory is in html-src
  284. my $name = &fname('html-src', $importdir);
  285. unless (-d $name)
  286. {
  287. &mkdirordie($name);
  288. }
  289. my $text = '';
  290. # Read the LaTeX file and store everything up to
  291. # the end of the abstract
  292. my $tex = "$importbase.tex";
  293. my $absfile = &fname("html-src", $importdir,
  294. $import->{'name'}.'.tex');
  295. if ($execute)
  296. {
  297. open TEX, $tex or die "$appname: Can't open '$tex': $!\n";
  298. while (<TEX>)
  299. {
  300. # This doesn't handle complicated cases, such as
  301. # the author using \abstract ... \endabstract
  302. # or commenting out the abstract with conditionals
  303. if (/^([^%]*)\\end{abstract}/)
  304. {
  305. $text .= $&;
  306. last;
  307. }
  308. $text .= $_;
  309. }
  310. close TEX;
  311. # Add the 'html' class option:
  312. unless ($text=~
  313. s/^([^%]*)\\documentclass\s*\[(.*)\]/$1\\documentclass[$2,html]/m)
  314. {
  315. $text=~s/^([^%]*)\\documentclass\s*/$1\\documentclass[html]/m;
  316. }
  317. my $aux = "$importbase.aux";
  318. $aux=~s/\\/\//g if ($dd eq '\\');
  319. my $prebegindoc = '\\hypersetup{draft}' . $eol
  320. . '\\makeatletter' . $eol
  321. . "\\input{../../$aux}" . $eol
  322. . '\\makeatother'
  323. . $eol;
  324. my $begindoc = '';
  325. # Set the authors
  326. if (defined($import->{'author'}))
  327. {
  328. my $author = $import->{'author'};
  329. $author=~s/^([^;]*);/\\textbf{\\emph{$1};}/;
  330. $begindoc .= "\\jmlrauthors{$author}";
  331. }
  332. # Add content div
  333. # v0.31 modified \footnote to set the footnote text as in-line
  334. # parenthesis.
  335. $text=~s/^([^%\n\r\f]*)\\begin{document}/
  336. $prebegindoc$&$begindoc
  337. \\HCode{<div id="content">}
  338. \\renewcommand{\\footnote}[2][]{ (\#2)}%$eol
  339. /mx;
  340. # Create file containing the abstract
  341. open ABSFD,">$absfile"
  342. or die "$appname: Can't create '$absfile': $!\n";
  343. print ABSFD "\\batchmode", $eol if ($batchtex or $quiet);
  344. my $texpath = $import->{path};
  345. $texpath=~s/\\/\//g if ($dd eq '\\');
  346. print ABSFD
  347. "\\makeatletter",$eol,
  348. "\\def\\input\@path{{../../$texpath/}}$eol",
  349. "\\makeatother",$eol,
  350. $text, $eol,
  351. "\\HCode{", &htmltimestamp, "}", $eol,
  352. "\\HCode{</div>}", $eol,
  353. &htmlmenu, # v0.3 added by Olivier Chapelle
  354. "\\end{document}",$eol;
  355. close ABSFD;
  356. }
  357. else
  358. {
  359. &messagecall("Skipping creation of '$absfile'\n");
  360. }
  361. # Create the cfg file
  362. &createjmlrcfg("html-src", $importdir);
  363. # Run htlatex
  364. # Change directory
  365. &chdirordie("html-src", $importdir);
  366. &htlatex($import->{'name'}, 'jmlr');
  367. # Go back to main directory
  368. &chdirordie($org_dir, $main_path);
  369. # Copy the html file to the html directory, but rename
  370. # the css file to jmlr.css
  371. &copyhtml($importdir, $import->{'name'});
  372. # Check the appropriate subdirectory is in html directory
  373. my $outname = &fname('html', $importdir);
  374. unless (-d $outname)
  375. {
  376. &mkdirordie($outname);
  377. }
  378. # Copy pdf file
  379. &copyordie("$importbase.$format",
  380. &fname($outname, "$import->{name}.$format"));
  381. }
  382. }
  383. # do we need to run bibtex on the main document?
  384. if ($main_bibdata)
  385. {
  386. &bibtex($main_name);
  387. }
  388. if ($online)
  389. {
  390. &latexonline($main_name);
  391. # do we need a rerun?
  392. if (&needs_rerun($main_name))
  393. {
  394. &message("Rerun required\n");
  395. &latexonline($main_name);
  396. # check again
  397. if (&needs_rerun($main_name))
  398. {
  399. &message("Rerun required\n");
  400. &latexonline($main_name);
  401. }
  402. }
  403. }
  404. if ($print)
  405. {
  406. &latexprint($main_name);
  407. # do we need a rerun?
  408. if (&needs_rerun($main_name))
  409. {
  410. &message("Rerun required\n");
  411. &latexprint($main_name);
  412. # check again
  413. if (&needs_rerun($main_name))
  414. {
  415. &message("Rerun required\n");
  416. &latexprint($main_name);
  417. }
  418. }
  419. }
  420. if ($html and $execute)
  421. {
  422. # Make the index file
  423. my $indexfile = &fname('html-src', "index");
  424. my $preamble = '';
  425. open OUTFD, ">$indexfile.tex"
  426. or die "Can't open '$indexfile.tex': $!\n";
  427. open INFD, "$main_name.tex"
  428. or die "Can't open '$main_name.tex': $!\n";
  429. print OUTFD "\\batchmode", $eol if ($batchtex or $quiet);
  430. print OUTFD
  431. "\\makeatletter",$eol,
  432. "\\def\\input\@path{{../}}$eol",
  433. "\\makeatother",$eol,
  434. "\\def\\jmlrgrayscale{0}",$eol;
  435. while (<INFD>)
  436. {
  437. unless
  438. (s/^([^%]*)\\documentclass\s*\[([^\]]*)\]/
  439. $1\\documentclass[$2,html]/x)
  440. {
  441. s/^([^%]*)\\documentclass\s*/$&\[html\]/;
  442. }
  443. s/^([^%]*)\\begin{document}/
  444. \\hypersetup{draft}$eol$&\\HCode{<div id="content">}/x;
  445. if (/^([^%]*)\\maketitle/)
  446. {
  447. $preamble .= join('', $1, "\\maketitle", $eol);
  448. last;
  449. }
  450. $preamble .= $_;
  451. }
  452. close INFD;
  453. # Find the book logo
  454. if ($preamble
  455. =~/\\logo\s*(?:\[[^\]]*\])?\s*{(%\s*\n)?\\includegraphics\s*(\[[^\]]*\])?{([^}]*)}}/m)
  456. {
  457. my $texpath = $3;
  458. my $orgtexpath = $texpath;
  459. $texpath=~s/\//\\/g if ($dd eq "\\");
  460. my $ext = '';
  461. if (-e $texpath)
  462. {
  463. &copyordie($texpath, 'html');
  464. &copyordie($texpath, 'html-src');
  465. }
  466. elsif (-e "$texpath.png")
  467. {
  468. &copyordie("$texpath.png", 'html');
  469. &copyordie("$texpath.png", 'html-src');
  470. $ext = '.png';
  471. }
  472. elsif (-e "$texpath.jpg")
  473. {
  474. &copyordie("$texpath.jpg", 'html');
  475. &copyordie("$texpath.jpg", 'html-src');
  476. $ext = '.jpg';
  477. }
  478. elsif (-e "$texpath.gif")
  479. {
  480. &copyordie("$texpath.gif", 'html');
  481. &copyordie("$texpath.gif", 'html-src');
  482. $ext = '.gif';
  483. }
  484. my $img = basename($texpath);
  485. if ($logourl)
  486. {
  487. $preamble=~s/
  488. \\includegraphics(\[[^\]]*\])?{$orgtexpath}/
  489. \\href{$logourl}{\\includegraphics${1}{$img$ext}}/mgx;
  490. }
  491. else
  492. {
  493. $preamble=~s/
  494. \\includegraphics(\[[^\]]*\])?{$orgtexpath}/
  495. \\includegraphics${1}{$img$ext}/mgx;
  496. }
  497. }
  498. print OUTFD $preamble, $eol;
  499. # Parse TOC
  500. my $toc = "$main_name.toc";
  501. # Add link to preface if required
  502. if ($extractpreface)
  503. {
  504. print OUTFD
  505. "\\begin{description}\\item[\\normalfont \\prefacename]", $eol;
  506. print OUTFD "\\textbf{\\emph{\\jmlrabbrnamelist{{",
  507. join('},{', @preface_editors),
  508. "}}};} ",
  509. '\\csname @jmlrabbrvproceedings\\endcsname\\space',
  510. '\\csname @jmlrvolume\\endcsname:',
  511. $preface_data->{'Start'};
  512. unless ($preface_data->{'Start'} eq $preface_data->{'End'})
  513. {
  514. print OUTFD '--', $preface_data->{'End'};
  515. }
  516. print OUTFD ', \\csname @jmlryear\\endcsname\\newline', $eol;
  517. my $name = $preface_data->{'OutFile'};
  518. print OUTFD "[\\HCode{<a href=\"$name.html\">html</a>}] ",
  519. "[\\HCode{<a href=\"$name/$name.pdf\">pdf</a>}]",
  520. $eol;
  521. print OUTFD "\\end{description}$eol";
  522. }
  523. open TOC, $toc or die "Can't open '$toc': $!\n";
  524. my $idx = 0;
  525. while (<TOC>)
  526. {
  527. if (/^\\tocpart\s*{(.*)}\s*$/)
  528. {
  529. print OUTFD "\\begin{center}\\bfseries $1\\end{center}$eol";
  530. }
  531. elsif (/\\contentsline\s*{papertitle}{(.*)}{[^{}]*}{[^{}]*}\s*$/)
  532. {
  533. # v0.3 Changed by Olivier Chapelle to use description
  534. # environment instead of paragraph break
  535. print OUTFD "\\begin{description}\\item[\\normalfont $1]$eol";
  536. }
  537. elsif (/\\contentsline\s*{chapterauthor}{(.*)}{[^{}]*}{[^{}]*}\s*$/)
  538. {
  539. my $details = $1;
  540. $details=~s/([^;]*);/\\textbf{\\emph{$1};}/;
  541. my $label = $imports[$idx]->{'label'};
  542. my $pages = $pagerefs{$label}->{'start'}.'--'
  543. . $pagerefs{$label}->{'end'};
  544. $details=~s/\\articlepagesref\s*{$label}/$pages/;
  545. # v0.3 Changed by Olivier Chapelle to use newline instead of par
  546. print OUTFD "$details\\newline$eol";
  547. my $name = $imports[$idx]->{'name'};
  548. print OUTFD "[\\HCode{<a href=\"$name.html\">abs</a>}] ",
  549. "[\\HCode{<a href=\"$name/$name.pdf\">pdf</a>}]",
  550. $eol;
  551. # v0.3 Changed by Olivier Chapelle to end description
  552. print OUTFD "\\end{description}$eol";
  553. $idx++;
  554. }
  555. }
  556. close TOC;
  557. # version 0.2 added time stamp
  558. print OUTFD "\\HCode{", &htmltimestamp, "}$eol";
  559. print OUTFD &htmlmenu; # v0.3 Added by Olivier Chapelle
  560. print OUTFD "\\HCode{</div>}\\end{document}$eol";
  561. close OUTFD;
  562. # Go into html-src directory and run htlatex
  563. &chdirordie('html-src');
  564. &htlatex("index", 'xhtml');
  565. &chdirordie('..');
  566. # Copy to html directory
  567. my $inname = &fname('html-src', 'index.html');
  568. my $outname = &fname('html', 'index.html');
  569. open INFD, $inname or die "Can't open '$inname': $!\n";
  570. open OUTFD, ">$outname" or die "Can't open '$outname': $!\n";
  571. while (<INFD>)
  572. {
  573. s/href="index.css"/href="jmlr.css"/;
  574. print OUTFD;
  575. }
  576. close OUTFD;
  577. close INFD;
  578. # v0.2 new:
  579. # Copy any images generated by htlatex to html/
  580. my @imagefiles = glob(&fname('html-src', "index*.png"));
  581. foreach my $imagefile (@imagefiles)
  582. {
  583. copy($imagefile, 'html');
  584. }
  585. }
  586. elsif ($html)
  587. {
  588. &messagecall("chdir 'html-src'\n");
  589. &htlatex("index", 'xhtml');
  590. }
  591. # Return to original directory
  592. chdir $org_dir;
  593. # Subroutines
  594. sub message{ print @_ unless ($quiet) }
  595. sub messagecall{ print @_ if (not $quiet or not $execute) }
  596. sub systemcall{
  597. my $cmd = shift;
  598. &messagecall($cmd, "\n");
  599. my $code = 0;
  600. $code = system($cmd) if ($execute);
  601. $code;
  602. }
  603. sub latex{
  604. my $file = shift;
  605. my $code = &systemcall(join(' ', $latexapp, $latexopts, "\"$file\""));
  606. if ($code)
  607. {
  608. die "**LaTeX run failed with exit code $code.**\n",
  609. "Check '$file.log' for details\n";
  610. }
  611. }
  612. # v0.2 new
  613. sub latexstartpage{
  614. my $file = shift;
  615. my $page = shift;
  616. my $code = &systemcall(join(' ', $latexapp, $latexopts,
  617. "\"\\def\\startpage{$page}\\input{$file}\""));
  618. if ($code)
  619. {
  620. die "**LaTeX run failed with exit code $code.**\n",
  621. "Check '$file.log' for details\n";
  622. }
  623. }
  624. sub copyordie{
  625. my ($org, $dest) = @_;
  626. &messagecall("copy '$org' to '$dest'\n");
  627. if ($execute)
  628. {
  629. copy($org, $dest) or die "Can't copy '$org' to '$dest': $!\n";
  630. }
  631. }
  632. sub latexonline{
  633. my $file = shift;
  634. my $code = &systemcall(join(' ', $latexapp, $latexopts,
  635. "\"\\def\\jmlrgrayscale{0}\\input{$file}\""));
  636. if ($code)
  637. {
  638. die "**LaTeX run failed with exit code $code.**\n",
  639. "Check '$file.log' for details\n";
  640. }
  641. &copyordie("$file.$format", "$file-online.$format");
  642. }
  643. sub latexprint{
  644. my $file = shift;
  645. my $code = &systemcall(join(' ', $latexapp, $latexopts,
  646. "\"\\def\\jmlrgrayscale{1}\\input{$file}\""));
  647. if ($code)
  648. {
  649. die "**LaTeX run failed with exit code $code.**\n",
  650. "Check '$file.log' for details\n";
  651. }
  652. &copyordie("$file.$format", "$file-print.$format");
  653. }
  654. sub bibtex{
  655. my $file = shift;
  656. my $code = &systemcall(
  657. join(' ', $bibtexapp, $bibtexopts, "\"$file\""));
  658. if ($code)
  659. {
  660. die "**BibTeX run failed with exit code $code.**\n",
  661. "Check '$file.blg' for details\n";
  662. }
  663. }
  664. sub needs_rerun{
  665. my $file = shift;
  666. my $rerun = 0;
  667. unless ($execute)
  668. {
  669. &messagecall("Skipping rerun check for '$file'\n");
  670. return 0;
  671. }
  672. # Scan log file for rerun message
  673. my $log = "$file.log";
  674. # If there's no log file a run is needed
  675. open LOGFD, $log or return 1;
  676. while (<LOGFD>)
  677. {
  678. if (/Rerun to get cross-references right\./)
  679. {
  680. $rerun = 1;
  681. last;
  682. }
  683. }
  684. close LOGFD;
  685. return $rerun;
  686. }
  687. sub fname{ join($dd, @_) }
  688. # v0.3 new
  689. sub chdirordie{
  690. my $dirname = &fname(@_);
  691. &messagecall("chdir '$dirname'\n");
  692. unless (chdir $dirname)
  693. {
  694. if ($execute)
  695. {
  696. die "$appname: Can't change directory to $dirname: $!\n";
  697. }
  698. else
  699. {
  700. warn "(Can't change directory to '$dirname')\n";
  701. }
  702. }
  703. }
  704. # v0.31 new
  705. sub mkdirordie{
  706. my $dirname = &fname(@_);
  707. &messagecall("mkdir '$dirname'\n");
  708. unless (mkdir $dirname)
  709. {
  710. if ($execute)
  711. {
  712. die "$appname: Can't create directory '$dirname': $!\n";
  713. }
  714. else
  715. {
  716. warn "(Can't create directory '$dirname')\n";
  717. }
  718. }
  719. }
  720. # v0.2 new
  721. sub htmltimestamp{
  722. my $timestamp = localtime;
  723. return "<hr><center>Page last modified on $timestamp.</center>";
  724. }
  725. # v0.3 Added by Olivier Chapelle
  726. sub htmlmenu{
  727. return '
  728. \\HCode{<div id="fixed"><br>}
  729. \\HCode{<a align="right" href="http://www.jmlr.org" target=_top><img align="right" class="jmlr" src="http://jmlr.csail.mit.edu/jmlr.jpg" border="0"></a>}
  730. \\HCode{<p><br><br>}
  731. \\HCode{<p align="right"> <A href="http://www.jmlr.org/"> Home Page </A>}
  732. \\HCode{<p align="right"> <A href="/papers"> Papers </A>}
  733. \\HCode{<p align="right"> <A href="/author-info.html"> Submissions </A>}
  734. \\HCode{<p align="right"> <A href="/news.html"> News </A>}
  735. \\HCode{<p align="right"> <A href="/scope.html"> Scope </A>}
  736. \\HCode{<p align="right"> <A href="/editorial-board.html"> Editorial Board </A>}
  737. \\HCode{<p align="right"> <A href="/announcements.html"> Announcements </A>}
  738. \\HCode{<p align="right"> <A href="/proceedings"> Proceedings </A>}
  739. \\HCode{<p align="right"> <A href="/mloss">Open Source Software</A>}
  740. \\HCode{<p align="right"> <A href="/search-jmlr.html"> Search </A>}
  741. \\HCode{<p align="right"> <A href="/manudb"> Login </A></p>}
  742. \\HCode{<br><br>}
  743. \\HCode{<p align="right"> <A href="http://jmlr.csail.mit.edu/jmlr.xml">}
  744. \\HCode{<img src="http://jmlr.csail.mit.edu/RSS.gif" class="rss" alt="RSS Feed">}
  745. \\HCode{</A>}
  746. \\HCode{</div>}
  747. '
  748. }
  749. # v0.3 new
  750. sub htlatex{
  751. my ($filename, $cfg) = @_;
  752. # unicode-related options suggested by Olivier Chapelle
  753. # v0.31 added latex options in 5th parameter
  754. my $code = &systemcall(join(' ', 'htlatex',
  755. "\"$filename\"",
  756. "\"$cfg,uni-html4\"",
  757. "\" -cunihtf -utf8\"",
  758. '""',
  759. "\" $latexopts\""
  760. ));
  761. if ($code)
  762. {
  763. die "$appname: htlatex failed with exit code $code.\n";
  764. }
  765. }
  766. #v0.3 new
  767. sub createjmlrcfg{
  768. my $cfg = &fname(@_, "jmlr.cfg");
  769. unless ($execute)
  770. {
  771. &messagecall("Skipping creation of '$cfg'\n");
  772. return;
  773. }
  774. open CFG, ">$cfg" or die "$appname: Can't create '$cfg': $!\n";
  775. print CFG <<END_CFG;
  776. \\Preamble{html}
  777. \\begin{document}
  778. \\Css{div.maketitle {text-align:left;}}
  779. \\Css{h2.titleHead {text-align:left;}}
  780. \\Css{. {font-family:verdana,helvetica,sans-serif}}
  781. \\Css{a {text-decoration:none;color:\\#3030a0}}
  782. \\Css{.cmbx-10x-x-109{ font-weight: bold;}}
  783. \\Css{.cmbxti-10x-x-109{ font-weight: bold; font-style: italic;}}
  784. \\Css{\\#fixed {position:absolute; top:0; left:0; width:8em;
  785. height:100\\%;}}
  786. \\Css{\\#content {margin-top:1em; margin-left:10em;
  787. margin-right:0.5em;}}
  788. \\Css{img.jmlr {width: 7em;}}
  789. \\Css{img.rss {width: 2em;}}
  790. \\EndPreamble
  791. END_CFG
  792. # v0.3 Last four \Css lines above added by Olivier Chapelle
  793. close CFG;
  794. }
  795. #v0.3 new
  796. # copy html from html-src/$dir/ to html/ and rename css file
  797. sub copyhtml{
  798. my ($dir, $name) = @_;
  799. my $infile = &fname("html-src", $dir, "$name.html");
  800. my $outfile = &fname("html", "$name.html");
  801. unless ($execute)
  802. {
  803. &messagecall("Copy '$infile' to '$outfile'\n");
  804. return;
  805. }
  806. open INFD, $infile or die "Can't open '$infile': $!\n";
  807. open OUTFD, ">$outfile" or die "Can't open '$outfile': $!\n";
  808. while (<INFD>)
  809. {
  810. s/href="$name\.css"/href="jmlr.css"/;
  811. print OUTFD;
  812. }
  813. close OUTFD;
  814. close INFD;
  815. # Copy css file
  816. &copyordie("html-src/$dir/$name.css", "html/jmlr.css");
  817. }
  818. sub parsemainaux{
  819. my $mainaux = shift;
  820. &message("Reading '$mainaux'...\n");
  821. unless (open AUX, "$mainaux")
  822. {
  823. if ($execute)
  824. {
  825. die "$appname: Can't open '$mainaux' $!\n";
  826. }
  827. else
  828. {
  829. warn "(Can't open '$mainaux' - skipping)\n";
  830. return;
  831. }
  832. }
  833. while (<AUX>)
  834. {
  835. if (/\\bibdata\b/)
  836. {
  837. $main_bibdata = 1;
  838. }
  839. elsif (/\\\@jmlr\@import{(.*)}{(.*)}{(.*)}/)
  840. {
  841. my $import =
  842. {
  843. label => $1,
  844. path => $2,
  845. name => $3
  846. };
  847. $import->{'name'} =~s/\.(tex|ltx)\Z//;
  848. push @imports, $import;
  849. }
  850. elsif (/\\contentsline\s*{chapterauthor}{(.*)}{}{}}\s*$/
  851. and $#imports > -1)
  852. {
  853. $imports[$#imports]->{'author'} = $1;
  854. }
  855. elsif (/^\\newlabel\s*{([^}]*)jmlrstart}{{([^}]*)}{([^}]*)}/)
  856. {
  857. my $label = $1;
  858. $pagerefs{$label}->{'start'} = $3;
  859. }
  860. elsif (/^\\newlabel\s*{([^}]*)jmlrend}{{([^}]*)}{([^}]*)}/)
  861. {
  862. my $label = $1;
  863. $pagerefs{$label}->{'end'} = $3;
  864. }
  865. elsif ($extractpreface) # v0.3 new
  866. {
  867. if (/^\\\@prefacestart{([^}]*)}{(\d*)}/)
  868. {
  869. $preface_data->{'Start'} = $1;
  870. $preface_data->{'StartArabic'} = $2;
  871. }
  872. elsif (/^\\\@prefaceend{([^}]*)}/)
  873. {
  874. $preface_data->{'End'} = $1;
  875. }
  876. elsif (/^\\\@prefacefile{([^}]*)}{([^}]*)}/)
  877. {
  878. $preface_data->{'File'} = $1;
  879. $preface_data->{'OutFile'} = $2;
  880. }
  881. elsif (/^\\\@prefaceeditor{(.*)}/)
  882. {
  883. my $name = $1;
  884. $name=~s/\\\\.*//;
  885. push @preface_editors, $name;
  886. }
  887. }
  888. }
  889. # if preface is to be extracted, has the require data been found?
  890. if ($extractpreface)
  891. {
  892. unless ($preface_data->{'File'})
  893. {
  894. warn "$appname: Can't find preface information in aux file.\n",
  895. "Have you used the preface environment?\n";
  896. $extractpreface = 0;
  897. }
  898. }
  899. close AUX;
  900. }
  901. sub createprefacefile{
  902. my ($prefdir, $prefbase) = @_;
  903. my $prefout = "$prefbase.tex";
  904. &messagecall("Create preface file '$prefout'\n");
  905. return unless ($execute);
  906. # Open preface output file
  907. open PREFOUT, ">$prefout"
  908. or die "$appname: Can't open '$prefout': $!\n";
  909. print PREFOUT "\\batchmode", $eol if ($batchtex or $quiet);
  910. print PREFOUT "\\makeatletter", $eol;
  911. print PREFOUT "\\def\\input\@path{{../../}}", $eol;
  912. print PREFOUT "\\makeatother", $eol;
  913. # Get the book's preamble
  914. my $filename = "$main_name$main_suffix";
  915. open BOOK, $filename
  916. or die "$appname: Can't open '$filename': $!\n";
  917. while (<BOOK>)
  918. {
  919. if (/\\documentclass/)
  920. {
  921. unless (s/^([^%]*)\\documentclass\s*\[(.*)\]/$1\\documentclass[$2,html]/m)
  922. {
  923. s/^([^%]*)\\documentclass\s*/$1\\documentclass[html]/m;
  924. }
  925. print PREFOUT;
  926. }
  927. elsif (/^\\begin{document}/)
  928. {
  929. if ($preface_data->{'Start'}=~/^[clxvi]+$/)
  930. {
  931. print PREFOUT "\\pagenumbering{roman}%", $eol;
  932. }
  933. elsif ($preface_data->{'Start'}=~/^[CLXVI]+$/)
  934. {
  935. print PREFOUT "\\pagenumbering{Roman}%", $eol;
  936. }
  937. print PREFOUT
  938. "\\setcounter{page}{",
  939. $preface_data->{'StartArabic'},
  940. "}%", $eol;
  941. # \hypersetup{draft} is used to suppress links.
  942. # (Only a partial document so internal links may be
  943. # dead. Also prevents unwanted tag before the DOCTYPE
  944. # line in the HTML file.)
  945. print PREFOUT
  946. "\\hypersetup{draft}", $eol,
  947. '\\makeatletter',
  948. "\\\@openrightfalse\\input{../../$main_name.aux}",
  949. '\\makeatother', $eol;
  950. print PREFOUT
  951. "\\providecommand{\\HCode}[1]{}", $eol,
  952. "\\title{\\prefacename}", $eol,
  953. "\\begin{document}", $eol,
  954. "\\HCode{<div id=\"content\">}", $eol;
  955. last;
  956. }
  957. else
  958. {
  959. print PREFOUT;
  960. }
  961. }
  962. close BOOK;
  963. # Preface file name will have '/' as directory divider
  964. my $preffile = $preface_data->{'File'};
  965. if ($dd eq "\\")
  966. {
  967. $preffile=~s/\//\\/g;
  968. }
  969. open PREFIN, $preffile
  970. or die "$appname: Can't open '$preffile': $!\n";
  971. my $scanning = 0;
  972. while (<PREFIN>)
  973. {
  974. # This is fairly primitive and works best when the begin
  975. # and end of the environment are on their own line.
  976. if (/\\begin{preface}/)
  977. {
  978. print PREFOUT;
  979. $scanning = 1;
  980. }
  981. elsif ($scanning)
  982. {
  983. print PREFOUT;
  984. last if /\\end{preface}/;
  985. }
  986. }
  987. close PREFIN;
  988. print PREFOUT
  989. "\\HCode{", &htmltimestamp, "}", $eol,
  990. "\\HCode{</div>}", $eol,
  991. &htmlmenu,
  992. "\\end{document}", $eol;
  993. close PREFOUT;
  994. }
  995. 1;