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