#!/usr/bin/perl # # pdfmom: front end to run groff to produce PDFs # # Copyright 2012-2024 Free Software Foundation, Inc. # # Written by Deri James # # This file is part of groff, the GNU roff typesetting system. # # groff is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your # option) any later version. # # groff is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . use strict; use warnings; use File::Spec; use File::Temp qw/tempfile/; my @cmd; my $dev='pdf'; my $groff='groff'; my $preconv=''; my $readstdin=1; my $mom='-mom'; my $zflg=''; if ($0=~m/pdf(\w+)$/) { my $m=$1; if ($m=~m/^(mom|mm|ms|me|man|mandoc)$/) { $mom="-".$m; } else { $mom=''; } } my $RT_SEP=':'; $ENV{PATH}=$ENV{GROFF_BIN_PATH}.$RT_SEP.$ENV{PATH} if exists($ENV{GROFF_BIN_PATH}); $ENV{TMPDIR}=$ENV{GROFF_TMPDIR} if exists($ENV{GROFF_TMPDIR}); $groff=$ENV{GROFF_COMMAND} if exists ($ENV{GROFF_COMMAND}); (undef,undef,my $prog)=File::Spec->splitpath($0); sub abort { my $message=shift(@_); print STDERR "$prog: fatal error: $message"; exit 1; } sub autopsy { my $waitstatus=shift(@_); my $finding; if ($waitstatus == -1) { $finding = "unable to run groff: $!\n"; } elsif ($? & 127) { $finding = sprintf("$groff died with signal %d, %s core dump\n", ($? & 127), ($? & 128) ? 'with' : 'without'); } else { $finding = sprintf("$groff exited with status %d\n", $? >> 8); } return $finding; } while (my $c=shift) { $c=~s/(? 2) { $dev=substr($c,2); } else { $dev=shift; } next; } elsif (substr($c,0,2) eq '-K') { if (length($c) > 2) { $preconv.=" $c"; } else { $preconv.=" $c"; $preconv.=shift; } next; } elsif (substr($c,0,2) eq '-k') { $preconv.=" $c"; next; } elsif ($c eq '-Z') { $zflg=$c; next; } elsif ($c eq '-z') { $zflg="$c -dPDF.EXPORT=1"; next; } elsif ($c eq '--roff') { $mom=''; } elsif ($c eq '--help') { print "usage: pdfmom [--roff] [-Tpdf] [groff-option ...] [file ...]\n"; print "usage: pdfmom [--roff] -Tps [pdfroff-option ...] [groff-option ...] [file ...]\n"; print "usage: pdfmom {-v | --version}\n"; print "usage: pdfmom --help\n"; print "\nHandle forward references in groff(1) documents" . " to be formatted as PDF.\n" . "See the pdfmom(1) manual page.\n"; exit; } elsif ($c eq '-v' or $c eq '--version') { print "GNU pdfmom (groff) version 1.24.0\n"; my $waitstatus = system("$groff -T$dev --version"); abort(autopsy($?)) unless $waitstatus == 0; exit; } elsif (substr($c,0,1) eq '-') { if (length($c) > 1) { push(@cmd,"\"$c\""); push(@cmd,"'".(shift)."'") if length($c)==2 and index('dDfFIKLmMnoPrwW',substr($c,-1)) >= 0; } else { # Just a '-' push(@cmd,$c); $readstdin=2; } } else { # Got a filename? push(@cmd,"\"$c\""); $readstdin=0 if $readstdin == 1; } } my $cmdstring=' '.join(' ',@cmd).' '; if ($readstdin) { my ($fh,$tmpfn)=tempfile('pdfmom-XXXXX', UNLINK=>1); while () { print $fh ($_); } close($fh); $cmdstring=~s/ - / $tmpfn / if $readstdin == 2; $cmdstring.=" $tmpfn " if $readstdin == 1; } my $waitstatus = 0; if ($dev eq 'pdf') { if ($mom) { $waitstatus = system("$groff -Tpdf -dLABEL.REFS=1 $mom -z $cmdstring 2>&1 | LC_ALL=C grep '^\\. *ds' | $groff -Tpdf $preconv -dPDF.EXPORT=1 -dLABEL.REFS=1 $mom -z - $cmdstring 2>&1 | LC_ALL=C grep '^\\. *ds' | $groff -Tpdf $mom $preconv - $cmdstring $zflg"); abort(autopsy($?)) unless $waitstatus == 0; } else { $waitstatus = system("$groff -Tpdf $preconv -dPDF.EXPORT=1 -z $cmdstring 2>&1 | LC_ALL=C grep '^\\. *ds' | $groff -Tpdf $preconv - $cmdstring $zflg"); abort(autopsy($?)) unless $waitstatus == 0; } } elsif ($dev eq 'ps') { $waitstatus = system("$groff -Tpdf -dLABEL.REFS=1 $mom -z $cmdstring 2>&1 | LC_ALL=C grep '^\\. *ds' | pdfroff -mpdfmark $mom --no-toc - $preconv $cmdstring"); abort(autopsy($?)) unless $waitstatus == 0; } elsif ($dev eq '-z') # pseudo dev - just compile for warnings { $waitstatus = system("$groff -Tpdf $mom -z $cmdstring"); abort(autopsy($?)) unless $waitstatus == 0; } else { abort("groff output device '$dev' not supported"); } # Local Variables: # fill-column: 72 # mode: CPerl # End: # vim: set cindent noexpandtab shiftwidth=4 softtabstop=4 textwidth=72: