diff --git a/lib/jsduck/assets.rb b/lib/jsduck/assets.rb
index 02085a51f13dc9543ea64ca2ceb3bba3cbe14a96..d28089a0230912615c6ff134bdd93418b623c7e0 100644
--- a/lib/jsduck/assets.rb
+++ b/lib/jsduck/assets.rb
@@ -27,8 +27,7 @@ module JsDuck
@relations = relations
@opts = opts
- doc_formatter = DocFormatter.new(@opts)
- doc_formatter.relations = @relations
+ doc_formatter = DocFormatter.new(@relations, @opts)
@images = Img::DirSet.new(@opts.images, "images")
@welcome = Welcome.create(@opts.welcome, doc_formatter)
diff --git a/lib/jsduck/batch_formatter.rb b/lib/jsduck/batch_formatter.rb
index 402083a131b0482a019e19bbdc7662df35ff835b..0553db6f6f23f64d6b56187a65d015c576c394b0 100644
--- a/lib/jsduck/batch_formatter.rb
+++ b/lib/jsduck/batch_formatter.rb
@@ -45,8 +45,7 @@ module JsDuck
# Factory method to create new ClassFormatter instances.
def self.create_class_formatter(relations, opts)
- doc_formatter = DocFormatter.new(opts)
- doc_formatter.relations = relations
+ doc_formatter = DocFormatter.new(relations, opts)
doc_formatter.images = Img::DirSet.new(opts.images, "images")
class_formatter = ClassFormatter.new(relations, doc_formatter)
diff --git a/lib/jsduck/doc_formatter.rb b/lib/jsduck/doc_formatter.rb
index 433d14347d1f2df4d7f6209b80a707950562e39a..3e2fcee91ae39a38c1fbd1129e09313bbc34d6f1 100644
--- a/lib/jsduck/doc_formatter.rb
+++ b/lib/jsduck/doc_formatter.rb
@@ -3,6 +3,8 @@ require 'strscan'
require 'rdiscount'
require 'jsduck/html_stack'
require 'jsduck/inline/link'
+require 'jsduck/inline/auto_link'
+require 'jsduck/inline/link_renderer'
require 'jsduck/inline/img'
require 'jsduck/inline/video'
require 'jsduck/inline/example'
@@ -15,9 +17,11 @@ module JsDuck
# Creates a formatter configured with options originating from
# command line. For the actual effect of the options see
# Inline::* classes.
- def initialize(opts={})
+ def initialize(relations={}, opts={})
@opts = opts
- @inline_link = Inline::Link.new(opts)
+ @link_renderer = Inline::LinkRenderer.new(relations, opts)
+ @inline_link = Inline::Link.new(@link_renderer)
+ @auto_link = Inline::AutoLink.new(@link_renderer)
@inline_img = Inline::Img.new(opts)
@inline_video = Inline::Video.new(opts)
@inline_example = Inline::Example.new(opts)
@@ -37,6 +41,7 @@ module JsDuck
# Context#blah is meant.
def class_context=(cls)
@inline_link.class_context = cls
+ @auto_link.class_context = cls
end
# Sets up instance to work in context of particular doc object.
@@ -45,6 +50,7 @@ module JsDuck
@doc_context = doc
@inline_video.doc_context = doc
@inline_link.doc_context = doc
+ @auto_link.doc_context = doc
@inline_img.doc_context = doc
end
@@ -53,15 +59,6 @@ module JsDuck
@doc_context
end
- # JsDuck::Relations for looking up class names.
- #
- # When auto-creating class links from CamelCased names found from
- # text, we check the relations object to see if a class with that
- # name actually exists.
- def relations=(relations)
- @inline_link.relations = relations
- end
-
# Formats doc-comment for placement into HTML.
# Renders it with Markdown-formatter and replaces @link-s.
def format(input)
@@ -127,7 +124,7 @@ module JsDuck
# Replace class names in the following text up to next "<" or "{"
# but only when we're not inside ...
text = s.scan(/[^{<]+/)
- out += tags.open?("a") ? text : @inline_link.create_magic_links(text)
+ out += tags.open?("a") ? text : @auto_link.replace(text)
end
end
@@ -136,7 +133,7 @@ module JsDuck
# Creates a link based on the link template.
def link(cls, member, anchor_text, type=nil, static=nil)
- @inline_link.link(cls, member, anchor_text, type, static)
+ @link_renderer.link(cls, member, anchor_text, type, static)
end
end
diff --git a/lib/jsduck/inline/auto_link.rb b/lib/jsduck/inline/auto_link.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c118b2d70f7061df7d55ebea74f4ec7120c8ec60
--- /dev/null
+++ b/lib/jsduck/inline/auto_link.rb
@@ -0,0 +1,106 @@
+require 'jsduck/logger'
+
+module JsDuck
+ module Inline
+
+ # Takes care of the auto-detection of links in text.
+ class AutoLink
+ # Sets up instance to work in context of particular class, so it
+ # knows that #blah is in context of SomeClass.
+ attr_accessor :class_context
+
+ # Sets up instance to work in context of particular doc object.
+ # Used for error reporting.
+ attr_accessor :doc_context
+
+ def initialize(link_renderer)
+ @class_context = ""
+ @doc_context = {}
+ @relations = link_renderer.relations
+ @renderer = link_renderer
+ @magic_link_re = magic_link_re
+ end
+
+ # Looks input text for patterns like:
+ #
+ # My.ClassName
+ # MyClass#method
+ # #someProperty
+ #
+ # and converts them to links, as if they were surrounded with
+ # {@link} tag. One notable exception is that Foo is not created to
+ # link, even when Foo class exists, but Foo.Bar is. This is to
+ # avoid turning normal words into links. For example:
+ #
+ # Math involves a lot of numbers. Ext JS is a JavaScript framework.
+ #
+ # In these sentences we don't want to link "Math" and "Ext" to the
+ # corresponding JS classes. And that's why we auto-link only
+ # class names containing a dot "."
+ #
+ def replace(input)
+ input.gsub(@magic_link_re) do
+ cls = $1 || $3
+ member = $2 || $4
+ replace_magic_link(cls, member)
+ end
+ end
+
+ private
+
+ # Generates regex for auto-linking class and member names in text.
+ def magic_link_re
+ ident_re = "(?:[A-Za-z_$][A-Za-z0-9_$]*)"
+ cls_re = "(#{ident_re}(?:\\.#{ident_re})*)"
+ ns_cls_re = "(#{ident_re}(?:\\.#{ident_re})+)"
+ member_re = "(?:#(#{ident_re}))"
+ /#{cls_re}#{member_re}|#{ns_cls_re}|#{member_re}/m
+ end
+
+ def replace_magic_link(cls, member)
+ if cls && member
+ if @relations[cls] && @renderer.get_matching_member(cls, {:name => member})
+ return @renderer.link(cls, member, cls+"."+member)
+ else
+ warn_magic_link("#{cls}##{member} links to non-existing " + (@relations[cls] ? "member" : "class"))
+ end
+ elsif cls
+ if @relations[cls]
+ return @renderer.link(cls, nil, cls)
+ else
+ cls2, member2 = split_to_cls_and_member(cls)
+ if @relations[cls2] && @renderer.get_matching_member(cls2, {:name => member2})
+ return @renderer.link(cls2, member2, cls2+"."+member2)
+ elsif cls =~ /\.(js|css|html|php)\Z/
+ # Ignore common filenames
+ else
+ warn_magic_link("#{cls} links to non-existing class")
+ end
+ end
+ else
+ if @renderer.get_matching_member(@class_context, {:name => member})
+ return @renderer.link(@class_context, member, member)
+ elsif member =~ /\A([A-F0-9]{3}|[A-F0-9]{6})\Z/i || member =~ /\A[0-9]/
+ # Ignore HEX color codes and
+ # member names beginning with number
+ else
+ warn_magic_link("##{member} links to non-existing member")
+ end
+ end
+
+ return "#{cls}#{member ? '#' : ''}#{member}"
+ end
+
+ def split_to_cls_and_member(str)
+ parts = str.split(/\./)
+ return [parts.slice(0, parts.length-1).join("."), parts.last]
+ end
+
+ def warn_magic_link(msg)
+ Logger.warn(:link_auto, msg, @doc_context[:filename], @doc_context[:linenr])
+ end
+
+ end
+
+ end
+end
diff --git a/lib/jsduck/inline/link.rb b/lib/jsduck/inline/link.rb
index bf39ac3b46e1300c3d9636e182248ed949184017..41f61f6c5fef6aa1697b49eb3ee06c730d120829 100644
--- a/lib/jsduck/inline/link.rb
+++ b/lib/jsduck/inline/link.rb
@@ -1,4 +1,3 @@
-require 'jsduck/util/html'
require 'jsduck/logger'
require 'jsduck/tag_registry'
@@ -19,28 +18,11 @@ module JsDuck
# Used for error reporting.
attr_accessor :doc_context
- # JsDuck::Relations for looking up class names.
- #
- # When auto-creating class links from CamelCased names found from
- # text, we check the relations object to see if a class with that
- # name actually exists.
- attr_accessor :relations
-
- def initialize(opts={})
+ def initialize(link_renderer)
@class_context = ""
@doc_context = {}
- @relations = {}
-
- # Template HTML that replaces {@link Class#member anchor text}.
- # Can contain placeholders:
- #
- # %c - full class name (e.g. "Ext.Panel")
- # %m - class member name prefixed with member type (e.g. "method-urlEncode")
- # %# - inserts "#" if member name present
- # %- - inserts "-" if member name present
- # %a - anchor text for link
- @tpl = opts[:link_tpl] || '%a'
-
+ @relations = link_renderer.relations
+ @renderer = link_renderer
@re = /\{@link\s+(\S*?)(?:\s+(.+?))?\}/m
end
@@ -86,7 +68,7 @@ module JsDuck
Logger.warn(:link, "#{full_link} links to non-existing class", file, line)
return text
elsif member
- ms = find_members(cls, {:name => member, :tagname => type, :static => static})
+ ms = @renderer.find_members(cls, {:name => member, :tagname => type, :static => static})
if ms.length == 0
Logger.warn(:link, "#{full_link} links to non-existing member", file, line)
return text
@@ -108,120 +90,12 @@ module JsDuck
end
end
- return link(cls, member, text, type, static)
+ return @renderer.link(cls, member, text, type, static)
else
- return link(cls, false, text)
+ return @renderer.link(cls, false, text)
end
end
- # Looks input text for patterns like:
- #
- # My.ClassName
- # MyClass#method
- # #someProperty
- #
- # and converts them to links, as if they were surrounded with
- # {@link} tag. One notable exception is that Foo is not created to
- # link, even when Foo class exists, but Foo.Bar is. This is to
- # avoid turning normal words into links. For example:
- #
- # Math involves a lot of numbers. Ext JS is a JavaScript framework.
- #
- # In these sentences we don't want to link "Math" and "Ext" to the
- # corresponding JS classes. And that's why we auto-link only
- # class names containing a dot "."
- #
- def create_magic_links(input)
- cls_re = "([A-Z][A-Za-z0-9.]*[A-Za-z0-9])"
- member_re = "(?:#([A-Za-z0-9]+))"
-
- input.gsub(/\b#{cls_re}#{member_re}?\b|#{member_re}\b/m) do
- replace_magic_link($1, $2 || $3)
- end
- end
-
- def replace_magic_link(cls, member)
- if cls && member
- if @relations[cls] && get_matching_member(cls, {:name => member})
- return link(cls, member, cls+"."+member)
- else
- warn_magic_link("#{cls}##{member} links to non-existing " + (@relations[cls] ? "member" : "class"))
- end
- elsif cls && cls =~ /\./
- if @relations[cls]
- return link(cls, nil, cls)
- else
- cls2, member2 = split_to_cls_and_member(cls)
- if @relations[cls2] && get_matching_member(cls2, {:name => member2})
- return link(cls2, member2, cls2+"."+member2)
- elsif cls =~ /\.(js|css|html|php)\Z/
- # Ignore common filenames
- else
- warn_magic_link("#{cls} links to non-existing class")
- end
- end
- elsif !cls && member
- if get_matching_member(@class_context, {:name => member})
- return link(@class_context, member, member)
- elsif member =~ /\A([A-F0-9]{3}|[A-F0-9]{6})\Z/i || member =~ /\A[0-9]/
- # Ignore HEX color codes and
- # member names beginning with number
- else
- warn_magic_link("##{member} links to non-existing member")
- end
- end
-
- return "#{cls}#{member ? '#' : ''}#{member}"
- end
-
- def split_to_cls_and_member(str)
- parts = str.split(/\./)
- return [parts.slice(0, parts.length-1).join("."), parts.last]
- end
-
- def warn_magic_link(msg)
- Logger.warn(:link_auto, msg, @doc_context[:filename], @doc_context[:linenr])
- end
-
- # applies the link template
- def link(cls, member, anchor_text, type=nil, static=nil)
- # Use the canonical class name for link (not some alternateClassName)
- cls = @relations[cls][:name]
- # prepend type name to member name
- member = member && get_matching_member(cls, {:name => member, :tagname => type, :static => static})
-
- @tpl.gsub(/(%[\w#-])/) do
- case $1
- when '%c'
- cls
- when '%m'
- member ? member[:id] : ""
- when '%#'
- member ? "#" : ""
- when '%-'
- member ? "-" : ""
- when '%a'
- Util::HTML.escape(anchor_text||"")
- else
- $1
- end
- end
- end
-
- def get_matching_member(cls, query)
- ms = find_members(cls, query)
- if ms.length > 1
- instance_ms = ms.find_all {|m| !m[:static] }
- instance_ms.length > 0 ? instance_ms[0] : ms.find_all {|m| m[:static] }[0]
- else
- ms[0]
- end
- end
-
- def find_members(cls, query)
- @relations[cls] ? @relations[cls].find_members(query) : []
- end
-
end
end
diff --git a/lib/jsduck/inline/link_renderer.rb b/lib/jsduck/inline/link_renderer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6d81848ec3bfbca73d1df954cf894f8f125df3a8
--- /dev/null
+++ b/lib/jsduck/inline/link_renderer.rb
@@ -0,0 +1,69 @@
+require 'jsduck/util/html'
+
+module JsDuck
+ module Inline
+
+ # Renders HTML link class or member.
+ class LinkRenderer
+ # Access to relations object, used by Inline::Link and
+ # Inline::AutoLink.
+ attr_reader :relations
+
+ def initialize(relations={}, opts={})
+ @relations = relations
+
+ # Template HTML that replaces {@link Class#member anchor text}.
+ # Can contain placeholders:
+ #
+ # %c - full class name (e.g. "Ext.Panel")
+ # %m - class member name prefixed with member type (e.g. "method-urlEncode")
+ # %# - inserts "#" if member name present
+ # %- - inserts "-" if member name present
+ # %a - anchor text for link
+ @tpl = opts[:link_tpl] || '%a'
+ end
+
+ # Generates HTML link to class or member applying the link
+ # template.
+ def link(cls, member, anchor_text, type=nil, static=nil)
+ # Use the canonical class name for link (not some alternateClassName)
+ cls = @relations[cls][:name]
+ # prepend type name to member name
+ member = member && get_matching_member(cls, {:name => member, :tagname => type, :static => static})
+
+ @tpl.gsub(/(%[\w#-])/) do
+ case $1
+ when '%c'
+ cls
+ when '%m'
+ member ? member[:id] : ""
+ when '%#'
+ member ? "#" : ""
+ when '%-'
+ member ? "-" : ""
+ when '%a'
+ Util::HTML.escape(anchor_text||"")
+ else
+ $1
+ end
+ end
+ end
+
+ def get_matching_member(cls, query)
+ ms = find_members(cls, query)
+ if ms.length > 1
+ instance_ms = ms.find_all {|m| !m[:static] }
+ instance_ms.length > 0 ? instance_ms[0] : ms.find_all {|m| m[:static] }[0]
+ else
+ ms[0]
+ end
+ end
+
+ def find_members(cls, query)
+ @relations[cls] ? @relations[cls].find_members(query) : []
+ end
+
+ end
+
+ end
+end
diff --git a/spec/doc_formatter_spec.rb b/spec/doc_formatter_spec.rb
index 7cbe18d1c3653d984bfdfb47f13244b6cfb8869f..00629342b3809288e5a74fdc599468dbd69dd563 100644
--- a/spec/doc_formatter_spec.rb
+++ b/spec/doc_formatter_spec.rb
@@ -11,37 +11,37 @@ describe JsDuck::DocFormatter do
end
end
- before do
- @formatter = JsDuck::DocFormatter.new(:img_tpl => '
')
- @formatter.class_context = "Context"
- @formatter.images = ImageDirMock.new
- @formatter.relations = JsDuck::Relations.new([
- JsDuck::Class.new({
- :name => "Context",
- :members => [
- {:tagname => :method, :name => "bar", :id => "method-bar"},
- {:tagname => :method, :name => "id", :id => "static-method-id",
- :static => true},
- ],
- }),
- JsDuck::Class.new({
- :name => 'Ext.Msg'
- }),
- JsDuck::Class.new({
- :name => "Foo",
- :members => [
- {:tagname => :cfg, :name => "bar", :id => "cfg-bar"},
- {:tagname => :method, :name => "id", :id => "static-method-id",
- :static => true},
- {:tagname => :method, :name => "privMeth", :id => "method-privMeth", :private => true},
- ],
- :alternateClassNames => ["FooBar"]
- }),
- ])
- end
-
describe "#replace" do
+ before do
+ relations = JsDuck::Relations.new([
+ JsDuck::Class.new({
+ :name => "Context",
+ :members => [
+ {:tagname => :method, :name => "bar", :id => "method-bar"},
+ {:tagname => :method, :name => "id", :id => "static-method-id",
+ :static => true},
+ ],
+ }),
+ JsDuck::Class.new({
+ :name => 'Ext.Msg'
+ }),
+ JsDuck::Class.new({
+ :name => "Foo",
+ :members => [
+ {:tagname => :cfg, :name => "bar", :id => "cfg-bar"},
+ {:tagname => :method, :name => "id", :id => "static-method-id",
+ :static => true},
+ {:tagname => :method, :name => "privMeth", :id => "method-privMeth", :private => true},
+ ],
+ :alternateClassNames => ["FooBar"]
+ }),
+ ])
+ @formatter = JsDuck::DocFormatter.new(relations, :img_tpl => '
')
+ @formatter.class_context = "Context"
+ @formatter.images = ImageDirMock.new
+ end
+
# {@link ...}
it "replaces {@link Ext.Msg} with link to class" do
@@ -137,238 +137,282 @@ describe JsDuck::DocFormatter do
@formatter.replace("{@video vimeo 123456 Alt text}").should =~
//
end
+ end
- # auto-conversion of identifiable ClassNames to links
- describe "auto-detect" do
- before do
- @formatter.class_context = "Context"
- @formatter.images = ImageDirMock.new
- @formatter.relations = JsDuck::Relations.new([
- JsDuck::Class.new({:name => 'Foo.Bar'}),
- JsDuck::Class.new({:name => 'Foo.Bar.Blah'}),
- JsDuck::Class.new({
- :name => 'Ext.form.Field',
- :members => [
- {:tagname => :method, :name => "getValues", :id => "method-getValues"}
- ]
- }),
- JsDuck::Class.new({
- :name => 'Ext.XTemplate',
- :alternateClassNames => ['Ext.AltXTemplate']
- }),
- JsDuck::Class.new({
- :name => 'Ext',
- :members => [
- {:tagname => :method, :name => "encode", :id => "method-encode"}
- ]
- }),
- JsDuck::Class.new({
- :name => "Context",
- :members => [
- {:tagname => :method, :name => "bar", :id => "method-bar"},
- {:tagname => :method, :name => "privMeth", :id => "method-privMeth", :private => true},
- ]
- }),
- ])
- end
+ # auto-conversion of identifiable ClassNames to links
+ describe "#replace auto-detect" do
+ before do
+ relations = JsDuck::Relations.new([
+ JsDuck::Class.new({:name => 'Foo.Bar'}),
+ JsDuck::Class.new({:name => 'Foo.Bar.Blah'}),
+ JsDuck::Class.new({
+ :name => 'Ext.form.Field',
+ :members => [
+ {:tagname => :method, :name => "getValues", :id => "method-getValues"}
+ ]
+ }),
+ JsDuck::Class.new({
+ :name => 'Ext.XTemplate',
+ :alternateClassNames => ['Ext.AltXTemplate']
+ }),
+ JsDuck::Class.new({
+ :name => 'Ext',
+ :members => [
+ {:tagname => :method, :name => "encode", :id => "method-encode"}
+ ]
+ }),
+ JsDuck::Class.new({
+ :name => "Context",
+ :members => [
+ {:tagname => :method, :name => "bar", :id => "method-bar"},
+ {:tagname => :method, :name => "privMeth", :id => "method-privMeth", :private => true},
+ ]
+ }),
+ JsDuck::Class.new({
+ :name => "downcase.ClassName",
+ :members => [
+ {:tagname => :method, :name => "blah", :id => "method-blah"},
+ ]
+ }),
+ JsDuck::Class.new({
+ :name => "_us.In_Cls_Name",
+ :members => [
+ {:tagname => :method, :name => "_sss", :id => "method-_sss"},
+ ]
+ }),
+ JsDuck::Class.new({
+ :name => "$Class",
+ :members => [
+ {:tagname => :method, :name => "$sss", :id => "method-S-sss"},
+ ]
+ }),
+ ])
+ @formatter = JsDuck::DocFormatter.new(relations, :img_tpl => '
')
+ @formatter.class_context = "Context"
+ @formatter.images = ImageDirMock.new
+ end
- it "doesn't recognize John as class name" do
- @formatter.replace("John is lazy").should ==
- "John is lazy"
- end
+ it "doesn't recognize John as class name" do
+ @formatter.replace("John is lazy").should ==
+ "John is lazy"
+ end
- it "doesn't recognize Bla.Bla as class name" do
- @formatter.replace("Unknown Bla.Bla class").should ==
- "Unknown Bla.Bla class"
- end
+ it "doesn't recognize Bla.Bla as class name" do
+ @formatter.replace("Unknown Bla.Bla class").should ==
+ "Unknown Bla.Bla class"
+ end
- it "doesn't recognize Ext as class name" do
- @formatter.replace("Talking about Ext JS").should ==
- "Talking about Ext JS"
- end
+ it "doesn't recognize Ext as class name" do
+ @formatter.replace("Talking about Ext JS").should ==
+ "Talking about Ext JS"
+ end
- it "converts Foo.Bar to class link" do
- @formatter.replace("Look at Foo.Bar").should ==
- 'Look at Foo.Bar'
- end
+ it "converts Foo.Bar to class link" do
+ @formatter.replace("Look at Foo.Bar").should ==
+ 'Look at Foo.Bar'
+ end
- it "converts FooBar.Blah to class link" do
- @formatter.replace("Look at Foo.Bar.Blah").should ==
- 'Look at Foo.Bar.Blah'
- end
+ it "converts FooBar.Blah to class link" do
+ @formatter.replace("Look at Foo.Bar.Blah").should ==
+ 'Look at Foo.Bar.Blah'
+ end
- it "converts Ext.form.Field to class link" do
- @formatter.replace("Look at Ext.form.Field").should ==
- 'Look at Ext.form.Field'
- end
+ it "converts Ext.form.Field to class link" do
+ @formatter.replace("Look at Ext.form.Field").should ==
+ 'Look at Ext.form.Field'
+ end
- it "converts Ext.XTemplate to class link" do
- @formatter.replace("Look at Ext.XTemplate").should ==
- 'Look at Ext.XTemplate'
- end
+ it "converts Ext.XTemplate to class link" do
+ @formatter.replace("Look at Ext.XTemplate").should ==
+ 'Look at Ext.XTemplate'
+ end
- it "links alternate classname to canonical classname" do
- @formatter.replace("Look at Ext.AltXTemplate").should ==
- 'Look at Ext.AltXTemplate'
- end
+ it "links alternate classname to canonical classname" do
+ @formatter.replace("Look at Ext.AltXTemplate").should ==
+ 'Look at Ext.AltXTemplate'
+ end
- it "converts ClassName ending with dot to class link" do
- @formatter.replace("Look at Foo.Bar.").should ==
- 'Look at Foo.Bar.'
- end
+ it "converts downcase.ClassName to class link" do
+ @formatter.replace("Look at downcase.ClassName").should ==
+ 'Look at downcase.ClassName'
+ end
- it "converts ClassName ending with comma to class link" do
- @formatter.replace("Look at Foo.Bar, it's great!").should ==
- 'Look at Foo.Bar, it\'s great!'
- end
+ it "converts classname with underscores to class link" do
+ @formatter.replace("Look at _us.In_Cls_Name").should ==
+ 'Look at _us.In_Cls_Name'
+ end
- it "converts two ClassNames in one line to links" do
- @formatter.replace("See: Foo.Bar, Ext.XTemplate").should ==
- 'See: Foo.Bar, Ext.XTemplate'
- end
+ it "converts ClassName ending with dot to class link" do
+ @formatter.replace("Look at Foo.Bar.").should ==
+ 'Look at Foo.Bar.'
+ end
- # Links to #members
+ it "converts ClassName ending with comma to class link" do
+ @formatter.replace("Look at Foo.Bar, it's great!").should ==
+ 'Look at Foo.Bar, it\'s great!'
+ end
- it "converts Ext#encode to method link" do
- @formatter.replace("Look at Ext#encode").should ==
- 'Look at Ext.encode'
- end
+ it "converts two ClassNames in one line to links" do
+ @formatter.replace("See: Foo.Bar, Ext.XTemplate").should ==
+ 'See: Foo.Bar, Ext.XTemplate'
+ end
- it "converts Ext.form.Field#getValues to method link" do
- @formatter.replace("Look at Ext.form.Field#getValues").should ==
- 'Look at Ext.form.Field.getValues'
- end
+ # Links to #members
- it "converts Ext.encode to method link" do
- @formatter.replace("Look at Ext.encode").should ==
- 'Look at Ext.encode'
- end
+ it "converts Ext#encode to method link" do
+ @formatter.replace("Look at Ext#encode").should ==
+ 'Look at Ext.encode'
+ end
- it "converts #bar to link to current class method" do
- @formatter.replace("Look at #bar method").should ==
- 'Look at bar method'
- end
+ it "converts Ext.form.Field#getValues to method link" do
+ @formatter.replace("Look at Ext.form.Field#getValues").should ==
+ 'Look at Ext.form.Field.getValues'
+ end
- it "converts #privMeth to link to private method" do
- @formatter.replace("Look at #privMeth method").should ==
- 'Look at privMeth method'
- end
+ it "converts downcase.ClassName#blah to method link" do
+ @formatter.replace("Look at downcase.ClassName#blah").should ==
+ 'Look at downcase.ClassName.blah'
+ end
- it "Doesn't convert #unknown to link" do
- @formatter.replace("Ahh, an #unknown method").should ==
- 'Ahh, an #unknown method'
- end
+ it 'converts $Class#$sss to method link' do
+ @formatter.replace('Look at $Class#$sss').should ==
+ 'Look at $Class.$sss'
+ end
+
+ it "converts Ext.encode to method link" do
+ @formatter.replace("Look at Ext.encode").should ==
+ 'Look at Ext.encode'
+ end
- # Ensure links aren't created inside ... or {@link} and {@img} tags.
+ it "converts #bar to link to current class method" do
+ @formatter.replace("Look at #bar method").should ==
+ 'Look at bar method'
+ end
- it "doesn't create links inside {@link} tag" do
- @formatter.replace("{@link Foo.Bar a Foo.Bar link}").should ==
- 'a Foo.Bar link'
- end
+ it "converts #privMeth to link to private method" do
+ @formatter.replace("Look at #privMeth method").should ==
+ 'Look at privMeth method'
+ end
- it "doesn't create links inside {@img} tag" do
- @formatter.replace("{@img some/file.jpg a Foo.Bar image}").should ==
- '
'
- end
+ it "Doesn't convert #unknown to link" do
+ @formatter.replace("Ahh, an #unknown method").should ==
+ 'Ahh, an #unknown method'
+ end
- it "doesn't create links inside HTML tags" do
- @formatter.replace('
').should ==
- '
'
- end
+ # Ensure links aren't created inside ... or {@link} and {@img} tags.
- it "doesn't create links inside multiline HTML tags" do
- @formatter.replace('
').should ==
- '
'
- end
+ it "doesn't create links inside {@link} tag" do
+ @formatter.replace("{@link Foo.Bar a Foo.Bar link}").should ==
+ 'a Foo.Bar link'
+ end
- it "doesn't create links inside ..." do
- @formatter.replace('See Foo.Bar').should ==
- 'See Foo.Bar'
- end
+ it "doesn't create links inside {@img} tag" do
+ @formatter.replace("{@img some/file.jpg a Foo.Bar image}").should ==
+ '
'
+ end
- it "creates links inside ..." do
- @formatter.replace('See Foo.Bar').should ==
- 'See Foo.Bar'
- end
+ it "doesn't create links inside HTML tags" do
+ @formatter.replace('
').should ==
+ '
'
+ end
- it "doesn't create links inside ..." do
- @formatter.replace('See Foo.Bar').should ==
- 'See Foo.Bar'
- end
+ it "doesn't create links inside multiline HTML tags" do
+ @formatter.replace('
').should ==
+ '
'
+ end
- it "creates links after ..." do
- @formatter.replace('See Foo.Bar and Ext.XTemplate.').should ==
- 'See Foo.Bar and Ext.XTemplate.'
- end
+ it "doesn't create links inside ..." do
+ @formatter.replace('See Foo.Bar').should ==
+ 'See Foo.Bar'
+ end
- it "doesn't create links inside nested tags" do
- @formatter.replace('See Foo.Bar Ext.XTemplate').should ==
- 'See Foo.Bar Ext.XTemplate'
- end
+ it "creates links inside ..." do
+ @formatter.replace('See Foo.Bar').should ==
+ 'See Foo.Bar'
+ end
- it "handles unclosed HTML tags" do
- @formatter.replace('Malformed
..." do
+ @formatter.replace('See Foo.Bar').should ==
+ 'See Foo.Bar'
+ end
+ it "creates links after ..." do
+ @formatter.replace('See Foo.Bar and Ext.XTemplate.').should ==
+ 'See Foo.Bar and Ext.XTemplate.'
end
- describe "with type information" do
- before do
- @formatter.relations = JsDuck::Relations.new([
- JsDuck::Class.new({
- :name => 'Foo',
- :members => [
- {:tagname => :method, :name => "select", :id => "method-select"},
- {:tagname => :event, :name => "select", :id => "event-select"},
- ]
- })
- ])
- end
+ it "doesn't create links inside nested tags" do
+ @formatter.replace('See Foo.Bar Ext.XTemplate').should ==
+ 'See Foo.Bar Ext.XTemplate'
+ end
- it "replaces {@link Foo#method-select} with link to method" do
- @formatter.replace("Look at {@link Foo#method-select}").should ==
- 'Look at Foo.select'
- end
+ it "handles unclosed HTML tags" do
+ @formatter.replace('Malformed
Foo.select'
- end
+ end
+
+ describe "#replace with type information" do
+ before do
+ relations = JsDuck::Relations.new([
+ JsDuck::Class.new({
+ :name => 'Foo',
+ :members => [
+ {:tagname => :method, :name => "select", :id => "method-select"},
+ {:tagname => :event, :name => "select", :id => "event-select"},
+ ]
+ })
+ ])
+ @formatter = JsDuck::DocFormatter.new(relations)
end
- describe "with staticality information" do
- before do
- @formatter.relations = JsDuck::Relations.new([
- JsDuck::Class.new({
- :name => 'Foo',
- :members => [
- {:tagname => :method, :name => "select", :id => "method-select"},
- {:tagname => :method, :name => "select", :id => "static-method-select",
- :static => true},
- ]
- })
- ])
- end
+ it "replaces {@link Foo#method-select} with link to method" do
+ @formatter.replace("Look at {@link Foo#method-select}").should ==
+ 'Look at Foo.select'
+ end
- it "replaces {@link Foo#select} with link to instance method" do
- @formatter.replace("Look at {@link Foo#select}").should ==
- 'Look at Foo.select'
- end
+ it "replaces {@link Foo#event-select} with link to event" do
+ @formatter.replace("Look at {@link Foo#event-select}").should ==
+ 'Look at Foo.select'
+ end
+ end
- it "replaces {@link Foo#static-select} with link to static method" do
- @formatter.replace("Look at {@link Foo#static-select}").should ==
- 'Look at Foo.select'
- end
+ describe "#replace with staticality information" do
+ before do
+ relations = JsDuck::Relations.new([
+ JsDuck::Class.new({
+ :name => 'Foo',
+ :members => [
+ {:tagname => :method, :name => "select", :id => "method-select"},
+ {:tagname => :method, :name => "select", :id => "static-method-select",
+ :static => true},
+ ]
+ })
+ ])
+ @formatter = JsDuck::DocFormatter.new(relations)
+ end
- it "replaces {@link Foo#static-method-select} with link to static method" do
- @formatter.replace("Look at {@link Foo#static-method-select}").should ==
- 'Look at Foo.select'
- end
+ it "replaces {@link Foo#select} with link to instance method" do
+ @formatter.replace("Look at {@link Foo#select}").should ==
+ 'Look at Foo.select'
+ end
+
+ it "replaces {@link Foo#static-select} with link to static method" do
+ @formatter.replace("Look at {@link Foo#static-select}").should ==
+ 'Look at Foo.select'
+ end
+
+ it "replaces {@link Foo#static-method-select} with link to static method" do
+ @formatter.replace("Look at {@link Foo#static-method-select}").should ==
+ 'Look at Foo.select'
end
end
describe "#format" do
+ before do
+ @formatter = JsDuck::DocFormatter.new
+ end
# Just a sanity check that Markdown formatting works
it "converts Markdown to HTML" do
diff --git a/spec/type_parser_spec.rb b/spec/type_parser_spec.rb
index 35435a99f42683ccc0401d8174569cbd1b3ca1b5..b8e7cd7491247e7ab233a59251046f3c51d2057f 100644
--- a/spec/type_parser_spec.rb
+++ b/spec/type_parser_spec.rb
@@ -325,8 +325,7 @@ describe JsDuck::TypeParser do
it "links primitive types to classes" do
relations = JsDuck::Relations.new([JsDuck::Class.new({:name => "String"})])
- doc_formatter = JsDuck::DocFormatter.new
- doc_formatter.relations = relations
+ doc_formatter = JsDuck::DocFormatter.new(relations)
p = JsDuck::TypeParser.new(relations, doc_formatter)
p.parse("string")
p.out.should == 'string'