wrongdoc.git  about / heads / tags
RDoc done right (IMNSHO)
blob b7e72e2bb3d98c26a86cd10de7fbe5388bf61cf1 5281 bytes (raw)
$ git show HEAD:lib/wrongdoc/final.rb	# shows this blob on the CLI

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
 
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_uri = URI.parse(opts[: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!<br />
        Email patches (with <a href="#{SE_URL}">git send-email</a>),
        pull requests, questions, bug reports, suggestions, etc.
        to us publically at:
        <a href="mailto:#@public_email">#@public_email</a><br />
        EOF

        case @public_email
        when /@librelist\.(?:com|org)\z/
          txt << <<-EOF
          To subscribe, just send any email to
          <a href="mailto:#@public_email">#@public_email</a>,
          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 <b>Cc:</b> you if you're unsubscribed.<br />
          To subscribe, email
          <a href="mailto:#{requests}?subject=subscribe">#{requests}</a>
          with \"subscribe\" in the Subject
          and respond to the automated confirmation message.
          EOF
        when /public/
          txt << <<-EOF
          This is a <a href="http://public-inbox.org/">public-inbox</a> with no sign up.<br />
          Please Cc: all recipients on replies, as not everybody subscribes
          with <a href="http://ssoma.public-inbox.org/">ssoma</a>.<br />
          See <a href="#@ml_uri">#@ml_uri</a> for archives and more information.
          EOF
        end

        txt << <<-EOF
        <br />
        <b>
        Do not waste bandwidth with HTML, HTML mail will not be read.<br />
        Quote only parts you're responding to and do not
        <a href="http://catb.org/jargon/html/T/top-post.html">top post</a>.
        <br />
        </b>
        For sensitive topics, email us privately at:
        <a href="mailto:#@private_email">#@private_email</a>
        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

git clone https://yhbt.net/wrongdoc.git