]> git.proxmox.com Git - pve-docs.git/blame - scan-adoc-refs
pve-docs-mediawiki-import: fix syntax error
[pve-docs.git] / scan-adoc-refs
CommitLineData
aa99b349
DM
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use IO::File;
6use JSON;
7
8use Data::Dumper;
9
10my $environments = {
11 default => 1,
12 wiki => 1,
13 manvolnum => 1,
14 pvelogo => 0, # ignore
15};
16
17my $resolve_skip_files = {
18 default => {},
19 wiki => { 'pve-admin-guide.adoc' => 1 },
20 manvolnum => {},
21};
22
23my $fileinfo = {};
24
25my $start_env = [];
26foreach my $e (keys %$environments) {
27 push @$start_env, $e if $environments->{$e};
28}
29
30my $env_stack = [$start_env];
31my $env_name_stack = [];
32
33sub reset_environment_stack {
34 $env_stack = [$start_env];
35 $env_name_stack = [];
36}
37
38sub push_environment {
39 my ($env, $not) = @_;
40
41 die "undefined environment '$env'\n" if !defined($environments->{$env});
42
835dd63b 43 # FIXME: this seems wrong (nested env?)?
aa99b349 44 return if !$environments->{$env}; # do not track
74b0334e 45
aa99b349
DM
46 if ($not) {
47 my $new_env = [];
48 foreach my $e (@{$env_stack->[-1]}) {
49 if ($e ne $env) {
50 push @$new_env, $e;
51 }
52 }
53 die "empty environment" if !scalar($new_env);
54 push @$env_stack, $new_env;
55 } else {
56 push @$env_stack, [$env];
57 }
74b0334e 58
aa99b349
DM
59 push @$env_name_stack, $env;
60}
61
62sub pop_environment {
63 my ($env) = @_;
64
65 die "undefined environment '$env'\n" if !defined($environments->{$env});
74b0334e 66
aa99b349
DM
67 return if !$environments->{$env}; # do not track
68
69 pop @$env_stack;
70 my $res = pop @$env_name_stack;
74b0334e 71
aa99b349
DM
72 die "environment missmatch ($res != $env)\n" if $res ne $env;
73}
74
75sub register_include {
76 my ($filename, $include_filename, $env_list) = @_;
77
78 return if $include_filename !~ m/\.adoc$/; # skip attributes.txt
79
80 foreach my $e (@$env_list) {
81 $fileinfo->{include}->{$e}->{$filename}->{$include_filename} = 1;
82 }
83}
84
85sub register_blockid {
45930831 86 my ($filename, $blockid, $reftext, $env_list) = @_;
aa99b349
DM
87
88 foreach my $e (@$env_list) {
89 my $fn = $fileinfo->{blockid}->{$e}->{$blockid};
74b0334e 90 die "blockid '$blockid' already defined in $fn"
aa99b349
DM
91 if defined($fn);
92 $fileinfo->{blockid}->{$e}->{$blockid} = $filename;
45930831
DM
93 $fileinfo->{reftext}->{$e}->{$blockid} = $reftext
94 if defined($reftext);
aa99b349
DM
95 }
96}
97
98sub scan_adoc_file {
99 my ($filename) = @_;
100
101 reset_environment_stack();
74b0334e 102
aa99b349
DM
103 # print "SCAN $filename\n";
104
105 my $fh = IO::File->new("$filename", "r") or
106 die "unable to open file '$filename' - $!\n";
107
108 my $env_last_line = {};
74b0334e 109
aa99b349
DM
110 while (defined (my $line = <$fh>)) {
111 if ($line =~ m/^if(n?)def::(\S+)\[(.*)\]\s*$/) {
74b0334e 112 my ($not, $env, $text) = ($1, $2, $3);
aa99b349
DM
113 die "unsuported ifdef usage - implement me" if $text;
114 push_environment($env, $not);
115 next;
116 } elsif ($line =~ m/^endif::(\S+)\[(.*)\]\s*$/) {
117 my ($env, $text) = ($1, $2);
118 die "unsuported ifdef usage - implement me" if $text;
119 pop_environment($env);
120 next;
121 } elsif ($line =~ m/^include::(\S+)\[.*\]\s*$/) {
122 register_include($filename, $1, $env_stack->[-1]);
123 next;
124 }
125
126 # try to detect titles
127 foreach my $e (@{$env_stack->[-1]}) {
128 my $title = $fileinfo->{titles}->{$e}->{$filename};
129 next if defined($title);
130
131 if (($line =~ m/^=====+/) || ($line =~ m/^-----+/)) {
132 $fileinfo->{titles}->{$e}->{$filename} = $env_last_line->{$e};
133 }
134 $env_last_line->{$e} = $line;
135 chomp $env_last_line->{$e};
136 }
74b0334e 137
aa99b349 138 # fixme: also scan <<>>
74b0334e 139
aa99b349
DM
140 while ($line =~ m/xref:([^\s\[\]]+)\[([^\]]*)\]/g) {
141 # print "$filename xref:$1 [$2]\n";
142 }
143
144 if ($line =~ m/^\[\[(.*)\]\]\s*$/) {
145 my $blockid = $1;
146 die "implement me" if $blockid =~m/,/;
45930831
DM
147 my $reftext = '';
148 register_blockid($filename, $blockid, $reftext, $env_stack->[-1]);
aa99b349 149 }
a0ba8b4c
DM
150 # fixme: "anchor:"
151 # bibliography anchors
152 if ($line =~ m/\[\[\[([^\]]*)\]\]\]/) {
153 my $blockid = $1;
154 die "implement me" if $blockid =~m/,/;
45930831 155 register_blockid($filename, $blockid, "&#91;$blockid&#93;", $env_stack->[-1]);
a0ba8b4c 156 }
74b0334e 157 }
aa99b349
DM
158}
159
160my $scanned_files = {};
161while (my $filename = shift) {
162 next if $filename !~ m/\.adoc$/; # skip attributes.txt
163 next if $scanned_files->{$filename};
164
165 scan_adoc_file($filename);
166 $scanned_files->{$filename} = 1;
167}
168
169sub resolve_link_target {
170 my ($env, $filename) = @_;
171
172 my $include_hash = $fileinfo->{include}->{$env};
173
174 my $repeat = 1;
175
176 while ($repeat) {
177 $repeat = 0;
178 foreach my $fn (keys %$include_hash) {
179 next if $resolve_skip_files->{$env}->{$fn};
180 if ($include_hash->{$fn}->{$filename}) {
181 $filename = $fn;
182 $repeat = 1;
183 last;
184 }
185 }
186 }
74b0334e 187
aa99b349
DM
188 return $filename;
189}
190
191# now resolve blockids
192foreach my $e (@$start_env) {
193 my $blockid_hash = $fileinfo->{blockid}->{$e};
194 foreach my $blockid (keys %$blockid_hash) {
195 my $fn = resolve_link_target($e, $blockid_hash->{$blockid});
196 if ($e eq 'wiki') {
197 my $title = $fileinfo->{titles}->{$e}->{$fn};
aa99b349 198 $title =~ s/\{pve\}/Proxmox VE/g;
0e1bf0da 199 $title =~ s/\s/_/g;
aa99b349
DM
200 die "found not title for '$fn' in env '$e'" if !$title;
201 $fileinfo->{blockid_target}->{$e}->{$blockid} = "link:/wiki/$title#$blockid";
202 } else {
203 $fileinfo->{blockid_target}->{$e}->{$blockid} = $fn;
204 }
205 }
206}
207
208
209print to_json($fileinfo, { pretty => 1 } );