123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #!/usr/bin/env ruby
- #
- # Fixes htags' output so that files have fixed names. E.g., S/542.html -> D/whatever.c.h.
- #
- # It addresses the following problem:
- #
- # "Can htags create permanent addresses?"
- # http://lists.gnu.org/archive/html/help-global/2015-11/msg00002.html
- #
- require 'fileutils'
- require 'pp'
- Encoding.default_external = "BINARY"
- $base = '.' # Where the HTML is stored.
- $verbose = false
- $debug = false
- $create_subdirs = false # Experimental feature. Doesn't really work.
- # Bonus: highlight the target line.
- $css = "
- a:target {
- position: absolute;
- left: 0;
- height: 1.35em;
- width: 100%;
- background: yellow;
- opacity: .5;
- z-index: -1000;
- }
- "
- #
- # Computes pretty names for files:
- #
- # '.../S/456.html' => 'S/modules/tty.c.html'
- #
- def prettyname(full_path, prefix, kind, nid, ext)
- gist = nid
- start = IO.read(full_path, 1024)
- if start =~ /<title>(.*?)<\/title>/ then
- gist = $1
- gist.gsub!(%r{/+$}, '') # remove trailing '/'s.
- if not $create_subdirs then
- gist.gsub!('/', '--')
- end
- gist.gsub!(%r{[^a-zA-Z0-9_.,/-]}, '-') # clean special characters.
- end
- return kind + '/' + gist + ext
- end
- class Counter
- class << self
- def init(total)
- @total = total
- end
- def reset()
- @count = 0
- end
- def report()
- print "[#{@count}/#{@total}]\r"
- @count += 1
- end
- def finish()
- puts
- end
- end
- end
- #
- # Returns a table explaining how to rename the files. E.g.:
- #
- # {
- # 'S/456.html' => 'S/modules/tty.c.html'
- # ...
- # }
- #
- def build_cnv_tbl()
- Counter.reset()
- cnv = {}
- Dir[$base + '/{[A-Z],files}/*.html'].each do |full_path|
- #p full_path
- if full_path =~ /(.*)\/((\w+)\/(\d+)(\.\w+))$/ then
- prefix = $1 # "/home/joe/.../HTML"
- path = $2 # "S/323.html"
- kind = $3 # "S"
- nid = $4 # "323"
- ext = $5 # ".html"
- pretty = prettyname(full_path, prefix, kind, nid, ext)
- cnv[path] = pretty
- end
- Counter.report()
- end
- Counter.finish()
- return cnv
- end
- #
- # Make all the substiutions inside the files:
- #
- # <a href='../S/456.html'> --> <a href='../S/modules/tty.c.html'>
- # ...
- #
- def mksub(cnv)
- Counter.reset()
- Dir[$base + '/**/*.html'].each do |path|
- kind = path[$base.length .. -1][/\w+/]
- text = IO.read(path)
- fixed = text.gsub(/(<a href='(?:..\/)?)([^'#]+)/) do |a|
- prefix = $1
- target = $2
- if cnv[target] then
- target = cnv[target]
- elsif cnv[kind + '/' + target] then
- # This is a relative link of the form: href='456.html'
- if cnv[kind + '/' + target].match /\/(.*)/ # converts "s/whatever.html" to "whatever.html"
- target = $1
- end
- end
- prefix + target
- end
- # Fix a problem in Opera, where empty lines are squashed.
- fixed.gsub!(%r{(<a id='L\d+' name='L\d+'></a>)\n}, "\\1 \n")
- if text != fixed then
- IO.write(path, fixed)
- puts(path + " modified") if $debug
- end
- Counter.report()
- end
- Counter.finish()
- end
- #
- # Rename the files.
- #
- def rename(cnv)
- Counter.reset()
- cnv.each do |a, b|
- src = $base + '/' + a
- trg = $base + '/' + b
- if $create_subdirs then
- FileUtils.mkdir_p(File.dirname(trg))
- end
- File.rename(src, trg)
- Counter.report()
- end
- Counter.finish()
- end
- def better_css(css_path)
- text = IO.read(css_path)
- IO.write(css_path, text + $css)
- end
- def main()
- if not File.exists?($base + '/help.html') then
- $base += '/HTML'
- if not File.exists?($base + '/help.html') then
- puts "Error: This doesn't look like htags' output directory."
- exit(1)
- end
- end
- Counter.init( Dir[$base + '/**/*.html'].length )
- puts "Figuring out pretty names..."
- cnv = build_cnv_tbl()
- pp cnv if $verbose
- puts "Updating links in files..."
- mksub(cnv)
- puts "Renaming files..."
- rename(cnv)
- puts "Enhancing the css..."
- better_css($base + '/style.css')
- puts "Done."
- end
- main()
|