From dc348baf18240dc05e209ec781daada2cbcfe16f Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Wed, 13 May 2015 00:54:13 +0200 Subject: [PATCH 1/3] Update asciidoctor gem to the latest version --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 84007d4a776..f7da36be948 100644 --- a/Gemfile +++ b/Gemfile @@ -102,7 +102,7 @@ gem 'rdoc', '~>3.6' gem 'org-ruby', '= 0.9.12' gem 'creole', '~>0.3.6' gem 'wikicloth', '=0.8.1' -gem 'asciidoctor', '= 0.1.4' +gem 'asciidoctor', '~> 1.5.2' # Diffs gem 'diffy', '~> 3.0.3' diff --git a/Gemfile.lock b/Gemfile.lock index 571ab27ea71..b6cf03b0fd4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -42,7 +42,7 @@ GEM arel (5.0.1.20140414130214) asana (0.0.6) activeresource (>= 3.2.3) - asciidoctor (0.1.4) + asciidoctor (1.5.2) ast (2.0.0) astrolabe (1.3.0) parser (>= 2.2.0.pre.3, < 3.0) @@ -683,7 +683,7 @@ DEPENDENCIES addressable annotate (~> 2.6.0.beta2) asana (~> 0.0.6) - asciidoctor (= 0.1.4) + asciidoctor (~> 1.5.2) attr_encrypted (= 1.3.4) awesome_print better_errors From 8dbc4746fe7c723b67f3c90cbf40fd7bf6c29cb7 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Wed, 13 May 2015 01:07:48 +0200 Subject: [PATCH 2/3] Handle AsciiDoc better, reuse HTML pipeline filters (fixes #9263) --- app/helpers/application_helper.rb | 12 +++- app/helpers/gitlab_markdown_helper.rb | 15 ++++- app/helpers/tree_helper.rb | 2 + lib/gitlab/asciidoc.rb | 60 +++++++++++++++++++ lib/gitlab/markdown_helper.rb | 11 +++- spec/helpers/application_helper_spec.rb | 9 ++- spec/helpers/gitlab_markdown_helper_spec.rb | 8 +++ spec/lib/gitlab/asciidoc_spec.rb | 59 ++++++++++++++++++ .../lib/gitlab/gitlab_markdown_helper_spec.rb | 14 ++++- 9 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 lib/gitlab/asciidoc.rb create mode 100644 spec/lib/gitlab/asciidoc_spec.rb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ea9722b9bef..bc07c09cd4a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -222,8 +222,12 @@ module ApplicationHelper end def render_markup(file_name, file_content) - GitHub::Markup.render(file_name, file_content). - force_encoding(file_content.encoding).html_safe + if asciidoc?(file_name) + asciidoc(file_content) + else + GitHub::Markup.render(file_name, file_content). + force_encoding(file_content.encoding).html_safe + end rescue RuntimeError simple_format(file_content) end @@ -236,6 +240,10 @@ module ApplicationHelper Gitlab::MarkdownHelper.gitlab_markdown?(filename) end + def asciidoc?(filename) + Gitlab::MarkdownHelper.asciidoc?(filename) + end + # Overrides ActionView::Helpers::UrlHelper#link_to to add `rel="nofollow"` to # external links def link_to(name = nil, options = nil, html_options = {}) diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 846aded4bda..7bcc011fd5f 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -56,6 +56,16 @@ module GitlabMarkdownHelper @markdown.render(text).html_safe end + def asciidoc(text) + Gitlab::Asciidoc.render(text, { + commit: @commit, + project: @project, + project_wiki: @project_wiki, + requested_path: @path, + ref: @ref + }) + end + # Return the first line of +text+, up to +max_chars+, after parsing the line # as Markdown. HTML tags in the parsed output are not counted toward the # +max_chars+ limit. If the length limit falls within a tag's contents, then @@ -67,8 +77,11 @@ module GitlabMarkdownHelper end def render_wiki_content(wiki_page) - if wiki_page.format == :markdown + case wiki_page.format + when :markdown markdown(wiki_page.content) + when :asciidoc + asciidoc(wiki_page.content) else wiki_page.formatted_content.html_safe end diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 6dd9b6f017c..c03564a71ab 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -27,6 +27,8 @@ module TreeHelper def render_readme(readme) if gitlab_markdown?(readme.name) preserve(markdown(readme.data)) + elsif asciidoc?(readme.name) + asciidoc(readme.data) elsif markup?(readme.name) render_markup(readme.name, readme.data) else diff --git a/lib/gitlab/asciidoc.rb b/lib/gitlab/asciidoc.rb new file mode 100644 index 00000000000..bf33e5b1b1e --- /dev/null +++ b/lib/gitlab/asciidoc.rb @@ -0,0 +1,60 @@ +require 'asciidoctor' +require 'html/pipeline' + +module Gitlab + # Parser/renderer for the AsciiDoc format that uses Asciidoctor and filters + # the resulting HTML through HTML pipeline filters. + module Asciidoc + + # Provide autoload paths for filters to prevent a circular dependency error + autoload :RelativeLinkFilter, 'gitlab/markdown/relative_link_filter' + + DEFAULT_ADOC_ATTRS = [ + 'showtitle', 'idprefix=user-content-', 'idseparator=-', 'env=gitlab', + 'env-gitlab', 'source-highlighter=html-pipeline' + ].freeze + + # Public: Converts the provided Asciidoc markup into HTML. + # + # input - the source text in Asciidoc format + # context - a Hash with the template context: + # :commit + # :project + # :project_wiki + # :requested_path + # :ref + # asciidoc_opts - a Hash of options to pass to the Asciidoctor converter + # html_opts - a Hash of options for HTML output: + # :xhtml - output XHTML instead of HTML + # + def self.render(input, context, asciidoc_opts = {}, html_opts = {}) + asciidoc_opts = asciidoc_opts.reverse_merge( + safe: :secure, + backend: html_opts[:xhtml] ? :xhtml5 : :html5, + attributes: [] + ) + asciidoc_opts[:attributes].unshift(*DEFAULT_ADOC_ATTRS) + + html = ::Asciidoctor.convert(input, asciidoc_opts) + + if context[:project] + result = HTML::Pipeline.new(filters).call(html, context) + + save_opts = html_opts[:xhtml] ? + Nokogiri::XML::Node::SaveOptions::AS_XHTML : 0 + + html = result[:output].to_html(save_with: save_opts) + end + + html.html_safe + end + + private + + def self.filters + [ + Gitlab::Markdown::RelativeLinkFilter + ] + end + end +end diff --git a/lib/gitlab/markdown_helper.rb b/lib/gitlab/markdown_helper.rb index 5e3cfc0585b..70384b1db2c 100644 --- a/lib/gitlab/markdown_helper.rb +++ b/lib/gitlab/markdown_helper.rb @@ -9,7 +9,7 @@ module Gitlab # Returns boolean def markup?(filename) filename.downcase.end_with?(*%w(.textile .rdoc .org .creole .wiki - .mediawiki .rst .adoc .asciidoc .asc)) + .mediawiki .rst .adoc .ad .asciidoc)) end # Public: Determines if a given filename is compatible with @@ -22,6 +22,15 @@ module Gitlab filename.downcase.end_with?(*%w(.mdown .md .markdown)) end + # Public: Determines if the given filename has AsciiDoc extension. + # + # filename - Filename string to check + # + # Returns boolean + def asciidoc?(filename) + filename.downcase.end_with?(*%w(.adoc .ad .asciidoc)) + end + def previewable?(filename) gitlab_markdown?(filename) || markup?(filename) end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index d4cf6540080..59870dfb192 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -261,12 +261,19 @@ describe ApplicationHelper do end end - describe 'markup_render' do + describe 'render_markup' do let(:content) { 'Noël' } it 'should preserve encoding' do expect(content.encoding.name).to eq('UTF-8') expect(render_markup('foo.rst', content).encoding.name).to eq('UTF-8') end + + it "should delegate to #asciidoc when file name corresponds to AsciiDoc" do + expect(self).to receive(:asciidoc?).with('foo.adoc').and_return(true) + expect(self).to receive(:asciidoc).and_return('NOEL') + + expect(render_markup('foo.adoc', content)).to eq('NOEL') + end end end diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 9f3e8cf585e..0d0418f84a7 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -110,6 +110,14 @@ describe GitlabMarkdownHelper do helper.render_wiki_content(@wiki) end + it "should use Asciidoctor for asciidoc files" do + allow(@wiki).to receive(:format).and_return(:asciidoc) + + expect(helper).to receive(:asciidoc).with('wiki content') + + helper.render_wiki_content(@wiki) + end + it "should use the Gollum renderer for all other file types" do allow(@wiki).to receive(:format).and_return(:rdoc) formatted_content_stub = double('formatted_content') diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb new file mode 100644 index 00000000000..23f83339ec5 --- /dev/null +++ b/spec/lib/gitlab/asciidoc_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' +require 'nokogiri' + +module Gitlab + describe Asciidoc do + + let(:input) { 'ascii' } + let(:context) { {} } + let(:html) { 'H2O' } + + context "without project" do + + it "should convert the input using Asciidoctor and default options" do + expected_asciidoc_opts = { safe: :secure, backend: :html5, + attributes: described_class::DEFAULT_ADOC_ATTRS } + + expect(Asciidoctor).to receive(:convert) + .with(input, expected_asciidoc_opts).and_return(html) + + expect( render(input, context) ).to eql html + end + + context "with asciidoc_opts" do + + let(:asciidoc_opts) { {safe: :safe, attributes: ['foo']} } + + it "should merge the options with default ones" do + expected_asciidoc_opts = { safe: :safe, backend: :html5, + attributes: described_class::DEFAULT_ADOC_ATTRS + ['foo'] } + + expect(Asciidoctor).to receive(:convert) + .with(input, expected_asciidoc_opts).and_return(html) + + render(input, context, asciidoc_opts) + end + end + end + + context "with project in context" do + + let(:context) { {project: create(:project)} } + + it "should filter converted input via HTML pipeline and return result" do + filtered_html = 'ASCII' + + allow(Asciidoctor).to receive(:convert).and_return(html) + expect_any_instance_of(HTML::Pipeline).to receive(:call) + .with(html, context) + .and_return(output: Nokogiri::HTML.fragment(filtered_html)) + + expect( render('foo', context) ).to eql filtered_html + end + end + + def render(*args) + described_class.render(*args) + end + end +end diff --git a/spec/lib/gitlab/gitlab_markdown_helper_spec.rb b/spec/lib/gitlab/gitlab_markdown_helper_spec.rb index ab613193f41..beaafd56352 100644 --- a/spec/lib/gitlab/gitlab_markdown_helper_spec.rb +++ b/spec/lib/gitlab/gitlab_markdown_helper_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::MarkdownHelper do describe '#markup?' do %w(textile rdoc org creole wiki - mediawiki rst adoc asciidoc asc).each do |type| + mediawiki rst adoc ad asciidoc).each do |type| it "returns true for #{type} files" do expect(Gitlab::MarkdownHelper.markup?("README.#{type}")).to be_truthy end @@ -25,4 +25,16 @@ describe Gitlab::MarkdownHelper do expect(Gitlab::MarkdownHelper.gitlab_markdown?('README.rb')).not_to be_truthy end end + + describe '#asciidoc?' do + %w(adoc ad asciidoc ADOC).each do |type| + it "returns true for #{type} files" do + expect(Gitlab::MarkdownHelper.asciidoc?("README.#{type}")).to be_truthy + end + end + + it 'returns false when given a non-asciidoc filename' do + expect(Gitlab::MarkdownHelper.asciidoc?('README.rb')).not_to be_truthy + end + end end From 92133a89a42c219478b0cb8496d0efa377bd60b3 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Thu, 14 May 2015 20:00:16 +0200 Subject: [PATCH 3/3] Add changelog items for #9288 --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 2c368751376..d170e6d27c3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,8 @@ v 7.11.0 (unreleased) - Spin spinner icon next to "Checking for CI status..." on MR page. - Fix reference links in dashboard activity and ATOM feeds. - Ensure that the first added admin performs repository imports + - Update Asciidoctor gem to version 1.5.2. (Jakub Jirutka) + - Fix resolving of relative links to repository files in AsciiDoc documents. (Jakub Jirutka) v 7.10.2 - Fix CI links on MR page