Merge branch '3205_eta'
[midnight-commander.git] / maint / htagsfix
blobc0db95e20457682989e7fa4efa8fe41afeeb9c3c
1 #!/usr/bin/env ruby
4 # Fixes htags' output so that files have fixed names. E.g., S/542.html -> D/whatever.c.h.
6 # It addresses the following problem:
8 # "Can htags create permanent addresses?"
9 # http://lists.gnu.org/archive/html/help-global/2015-11/msg00002.html
12 require 'fileutils'
13 require 'pp'
15 Encoding.default_external = "BINARY"
17 $base = '.' # Where the HTML is stored.
18 $verbose = false
19 $debug = false
20 $create_subdirs = false # Experimental feature. Doesn't really work.
22 # Bonus: highlight the target line.
23 $css = "
24 a:target {
25 position: absolute;
26 left: 0;
27 height: 1.35em;
28 width: 100%;
29 background: yellow;
30 opacity: .5;
31 z-index: -1000;
36 # Computes pretty names for files:
38 # '.../S/456.html' => 'S/modules/tty.c.html'
40 def prettyname(full_path, prefix, kind, nid, ext)
41 gist = nid
42 start = IO.read(full_path, 1024)
43 if start =~ /<title>(.*?)<\/title>/ then
44 gist = $1
45 gist.gsub!(%r{/+$}, '') # remove trailing '/'s.
46 if not $create_subdirs then
47 gist.gsub!('/', '--')
48 end
49 gist.gsub!(%r{[^a-zA-Z0-9_.,/-]}, '-') # clean special characters.
50 end
51 return kind + '/' + gist + ext
52 end
54 class Counter
55 class << self
56 def init(total)
57 @total = total
58 end
59 def reset()
60 @count = 0
61 end
62 def report()
63 print "[#{@count}/#{@total}]\r"
64 @count += 1
65 end
66 def finish()
67 puts
68 end
69 end
70 end
73 # Returns a table explaining how to rename the files. E.g.:
75 # {
76 # 'S/456.html' => 'S/modules/tty.c.html'
77 # ...
78 # }
80 def build_cnv_tbl()
81 Counter.reset()
82 cnv = {}
83 Dir[$base + '/{[A-Z],files}/*.html'].each do |full_path|
84 #p full_path
85 if full_path =~ /(.*)\/((\w+)\/(\d+)(\.\w+))$/ then
86 prefix = $1 # "/home/joe/.../HTML"
87 path = $2 # "S/323.html"
88 kind = $3 # "S"
89 nid = $4 # "323"
90 ext = $5 # ".html"
91 pretty = prettyname(full_path, prefix, kind, nid, ext)
92 cnv[path] = pretty
93 end
94 Counter.report()
95 end
96 Counter.finish()
97 return cnv
98 end
101 # Make all the substiutions inside the files:
103 # <a href='../S/456.html'> --> <a href='../S/modules/tty.c.html'>
104 # ...
106 def mksub(cnv)
107 Counter.reset()
108 Dir[$base + '/**/*.html'].each do |path|
109 kind = path[$base.length .. -1][/\w+/]
110 text = IO.read(path)
111 fixed = text.gsub(/(<a href='(?:..\/)?)([^'#]+)/) do |a|
112 prefix = $1
113 target = $2
114 if cnv[target] then
115 target = cnv[target]
116 elsif cnv[kind + '/' + target] then
117 # This is a relative link of the form: href='456.html'
118 if cnv[kind + '/' + target].match /\/(.*)/ # converts "s/whatever.html" to "whatever.html"
119 target = $1
122 prefix + target
125 # Fix a problem in Opera, where empty lines are squashed.
126 fixed.gsub!(%r{(<a id='L\d+' name='L\d+'></a>)\n}, "\\1 \n")
128 if text != fixed then
129 IO.write(path, fixed)
130 puts(path + " modified") if $debug
132 Counter.report()
134 Counter.finish()
138 # Rename the files.
140 def rename(cnv)
141 Counter.reset()
142 cnv.each do |a, b|
143 src = $base + '/' + a
144 trg = $base + '/' + b
145 if $create_subdirs then
146 FileUtils.mkdir_p(File.dirname(trg))
148 File.rename(src, trg)
149 Counter.report()
151 Counter.finish()
154 def better_css(css_path)
155 text = IO.read(css_path)
156 IO.write(css_path, text + $css)
159 def main()
160 if not File.exists?($base + '/help.html') then
161 $base += '/HTML'
162 if not File.exists?($base + '/help.html') then
163 puts "Error: This doesn't look like htags' output directory."
164 exit(1)
167 Counter.init( Dir[$base + '/**/*.html'].length )
168 puts "Figuring out pretty names..."
169 cnv = build_cnv_tbl()
170 pp cnv if $verbose
171 puts "Updating links in files..."
172 mksub(cnv)
173 puts "Renaming files..."
174 rename(cnv)
175 puts "Enhancing the css..."
176 better_css($base + '/style.css')
177 puts "Done."
180 main()