groff: update vendor branch to v1.20.1
[dragonfly.git] / contrib / groff / contrib / mm / mmroff.pl
CommitLineData
465b256c 1#! /usr/bin/perl
4d3e9548
JL
2# -*- Perl -*-
3# Copyright (C) 1989, 2005, 2009
4# Free Software Foundation, Inc.
5#
6# This file is part of groff.
7#
8# groff is free software; you can redistribute it and/or modify it under
9# the terms of the GNU General Public License as published by the Free
10# Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# groff is distributed in the hope that it will be useful, but WITHOUT ANY
14# WARRANTY; without even the implied warranty of MERCHANTABILITY or
15# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16# for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
92d0a6a6
JR
20
21use strict;
22# runs groff in safe mode, that seems to be the default
23# installation now. That means that I have to fix all nice
24# features outside groff. Sigh.
25# I do agree however that the previous way opened a whole bunch
26# of security holes.
27
28my $no_exec;
29# check for -x and remove it
30if (grep(/^-x$/, @ARGV)) {
31 $no_exec++;
32 @ARGV = grep(!/^-x$/, @ARGV);
33}
34
35# mmroff should always have -mm, but not twice
36@ARGV = grep(!/^-mm$/, @ARGV);
37my $check_macro = "groff -rRef=1 -z -mm @ARGV";
38my $run_macro = "groff -mm @ARGV";
39
40my (%cur, $rfilename, $max_height, $imacro, $max_width, @out, @indi);
41open(MACRO, "$check_macro 2>&1 |") || die "run $check_macro:$!";
42while(<MACRO>) {
43 if (m#^\.\\" Rfilename: (\S+)#) {
44 # remove all directories just to be more secure
45 ($rfilename = $1) =~ s#.*/##;
46 next;
47 }
48 if (m#^\.\\" Imacro: (\S+)#) {
49 # remove all directories just to be more secure
50 ($imacro = $1) =~ s#.*/##;
51 next;
52 }
53 if (m#^\.\\" Index: (\S+)#) {
54 # remove all directories just to be more secure
55 my $f;
56 ($f = $1) =~ s#.*/##;
57 &print_index($f, \@indi, $imacro);
58 @indi = ();
59 $imacro = '';
60 next;
61 }
62 my $x;
63 if (($x) = m#^\.\\" IND (.+)#) {
64 $x =~ s#\\##g;
65 my @x = split(/\t/, $x);
66 grep(s/\s+$//, @x);
67 push(@indi, join("\t", @x));
68 next;
69 }
70 if (m#^\.\\" PIC id (\d+)#) {
71 %cur = ('id', $1);
72 next;
73 }
74 if (m#^\.\\" PIC file (\S+)#) {
75 &psbb($1);
76 &ps_calc($1);
77 next;
78 }
79 if (m#^\.\\" PIC (\w+)\s+(\S+)#) {
80 eval "\$cur{'$1'} = '$2'";
81 next;
82 }
83 s#\\ \\ $##;
84 push(@out, $_);
85}
86close(MACRO);
87
88
89if ($rfilename) {
90 push(@out, ".nr pict*max-height $max_height\n") if defined $max_height;
91 push(@out, ".nr pict*max-width $max_width\n") if defined $max_width;
92
93 open(OUT, ">$rfilename") || "create $rfilename:$!";
94 print OUT '.\" references', "\n";
95 my $i;
96 for $i (@out) {
97 print OUT $i;
98 }
99 close(OUT);
100}
101
102exit 0 if $no_exec;
103exit system($run_macro);
104
105sub print_index {
106 my ($f, $ind, $macro) = @_;
107
108 open(OUT, ">$f") || "create $f:$!";
109 my $i;
110 for $i (sort @$ind) {
111 if ($macro) {
112 $i = '.'.$macro.' "'.join('" "', split(/\t/, $i)).'"';
113 }
114 print OUT "$i\n";
115 }
116 close(OUT);
117}
118
119sub ps_calc {
120 my ($f) = @_;
121
122 my $w = abs($cur{'llx'}-$cur{'urx'});
123 my $h = abs($cur{'lly'}-$cur{'ury'});
124 $max_width = $w if $w > $max_width;
125 $max_height = $h if $h > $max_height;
126
127 my $id = $cur{'id'};
128 push(@out, ".ds pict*file!$id $f\n");
129 push(@out, ".ds pict*id!$f $id\n");
130 push(@out, ".nr pict*llx!$id $cur{'llx'}\n");
131 push(@out, ".nr pict*lly!$id $cur{'lly'}\n");
132 push(@out, ".nr pict*urx!$id $cur{'urx'}\n");
133 push(@out, ".nr pict*ury!$id $cur{'ury'}\n");
134 push(@out, ".nr pict*w!$id $w\n");
135 push(@out, ".nr pict*h!$id $h\n");
136}
137
138
139sub psbb {
140 my ($f) = @_;
141
142 unless (open(IN, $f)) {
143 print STDERR "Warning: Postscript file $f:$!";
144 next;
145 }
146 while(<IN>) {
147 if (/^%%BoundingBox:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/) {
148 $cur{'llx'} = $1;
149 $cur{'lly'} = $2;
150 $cur{'urx'} = $3;
151 $cur{'ury'} = $4;
152 }
153 }
154 close(IN);
155}