Commit 3b690891 authored by Robert Speicher's avatar Robert Speicher

Basic support for an Atom-specific rendering pipeline

parent 4bd92e68
......@@ -47,15 +47,16 @@ module GitlabMarkdownHelper
def markdown(text, context = {})
return unless text.present?
context.merge!(
context.reverse_merge!(
path: @path,
pipeline: :default,
project: @project,
project_wiki: @project_wiki,
ref: @ref
)
html = Gitlab::Markdown.render(text, context)
Gitlab::Markdown.post_process(html, current_user)
Gitlab::Markdown.post_process(html, pipeline: context[:pipeline], user: current_user)
end
# TODO (rspeicher): Remove all usages of this helper and just call `markdown`
......@@ -63,15 +64,16 @@ module GitlabMarkdownHelper
def gfm(text, options = {})
return unless text.present?
options.merge!(
options.reverse_merge!(
path: @path,
pipeline: :default,
project: @project,
project_wiki: @project_wiki,
ref: @ref
)
html = Gitlab::Markdown.gfm(text, options)
Gitlab::Markdown.post_process(html, current_user)
Gitlab::Markdown.post_process(html, pipeline: options[:pipeline], user: current_user)
end
def asciidoc(text)
......
%div{xmlns: "http://www.w3.org/1999/xhtml"}
= markdown(issue.description, xhtml: true, reference_only_path: false, project: issue.project)
= markdown(issue.description, pipeline: :atom, project: issue.project)
%div{xmlns: "http://www.w3.org/1999/xhtml"}
= markdown(merge_request.description, xhtml: true, reference_only_path: false, project: merge_request.project)
= markdown(merge_request.description, pipeline: :atom, project: merge_request.project)
%div{xmlns: "http://www.w3.org/1999/xhtml"}
= markdown(note.note, xhtml: true, reference_only_path: false, project: note.project)
= markdown(note.note, pipeline: :atom, project: note.project)
......@@ -6,7 +6,7 @@
%i
at
= commit[:timestamp].to_time.to_s(:short)
%blockquote= markdown(escape_once(commit[:message]), xhtml: true, reference_only_path: false, project: event.project)
%blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project)
- if event.commits_count > 15
%p
%i
......
......@@ -7,6 +7,14 @@ module Gitlab
module Markdown
# Convert a Markdown String into an HTML-safe String of HTML
#
# Note that while the returned HTML will have been sanitized of dangerous
# HTML, it may post a risk of information leakage if it's not also passed
# through `post_process`.
#
# Also note that the returned String is always HTML, not XHTML. Views
# requiring XHTML, such as Atom feeds, need to call `post_process` on the
# result, providing the appropriate `pipeline` option.
#
# markdown - Markdown String
# context - Hash of context options passed to our HTML Pipeline
#
......@@ -38,15 +46,19 @@ module Gitlab
# permission to make (`RedactorFilter`).
#
# html - String to process
# for_user - User state
# options - Hash of options to customize output
# :pipeline - Symbol pipeline type
# :user - User object
#
# Returns an HTML-safe String
def self.post_process(html, for_user)
result = post_processor.call(html, current_user: for_user)
result[:output].
to_html.
html_safe
def self.post_process(html, options)
doc = post_processor.to_document(html, current_user: options[:user])
if options[:pipeline] == :atom
doc.to_html(save_with: Nokogiri::XML::Node::SaveOptions::AS_XHTML)
else
doc.to_html
end.html_safe
end
# Provide autoload paths for filters to prevent a circular dependency error
......@@ -68,26 +80,20 @@ module Gitlab
autoload :TaskListFilter, 'gitlab/markdown/task_list_filter'
autoload :UserReferenceFilter, 'gitlab/markdown/user_reference_filter'
# Public: Parse the provided text with GitLab-Flavored Markdown
# Public: Parse the provided HTML with GitLab-Flavored Markdown
#
# text - the source text
# options - A Hash of options used to customize output (default: {}):
# :xhtml - output XHTML instead of HTML
# :reference_only_path - Use relative path for reference links
def self.gfm(text, options = {})
return text if text.nil?
# Duplicate the string so we don't alter the original, then call to_str
# to cast it back to a String instead of a SafeBuffer. This is required
# for gsub calls to work as we need them to.
text = text.dup.to_str
options.reverse_merge!(
xhtml: false,
reference_only_path: true,
project: options[:project],
current_user: options[:current_user]
)
# html - HTML String
# options - A Hash of options used to customize output (default: {})
# :no_header_anchors - Disable header anchors in TableOfContentsFilter
# :path - Current path String
# :pipeline - Symbol pipeline type
# :project - Current Project object
# :project_wiki - Current ProjectWiki object
# :ref - Current ref String
#
# Returns an HTML-safe String
def self.gfm(html, options = {})
return '' unless html.present?
@pipeline ||= HTML::Pipeline.new(filters)
......@@ -96,47 +102,39 @@ module Gitlab
pipeline: options[:pipeline],
# EmojiFilter
asset_root: Gitlab.config.gitlab.url,
asset_host: Gitlab::Application.config.asset_host,
# TableOfContentsFilter
no_header_anchors: options[:no_header_anchors],
asset_root: Gitlab.config.gitlab.url,
# ReferenceFilter
only_path: options[:reference_only_path],
project: options[:project],
only_path: only_path_pipeline?(options[:pipeline]),
project: options[:project],
# RelativeLinkFilter
project_wiki: options[:project_wiki],
ref: options[:ref],
requested_path: options[:path],
project_wiki: options[:project_wiki]
}
result = @pipeline.call(text, context)
save_options = 0
if options[:xhtml]
save_options |= Nokogiri::XML::Node::SaveOptions::AS_XHTML
end
text = result[:output].to_html(save_with: save_options)
# TableOfContentsFilter
no_header_anchors: options[:no_header_anchors]
}
text.html_safe
@pipeline.to_html(html, context).html_safe
end
private
def self.renderer
@markdown ||= begin
renderer = Redcarpet::Render::HTML.new
Redcarpet::Markdown.new(renderer, redcarpet_options)
# Check if a pipeline enables the `only_path` context option
#
# Returns Boolean
def self.only_path_pipeline?(pipeline)
case pipeline
when :atom, :email
false
else
true
end
end
def self.post_processor
@post_processor ||= HTML::Pipeline.new([Gitlab::Markdown::RedactorFilter])
end
def self.redcarpet_options
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@redcarpet_options ||= {
......@@ -151,6 +149,17 @@ module Gitlab
}.freeze
end
def self.renderer
@markdown ||= begin
renderer = Redcarpet::Render::HTML.new
Redcarpet::Markdown.new(renderer, redcarpet_options)
end
end
def self.post_processor
@post_processor ||= HTML::Pipeline.new([Gitlab::Markdown::RedactorFilter])
end
# Filters used in our pipeline
#
# SanitizationFilter should come first so that all generated reference HTML
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment