require 'find' require 'fileutils' class Wrongdoc::Final include Wrongdoc::ParseXML include Wrongdoc::NewsAtom SE_URL = 'http://kernel.org/pub/software/scm/git/docs/git-send-email.html' def run Find.find('doc') { |path| /\.html\z/ =~ path and fix(path) } FileUtils.rm_rf('doc/js') news_atom end def initialize(opts, git_tag = nil) @cgit_uri = URI.parse(opts[:cgit_url]) @rdoc_uri = URI.parse(opts[:rdoc_url]) ml_url = opts[:ml_url] and @ml_uri = URI.parse(ml_url) @public_email = opts[:public_email] or warn ":public_email unset" @private_email = opts[:private_email] or warn ":private_email unset" @git_tag = git_tag end # returns a cgit URI for the given +path+ and +lineno+ def path_uri(path, lineno) uri = @cgit_uri.dup uri.path += "/tree/#{URI.escape(path)}" uri.fragment = "n#{lineno}" uri.query = "id=#{URI.escape(@git_tag)}" if @git_tag uri end # delete all the stuff that offends us def killkillkill!(doc) unlink = proc { |node| node.unlink } # JavaScript is dangerous doc.search("script").each(&unlink) # if your project's big enough to need JS search, it's too bloated doc.search('span.search-toggle').each(&unlink) doc.search('form').each(&unlink) # remove W3C validator link, we use tidy instead doc.search('div#validator-badges p').each { |x| /Validate/i =~ x.content and x.unlink } # this shows up in browsers that don't do stylesheets doc.search('div#no-class-search-results').each(&unlink) end # since we killed off JavaScript, viewing source isn't possible with # RDoc anymore, so link people to the web source viewer def source_linkify!(doc) doc.search('div.method-detail').each { |mdetail| path = lineno = nil mdetail.search('div.method-source-code').each { |src| src.search('span.ruby-comment').each { |x| if x.content =~ /File\s+(\S+),\s+line\s+(\d+)/s path, lineno = $1, $2 end } src.unlink if path && lineno } mdetail.search('span.method-click-advice').each { |x| x.content = '' a = Nokogiri::XML::Node.new('a', doc) a['href'] = (path && lineno ? path_uri(path, lineno) : @cgit_uri).to_s a.content = 'view method source' x.add_child(a) } } end # Don't give the original Darkfish a bad name, and advertise ourselves :) def advertise!(doc) doc.search('div#validator-badges p small').each { |x| if /\AGenerated/ =~ x.content first = x.children.first first.content = first.content.gsub(/\AG/, "Originally g") last = x.children.last last.content = "#{last.content}, modified by " a = Nokogiri::XML::Node.new('a', doc) a["href"] = "http://bogomips.org/wrongdoc/" a.content = "wrongdoc" last.add_next_sibling(a) @public_email && @private_email or return txt = <<-EOF We love to hear from you!
Email patches (with git send-email), pull requests, questions, bug reports, suggestions, etc. to us publically at: #@public_email
EOF case @public_email when /@librelist\.(?:com|org)\z/ txt << <<-EOF To subscribe, just send any email to #@public_email, and respond to the automated confirmation message. EOF when /\A(.+)@(rubyforge\.org)\z/ # Mailman requests = "#$1-request@#$2" txt << <<-EOF No subscription to the mailing list is necessary, just let us know to Cc: you if you're unsubscribed.
To subscribe, email #{requests} with \"subscribe\" in the Subject and respond to the automated confirmation message. EOF when /public/ txt << <<-EOF This is a public-inbox with no sign up.
Please Cc: all recipients on replies, as not everybody subscribes with ssoma.
See #@ml_uri for archives and more information. EOF end txt << <<-EOF
Do not waste bandwidth with HTML, HTML mail will not be read.
Quote only parts you're responding to and do not top post.
For sensitive topics, email us privately at: #@private_email EOF para = Nokogiri::XML.fragment(txt) last.parent.parent.add_next_sibling(para) end } end def fix(file) File.open(file, "a+") do |fp| buf = process(fp.read) fp.truncate 0 fp.write buf end end # the main entry point, this does all the require processing on any # given String buffer. def process(str) doc = parse_xml(str) killkillkill!(doc) source_linkify!(doc) advertise!(doc) doc.to_xhtml(:indent => 0) end end