diff --git a/lib/yard/templates/helpers/html_helper.rb b/lib/yard/templates/helpers/html_helper.rb index 4d3d56862..0801ca35a 100644 --- a/lib/yard/templates/helpers/html_helper.rb +++ b/lib/yard/templates/helpers/html_helper.rb @@ -54,7 +54,7 @@ def urlencode(text) # @param [Symbol] markup examples are +:markdown+, +:textile+, +:rdoc+. # To add a custom markup type, see {MarkupHelper} # @return [String] the HTML - def htmlify(text, markup = options.markup) + def htmlify(text, markup = options.markup, internal = false) markup_meth = "html_markup_#{markup}" return text unless respond_to?(markup_meth) return "" unless text @@ -66,7 +66,7 @@ def htmlify(text, markup = options.markup) end html = resolve_links(html) unless [:text, :none, :pre, :ruby].include?(markup) - html = parse_codeblocks(html) + html = parse_codeblocks(html, internal) end html end @@ -202,6 +202,11 @@ def html_syntax_highlight(source, type = nil) new_type, source = parse_lang_for_codeblock(source) type ||= new_type || :ruby + + if type.to_s == "ruby" && source =~ /|

\s*\Z}, '') + htmlify(text, markup, true).gsub(%r{\A\s*

|

\s*\Z}, '') end # (see BaseHelper#link_object) @@ -637,20 +642,25 @@ def parse_lang_for_codeblock(source) # @param [String] html the html to search for code in # @return [String] highlighted html # @see #html_syntax_highlight - def parse_codeblocks(html) + def parse_codeblocks(html, internal = false) html.gsub(%r{(?:\s*)?(.+?)(?:\s*)?}m) do - string = $3 + pre_match, code_match, string = $1, $2, $3 # handle !!!LANG prefix to send to html_syntax_highlight_LANG language, = parse_lang_for_codeblock(string) - language ||= detect_lang_in_codeblock_attributes($1, $2) + language ||= detect_lang_in_codeblock_attributes(pre_match, code_match) language ||= object.source_type - if options.highlight + pre_attrs = [%(class="code #{language}")] + + if options.highlight && /\bdata-highlighted="true"/ !~ pre_match string = html_syntax_highlight(CGI.unescapeHTML(string), language) + pre_attrs << 'data-highlighted="true"' if internal end - classes = ['code', language].compact.join(' ') - %(
#{string}
) + + pre_attrs = pre_attrs.compact.join(' ') + + %(
#{string}
) end end diff --git a/lib/yard/templates/helpers/html_syntax_highlight_helper.rb b/lib/yard/templates/helpers/html_syntax_highlight_helper.rb index 07ab9be79..fc5c60cee 100644 --- a/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +++ b/lib/yard/templates/helpers/html_syntax_highlight_helper.rb @@ -39,7 +39,7 @@ def html_syntax_highlight_ruby_ripper(source) end output rescue Parser::ParserSyntaxError - source =~ /^test HI

' end + it "preserves syntax highlighting in {include:} snippets" do + load_markup_provider(:rdoc) + expect(File).to receive(:file?).with('foo.rdoc').and_return(true) + expect(File).to receive(:read).with('foo.rdoc').and_return( + " !!!ruby\n x = 1\n" + ) + expect(htmlify("{include:file:foo.rdoc}", :rdoc).gsub(/[\r?\n]+/, '')). + not_to include("<") + end + + it "escapes {include:} html snippets only once" do + expect(self).to receive(:html_syntax_highlight_html) do |source| + %(#{CGI.escapeHTML(source)}) + end.at_least(:once) + + load_markup_provider(:rdoc) + expect(File).to receive(:file?).with('foo.md').and_return(true) + expect(File).to receive(:read).with('foo.md').and_return( + " !!!html\n

\n" + ) + expect(htmlify("{include:file:foo.md}", :markdown).gsub(/[\r?\n]+/, '')). + to include(%(<h1>)) + end + it "does not autolink URLs inside of {} (markdown specific)" do log.enter_level(Logger::FATAL) do pending 'This test depends on markdown' unless markup_class(:markdown) @@ -648,6 +672,12 @@ def subject.respond_to?(method, include_all = false) ) end + it "wraps but doesn't alter ruby snippets that already contain highlighting tags" do + expect(subject.htmlify('
for
', :html)).to eq( + '
for
' + ) + end + it "highlights source when matching a pre lang= tag" do expect(subject.htmlify('
x = 1
', :html)).to eq( '
x = 1
'