From 4d3435dfa0caf4aba93682a55f11034cf93868f7 Mon Sep 17 00:00:00 2001
From: Rene Saarsoo <nene@triin.net>
Date: Tue, 29 Jan 2013 14:21:55 +0200
Subject: [PATCH] Extract #format from Tag#to_html.

The HTML rendering is now done in two parts:

1. Tag#format method is called, passing the DocFormatter.
   This is where Markdown to HTML conversion happens.

2. Tag#to_html method is called, which must just return HTML.
   No more can formatter be used inside #to_html.

This simplified the passing of DocFormatter instance to Tags -
no more do we need to inject the formatter inside Tag classes,
instead we can just pass it as a parameter.  With this we remove
the single remaining state object from Tag class.
---
 lib/jsduck/class_formatter.rb    | 16 +++-------------
 lib/jsduck/renderer.rb           |  8 ++++----
 lib/jsduck/tag/deprecated_tag.rb |  6 +++++-
 lib/jsduck/tag/tag.rb            | 19 +++++++++----------
 lib/jsduck/tag_renderer.rb       | 15 +++++++++------
 5 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/lib/jsduck/class_formatter.rb b/lib/jsduck/class_formatter.rb
index db1f3ef6..694ac008 100644
--- a/lib/jsduck/class_formatter.rb
+++ b/lib/jsduck/class_formatter.rb
@@ -16,14 +16,6 @@ module JsDuck
       @relations = relations
       @formatter = formatter
       @include_types = true
-      inject_formatter_to_tags
-    end
-
-    def inject_formatter_to_tags
-      # inject formatter to all html-producing tags
-      TagRegistry.html_renderers.each do |tag|
-        tag.formatter = @formatter
-      end
     end
 
     # Runs the formatter on doc object of a class.
@@ -35,7 +27,7 @@ module JsDuck
       cls[:doc] = @formatter.format(cls[:doc]) if cls[:doc]
       # format all members (except hidden ones)
       cls[:members] = cls[:members].map {|m| m[:hide] ? m : format_member(m)  }
-      cls[:html_tags] = format_tags_data(cls)
+      format_tags_data(cls)
       cls
     end
 
@@ -61,7 +53,7 @@ module JsDuck
       m[:return] = format_item(m[:return], is_css_tag) if m[:return]
       m[:throws] = m[:throws].map {|t| format_item(t, is_css_tag) } if m[:throws]
       m[:properties] = m[:properties].map {|b| format_item(b, is_css_tag) } if m[:properties]
-      m[:html_tags] = format_tags_data(m)
+      format_tags_data(m)
       m
     end
 
@@ -92,13 +84,11 @@ module JsDuck
     end
 
     def format_tags_data(context)
-      result = {}
       TagRegistry.html_renderers.each do |tag|
         if context[tag.key]
-          result[tag.key] = tag.to_html(context)
+          tag.format(context, @formatter)
         end
       end
-      result
     end
 
   end
diff --git a/lib/jsduck/renderer.rb b/lib/jsduck/renderer.rb
index a5c68fc0..f0b6b0b8 100644
--- a/lib/jsduck/renderer.rb
+++ b/lib/jsduck/renderer.rb
@@ -19,11 +19,11 @@ module JsDuck
           "<div>",
             render_sidebar,
             "<div class='doc-contents'>",
-              render_tags(@cls[:html_tags], :top),
+              render_tags(@cls, :top),
               render_private_class_notice,
               @cls[:doc],
               render_enum_class_notice,
-              render_tags(@cls[:html_tags], :bottom),
+              render_tags(@cls, :bottom),
             "</div>",
             "<div class='members'>",
               render_all_sections,
@@ -247,7 +247,7 @@ module JsDuck
     def render_long_doc(m)
       doc = []
 
-      doc << render_tags(m[:html_tags], :top)
+      doc << render_tags(m, :top)
 
       doc << m[:doc]
 
@@ -255,7 +255,7 @@ module JsDuck
         doc << "<p>Defaults to: <code>" + Util::HTML.escape(m[:default]) + "</code></p>"
       end
 
-      doc << render_tags(m[:html_tags], :bottom)
+      doc << render_tags(m, :bottom)
 
       doc << render_params_and_return(m)
 
diff --git a/lib/jsduck/tag/deprecated_tag.rb b/lib/jsduck/tag/deprecated_tag.rb
index 4ac1adc5..156309c6 100644
--- a/lib/jsduck/tag/deprecated_tag.rb
+++ b/lib/jsduck/tag/deprecated_tag.rb
@@ -27,13 +27,17 @@ module JsDuck::Tag
       h[@key] = v
     end
 
+    def format(context, formatter)
+      context[@key][:text] = formatter.format(context[@key][:text])
+    end
+
     def to_html(context)
       depr = context[@key]
       v = depr[:version] ? "since " + depr[:version] : ""
       <<-EOHTML
         <div class='signature-box #{@key}'>
         <p>This #{context[:tagname]} has been <strong>#{@key}</strong> #{v}</p>
-        #{format(depr[:text])}
+        #{depr[:text]}
         </div>
       EOHTML
     end
diff --git a/lib/jsduck/tag/tag.rb b/lib/jsduck/tag/tag.rb
index 6070c821..6eeed120 100644
--- a/lib/jsduck/tag/tag.rb
+++ b/lib/jsduck/tag/tag.rb
@@ -84,25 +84,24 @@ module JsDuck::Tag
 
     # Whether to render the tag before other content (:top) or after
     # it (:bottom).  Must be defined together with #to_html method.
+    # Additionally the #format method can be defined to perform
+    # rendering of Markdown before #to_html is called.
     attr_accessor :html_position
 
+    # Called before #to_html to allow rendering of Markdown content.
+    # For this an instance of DocFormatter is passed in, on which one
+    # can call the #format method to turn Markdown into HTML.
+    def format(context, formatter)
+    end
+
     # Implement #to_html to transform tag data to HTML to be included
     # into documentation.
     #
     # It gets passed the full class/member hash. It should return an
-    # HTML string to inject into document.  For help in that it can
-    # use the #format method to easily support Markdown and
-    # {@link/img} tags inside the contents.
+    # HTML string to inject into document.
     def to_html(context)
     end
 
-    # Helper method for use in #to_html for rendering markdown.
-    def format(markdown)
-      @formatter.format(markdown)
-    end
-
-    attr_accessor :formatter
-
     # Returns all descendants of JsDuck::Tag::Tag class.
     def self.descendants
       result = []
diff --git a/lib/jsduck/tag_renderer.rb b/lib/jsduck/tag_renderer.rb
index e5933487..37891b4f 100644
--- a/lib/jsduck/tag_renderer.rb
+++ b/lib/jsduck/tag_renderer.rb
@@ -2,16 +2,19 @@ require 'jsduck/tag_registry'
 
 module JsDuck
 
-  # Performs the rendering of builtin tags (for now just the signature data).
+  # Performs the rendering of tags.
   class TagRenderer
     # Renders tags of a particular section.
     #
-    # Returns array of rendered HTML or nil if no tag data.
-    def self.render(html_data, position)
-      return if html_data.size == 0
-
+    # Takes member or class hash and a position symbol.
+    # Returns array of rendered HTML.
+    def self.render(member, position)
       TagRegistry.html_renderers(position).map do |tag|
-        html_data[tag.key]
+        if member[tag.key]
+          tag.to_html(member)
+        else
+          nil
+        end
       end
     end
 
-- 
GitLab