Commit 1e6de51b authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Merge branch 'master' into doc-tags

parents d24ea3ff 407b24c3
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
module JsDuck

  # Transforms in-page links so they won't break docs app #!-navigation.
  #
  # For example a link to "#automation" in testing guide will be
  # replaced with "#!/guide/testing-section-automation" and the link
  # target ID will be transformed into "testing-section-automation".
  class GuideAnchors

    def self.transform(html, guide_name)
      html.gsub(/(<a\s+(?:[^<>]*\s+)?href=['"]#)([^!].*?)(['"])/i) do |m|
        "#{$1}!/guide/#{guide_name}-section-#{$2}#{$3}"

      end.gsub(/(<a\s+(?:[^<>]*\s+)?name=['"])(.*?)(['"])/i) do |m|
        $1 + transform_id($2, guide_name) + $3

      end.gsub(/(<\w+\s+(?:[^<>]*\s+)?id=['"])(.*?)(['"])/i) do |m|
        $1 + transform_id($2, guide_name) + $3
      end
    end

    def self.transform_id(id, guide_name)
      if id =~ /^#{guide_name}-section-/
        id
      else
        "#{guide_name}-section-#{id}"
      end
    end

  end

end
+49 −0
Original line number Diff line number Diff line
require 'jsduck/util/html'

module JsDuck

  # Adds Table of Contents section to guide HTML.
  class GuideToc

    # Inserts table of contents at the top of guide HTML by looking
    # for <h2> elements.
    def self.inject(html, guide_name)
      toc = []
      new_html = []

      html.each_line do |line|
        if line =~ /^\s*<(h[1-6])>(.*?)<\/h[1-6]>$/
          tag = $1
          text = Util::HTML.strip_tags($2)
          id = guide_name + "-section-" + title_to_id(text)
          if tag == "h2"
            toc << "<li><a href='#!/guide/#{id}'>#{text}</a></li>\n"
          end
          new_html << "<#{tag} id='#{id}'>#{text}</#{tag}>\n"
        else
          new_html << line
        end
      end

      # Inject TOC below first heading if at least 2 items in TOC
      if toc.length >= 2
        new_html.insert(1, [
            "<div class='toc'>\n",
            "<p><strong>Contents</strong></p>\n",
            "<ol>\n",
            toc,
            "</ol>\n",
            "</div>\n",
        ])
      end

      new_html.flatten.join
    end

    def self.title_to_id(title)
      title.downcase.gsub(/[^\w]+/, "-")
    end

  end

end
+5 −32
Original line number Diff line number Diff line
@@ -4,7 +4,8 @@ require 'jsduck/util/io'
require 'jsduck/util/null_object'
require 'jsduck/logger'
require 'jsduck/grouped_asset'
require 'jsduck/util/html'
require 'jsduck/guide_toc'
require 'jsduck/guide_anchors'
require 'jsduck/img/dir'
require 'fileutils'

@@ -67,7 +68,9 @@ module JsDuck
    def format_guide(guide)
      @formatter.doc_context = {:filename => guide[:filename], :linenr => 0}
      @formatter.images = Img::Dir.new(guide["url"], "guides/#{guide["name"]}")
      html = add_toc(guide, @formatter.format(Util::IO.read(guide[:filename])))
      html = @formatter.format(Util::IO.read(guide[:filename]))
      html = GuideToc.inject(html, guide['name'])
      html = GuideAnchors.transform(html, guide['name'])

      # Report unused images (but ignore the icon files)
      @formatter.images.get("icon.png")
@@ -115,36 +118,6 @@ module JsDuck
      end
    end

    # Creates table of contents at the top of guide by looking for <h2> elements in HTML.
    def add_toc(guide, html)
      toc = [
        "<div class='toc'>\n",
        "<p><strong>Contents</strong></p>\n",
        "<ol>\n",
      ]
      new_html = []
      i = 0
      html.each_line do |line|
        if line =~ /^<h2>(.*)<\/h2>$/
          i += 1
          text = Util::HTML.strip_tags($1)
          toc << "<li><a href='#!/guide/#{guide['name']}-section-#{i}'>#{text}</a></li>\n"
          new_html << "<h2 id='#{guide['name']}-section-#{i}'>#{text}</h2>\n"
        else
          new_html << line
        end
      end
      toc << "</ol>\n"
      toc << "</div>\n"
      # Inject TOC at below first heading if at least 2 items in TOC
      if i >= 2
        new_html.insert(1, toc)
        new_html.flatten.join
      else
        html
      end
    end

    # Returns HTML listing of guides
    def to_html(style="")
      html = @groups.map do |group|
+6 −3
Original line number Diff line number Diff line
@@ -95,7 +95,6 @@ module JsDuck
      @ext4_events = nil

      @version = "5.0.0.beta2"

      # Customizing output
      @title = "Documentation - JSDuck"
      @header = "<strong>Documentation</strong> JSDuck"
@@ -454,6 +453,8 @@ module JsDuck
        end

        opts.on('--comments-domain=STRING',
          "A name identifying the subset of comments.",
          "",
          "A string consisting of <name>/<version>.",
          "",
          "For example: ext-js/4",
@@ -463,7 +464,7 @@ module JsDuck
        end

        opts.on('--search-url=URL',
          "Address of guides search server server.",
          "Address of guides search server.",
          "",
          "When supplied, the search for guides is performed through this",
          "external service and the results merged together with API search.",
@@ -478,6 +479,8 @@ module JsDuck
        end

        opts.on('--search-domain=STRING',
          "A name identifying the subset to search from.",
          "",
          "A string consisting of <name>/<version>.",
          "",
          "Tells the search engine which product and version",
@@ -488,7 +491,7 @@ module JsDuck
          "Must be used together with --search-url option.",
          "",
          "This option is EXPERIMENTAL.") do |domain|
          @search[:product], @search[:version] = domain.slice(/\//)
          @search[:product], @search[:version] = domain.split(/\//)
        end

        opts.separator ""
+54 −0
Original line number Diff line number Diff line
require "jsduck/guide_anchors"

describe JsDuck::GuideAnchors do

  def transform(html)
    JsDuck::GuideAnchors.transform(html, "myguide")
  end

  it "transforms anchor links" do
    transform("<a href='#blah'>label</a>").should ==
      "<a href='#!/guide/myguide-section-blah'>label</a>"
  end

  it "transforms anchor links in fuzzier HTML" do
    transform("<a\n class='blah' href=\"#blah\"\n>label</a>").should ==
      "<a\n class='blah' href=\"#!/guide/myguide-section-blah\"\n>label</a>"
  end

  it "transforms anchor links in longer HTML" do
    transform("Some\nlong\ntext\nhere...\n\n <a href='#blah'>label</a>").should ==
      "Some\nlong\ntext\nhere...\n\n <a href='#!/guide/myguide-section-blah'>label</a>"
  end

  it "doesn't transform normal links" do
    transform("<a href='http://example.com'>label</a>").should ==
      "<a href='http://example.com'>label</a>"
  end

  it "doesn't transform docs-app #! links " do
    transform("<a href='#!/api/Ext.Base'>Ext.Base</a>").should ==
      "<a href='#!/api/Ext.Base'>Ext.Base</a>"
  end

  it "transforms anchors" do
    transform("<a name='blah'>target</a>").should ==
      "<a name='myguide-section-blah'>target</a>"
  end

  it "doesn't transforms anchors already in target format" do
    transform("<a name='myguide-section-blah'>target</a>").should ==
      "<a name='myguide-section-blah'>target</a>"
  end

  it "transforms ID-s" do
    transform("<h1 id='blah'>target</h1>").should ==
      "<h1 id='myguide-section-blah'>target</h1>"
  end

  it "doesn't ID-s already in target format" do
    transform("<h1 id='myguide-section-blah'>target</h1>").should ==
      "<h1 id='myguide-section-blah'>target</h1>"
  end

end
Loading