1 | #!/usr/bin/perl -p |
1 | #!/usr/bin/perl |
2 | |
2 | |
3 | use Pod::Tree; |
3 | use Pod::Tree; |
4 | |
4 | |
5 | sub escape_texi($) { |
5 | sub escape_texi($) { |
6 | local $_ = shift; |
6 | local $_ = shift; |
… | |
… | |
9 | $_; |
9 | $_; |
10 | } |
10 | } |
11 | |
11 | |
12 | sub example { |
12 | sub example { |
13 | my $text = $_[0]; |
13 | my $text = $_[0]; |
14 | print "\n\n\@example\n"; |
|
|
15 | $text =~ s/\n+$//; |
14 | $text =~ s/\n+$//; |
16 | $text =~ s/([\@\{\}])/@$1/g; |
15 | $text =~ s/([\@\{\}])/\@$1/g; |
17 | print $text; |
16 | |
|
|
17 | "\n\n\@example\n" |
|
|
18 | . $text |
18 | print "\n\@end example\n\n"; |
19 | . "\n\@end example\n\n"; |
19 | } |
20 | } |
20 | |
21 | |
21 | while (<>) { |
22 | my @nodes; # nodelist |
22 | if (/^\@c INCLUDE-(\S+) (\S+)/) { |
23 | my @ctx; # curstack |
23 | my $type = $1; |
|
|
24 | my $name = $2; |
|
|
25 | my $path = $2; |
|
|
26 | |
24 | |
27 | $name =~ s/\.(\d)$/($1)/; |
25 | sub out { |
28 | |
26 | $ctx[-1]{out} .= join "", @_; |
29 | print "\@chapter $name\n\n"; |
|
|
30 | |
|
|
31 | if ($type eq "POD") { |
|
|
32 | open my $x, "<$path.pod" or die "$path.pod: $!"; |
|
|
33 | my $data = do { local $/; <$x> }; |
|
|
34 | |
|
|
35 | my $pod = new Pod::Tree; |
|
|
36 | $pod->load_string($data); |
|
|
37 | |
|
|
38 | my $walker; $walker = sub { |
|
|
39 | my $n = $_[0]; |
|
|
40 | if ($n->is_code) { |
|
|
41 | # nop |
|
|
42 | } elsif ($n->is_link) { |
|
|
43 | my $target = $n->get_target; |
|
|
44 | my $page = $target->get_page; |
|
|
45 | my $section = $target->get_section; |
|
|
46 | |
|
|
47 | #print "<b>"; |
|
|
48 | $walker->($_) for @{$n->get_children}; |
|
|
49 | #print "</b>"; |
|
|
50 | } elsif ($n->is_text) { |
|
|
51 | print escape_texi $n->get_text; |
|
|
52 | } elsif ($n->is_verbatim) { |
|
|
53 | example $n->get_text; |
|
|
54 | } elsif ($n->is_sequence) { |
|
|
55 | if ($n->get_letter eq "C") { |
|
|
56 | print "\@t{"; |
|
|
57 | $walker->($_) for @{$n->get_children}; |
|
|
58 | print "}"; |
|
|
59 | } elsif ($n->get_letter eq "B") { |
|
|
60 | print "\@strong{"; |
|
|
61 | $walker->($_) for @{$n->get_children}; |
|
|
62 | print "}"; |
|
|
63 | } elsif ($n->get_letter eq "I" or $n->get_letter eq "F") { |
|
|
64 | print "\@emph{"; |
|
|
65 | $walker->($_) for @{$n->get_children}; |
|
|
66 | print "}"; |
|
|
67 | } else { |
|
|
68 | # S would mean to use nbsp |
|
|
69 | $walker->($_) for @{$n->get_children}; |
|
|
70 | } |
|
|
71 | } elsif ($n->is_command) { |
|
|
72 | if ($n->is_c_head1) { |
|
|
73 | print "\n\@subsection "; |
|
|
74 | $walker->($_) for @{$n->get_children}; |
|
|
75 | print "\n"; |
|
|
76 | } elsif ($n->is_c_head2) { |
|
|
77 | print "\n\n\@subsubsection "; |
|
|
78 | $walker->($_) for @{$n->get_children}; |
|
|
79 | print "\n"; |
|
|
80 | } else { |
|
|
81 | # nop? |
|
|
82 | } |
|
|
83 | } elsif ($n->is_ordinary) { |
|
|
84 | $walker->($_) for @{$n->get_children}; |
|
|
85 | print "\@refill\n"; |
|
|
86 | } elsif ($n->is_root) { |
|
|
87 | $walker->($_) for @{$n->get_children}; |
|
|
88 | } elsif ($n->is_list) { |
|
|
89 | print "\n\n\@itemize\n"; |
|
|
90 | $walker->($_) for @{$n->get_children}; |
|
|
91 | print "\@end itemize\n\n"; |
|
|
92 | } elsif ($n->is_item) { |
|
|
93 | print "\n\n\@item\n"; |
|
|
94 | print "\@b{"; |
|
|
95 | $walker->($_) for @{$n->get_children}; |
|
|
96 | print "}\n\n"; |
|
|
97 | $walker->($_) for @{$n->get_siblings}; |
|
|
98 | } else { |
|
|
99 | die "UNKNOWN NODE $_[0]{type}<br/>"; |
|
|
100 | $walker->($_) for @{$n->get_children}; |
|
|
101 | } |
|
|
102 | }; |
|
|
103 | |
|
|
104 | $walker->($pod->get_root); |
|
|
105 | } elsif ($type eq "TEXT") { |
|
|
106 | open my $x, "<$path" or die "$path: $!"; |
|
|
107 | my $data = do { local $/; <$x> }; |
|
|
108 | |
|
|
109 | print $data; |
|
|
110 | } elsif ($type eq "EXAMPLE") { |
|
|
111 | open my $x, "<$path" or die "$path: $!"; |
|
|
112 | my $data = do { local $/; <$x> }; |
|
|
113 | |
|
|
114 | example $data; |
|
|
115 | } |
|
|
116 | } else { |
|
|
117 | print; |
|
|
118 | } |
|
|
119 | } |
27 | } |
120 | |
28 | |
|
|
29 | sub parse_pod { |
|
|
30 | my ($data) = @_; |
|
|
31 | local $out; |
|
|
32 | |
|
|
33 | my $pod = new Pod::Tree; |
|
|
34 | $pod->load_string($data); |
|
|
35 | |
|
|
36 | my $walker; $walker = sub { |
|
|
37 | my $n = $_[0]; |
|
|
38 | if ($n->is_code) { |
|
|
39 | # nop |
|
|
40 | } elsif ($n->is_link) { |
|
|
41 | my $target = $n->get_target; |
|
|
42 | my $page = $target->get_page; |
|
|
43 | my $section = $target->get_section; |
|
|
44 | |
|
|
45 | $walker->($_) for @{$n->get_children}; |
|
|
46 | } elsif ($n->is_text) { |
|
|
47 | out escape_texi $n->get_text; |
|
|
48 | } elsif ($n->is_verbatim) { |
|
|
49 | out example $n->get_text; |
|
|
50 | } elsif ($n->is_sequence) { |
|
|
51 | if ($n->get_letter eq "C") { |
|
|
52 | out "\@t{"; |
|
|
53 | $walker->($_) for @{$n->get_children}; |
|
|
54 | out "}"; |
|
|
55 | } elsif ($n->get_letter eq "B") { |
|
|
56 | out "\@strong{"; |
|
|
57 | $walker->($_) for @{$n->get_children}; |
|
|
58 | out "}"; |
|
|
59 | } elsif ($n->get_letter eq "I" or $n->get_letter eq "F") { |
|
|
60 | out "\@emph{"; |
|
|
61 | $walker->($_) for @{$n->get_children}; |
|
|
62 | out "}"; |
|
|
63 | } else { |
|
|
64 | # S would mean to use nbsp |
|
|
65 | $walker->($_) for @{$n->get_children}; |
|
|
66 | } |
|
|
67 | } elsif ($n->is_command) { |
|
|
68 | if ($n->is_c_head1) { |
|
|
69 | out "\n\@section "; |
|
|
70 | $walker->($_) for @{$n->get_children}; |
|
|
71 | out "\n"; |
|
|
72 | } elsif ($n->is_c_head2) { |
|
|
73 | out "\n\n\@subsection "; |
|
|
74 | $walker->($_) for @{$n->get_children}; |
|
|
75 | out "\n"; |
|
|
76 | } else { |
|
|
77 | # nop? |
|
|
78 | } |
|
|
79 | } elsif ($n->is_ordinary) { |
|
|
80 | $walker->($_) for @{$n->get_children}; |
|
|
81 | out "\@refill\n"; |
|
|
82 | } elsif ($n->is_root) { |
|
|
83 | $walker->($_) for @{$n->get_children}; |
|
|
84 | } elsif ($n->is_list) { |
|
|
85 | out "\n\n\@itemize\n"; |
|
|
86 | $walker->($_) for @{$n->get_children}; |
|
|
87 | out "\@end itemize\n\n"; |
|
|
88 | } elsif ($n->is_item) { |
|
|
89 | out "\n\n\@item\n"; |
|
|
90 | out "\@b{"; |
|
|
91 | $walker->($_) for @{$n->get_children}; |
|
|
92 | out "}\n\n"; |
|
|
93 | $walker->($_) for @{$n->get_siblings}; |
|
|
94 | } elsif ($n->is_for) { |
|
|
95 | my $text = $n->get_text; |
|
|
96 | |
|
|
97 | if ($n->get_command eq "begin") { |
|
|
98 | if ($n->{brackets}[0] =~ / header/) { |
|
|
99 | $header = $text; |
|
|
100 | } elsif ($n->{brackets}[0] =~ / footer/) { |
|
|
101 | $footer = $text; |
|
|
102 | } else { |
|
|
103 | out $text; |
|
|
104 | } |
|
|
105 | |
|
|
106 | } elsif ($text =~ /^menu-begin/) { |
|
|
107 | out "\n\@menu\n"; |
|
|
108 | |
|
|
109 | push @ctx, {}; # dummy node |
|
|
110 | |
|
|
111 | } elsif ($text =~ /^menu-item (.*?)::\s+(.*)/) { |
|
|
112 | my ($name, $desc) = ($1, $2); |
|
|
113 | |
|
|
114 | push @{ $ctx[-2]{menu} }, [$name, $desc]; |
|
|
115 | $ctx[-2]{width} = length $name if $ctx[-2]{width} < length $name; |
|
|
116 | |
|
|
117 | my $ctx = { |
|
|
118 | name => $name, |
|
|
119 | up => $ctx[-2]{name}, |
|
|
120 | }; |
|
|
121 | push @nodes, $ctx; |
|
|
122 | $ctx[-1] = $ctx; |
|
|
123 | |
|
|
124 | } elsif ($text =~ /^menu-end/) { |
|
|
125 | pop @ctx; |
|
|
126 | |
|
|
127 | for (@{ $ctx[-1]{menu} }) { |
|
|
128 | out sprintf "* %-*s %s\n", $ctx[-1]{width} + 2, "$_->[0]::", $_->[1]; |
|
|
129 | } |
|
|
130 | |
|
|
131 | out "\@end menu\n"; |
|
|
132 | |
|
|
133 | } elsif ($text =~ /^include (\S+) (.*)/) { |
|
|
134 | my ($type, $path) = ($1, $2); |
|
|
135 | |
|
|
136 | open my $x, "<$path" or die "$path: $!"; |
|
|
137 | my $data = do { local $/; <$x> }; |
|
|
138 | |
|
|
139 | if ($type eq "pod") { |
|
|
140 | out parse_pod ($data); |
|
|
141 | } elsif ($type eq "text") { |
|
|
142 | out $data; |
|
|
143 | } elsif ($type eq "example") { |
|
|
144 | out example $data; |
|
|
145 | } |
|
|
146 | |
|
|
147 | } else { |
|
|
148 | die "UNKNOWN for command <$text>\n"; |
|
|
149 | } |
|
|
150 | |
|
|
151 | } else { |
|
|
152 | die "UNKNOWN NODE $_[0]{type}\n"; |
|
|
153 | $walker->($_) for @{$n->get_children}; |
|
|
154 | } |
|
|
155 | }; |
|
|
156 | |
|
|
157 | $walker->($pod->get_root); |
|
|
158 | } |
|
|
159 | |
|
|
160 | @ctx = @nodes = { |
|
|
161 | up => "(dir)", |
|
|
162 | name => "Top", |
|
|
163 | }; |
|
|
164 | |
|
|
165 | parse_pod do { local $/; <> }; |
|
|
166 | |
|
|
167 | print $header; |
|
|
168 | |
|
|
169 | for (0 .. $#nodes) { |
|
|
170 | my $node = $nodes[$_]; |
|
|
171 | my $prev = $_ > 0 ? $nodes[$_-1] : undef; |
|
|
172 | my $next = $nodes[$_+1]; |
|
|
173 | |
|
|
174 | print "\@node $node->{name},$next->{name},$prev->{name},$node->{up}\n\n", |
|
|
175 | "\@chapter $node->{name}\n", |
|
|
176 | "$node->{out}\n\n"; |
|
|
177 | } |
|
|
178 | |
|
|
179 | print $footer; |
|
|
180 | |