summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2015-10-21 12:18:23 +0200
committerDouwe Maan <douwe@gitlab.com>2015-10-21 12:32:30 +0200
commitabbca6151d66ebc227c883af35cd01cf4d7e24eb (patch)
treeb23adb0d3b63c365b40306dae64c037c265812eb /lib
parentde0acf3cf7f27e7a4f32dc8cad6293f823eda300 (diff)
downloadgitlab-ce-abbca6151d66ebc227c883af35cd01cf4d7e24eb.tar.gz
Make pipelines actually make sense
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/markdown.rb216
-rw-r--r--lib/gitlab/markdown/asciidoc_pipeline.rb13
-rw-r--r--lib/gitlab/markdown/atom_pipeline.rb14
-rw-r--r--lib/gitlab/markdown/combined_pipeline.rb25
-rw-r--r--lib/gitlab/markdown/description_pipeline.rb14
-rw-r--r--lib/gitlab/markdown/email_pipeline.rb13
-rw-r--r--lib/gitlab/markdown/full_pipeline.rb9
-rw-r--r--lib/gitlab/markdown/gfm_pipeline.rb41
-rw-r--r--lib/gitlab/markdown/note_pipeline.rb14
-rw-r--r--lib/gitlab/markdown/pipeline.rb29
-rw-r--r--lib/gitlab/markdown/plain_markdown_pipeline.rb13
-rw-r--r--lib/gitlab/markdown/post_process_pipeline.rb20
-rw-r--r--lib/gitlab/markdown/reference_extraction_pipeline.rb13
-rw-r--r--lib/gitlab/markdown/single_line_pipeline.rb9
14 files changed, 265 insertions, 178 deletions
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index 5c4481e6497..3ae4ccfacb6 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -35,14 +35,8 @@ module Gitlab
end
def self.render_result(text, context = {})
- pipeline = context[:pipeline] ||= :full
-
- html_pipeline = html_pipelines[pipeline]
-
- transformers = context_transformers[pipeline]
- context = transformers.reduce(context) { |context, transformer| transformer.call(context) }
-
- html_pipeline.call(text, context)
+ pipeline_type = context[:pipeline] ||= :full
+ pipeline_by_type(pipeline_type).call(text, context)
end
# Perform post-processing on an HTML String
@@ -59,17 +53,37 @@ module Gitlab
#
# Returns an HTML-safe String
def self.post_process(html, context)
- html_pipeline = html_pipelines[:post_process]
+ pipeline = pipeline_by_type(:post_process)
if context[:xhtml]
- html_pipeline.to_document(html, context).to_html(save_with: Nokogiri::XML::Node::SaveOptions::AS_XHTML)
+ pipeline.to_document(html, context).to_html(save_with: Nokogiri::XML::Node::SaveOptions::AS_XHTML)
else
- html_pipeline.to_html(html, context)
+ pipeline.to_html(html, context)
end.html_safe
end
private
+ def self.cacheless_render(text, context = {})
+ result = render_result(text, context)
+ output = result[:output]
+ if output.respond_to?(:to_html)
+ output.to_html
+ else
+ output.to_s
+ end
+ end
+
+ def self.full_cache_key(cache_key, pipeline = :full)
+ return unless cache_key
+
+ ["markdown", *cache_key, pipeline]
+ end
+
+ def self.pipeline_by_type(pipeline_type)
+ const_get("#{pipeline_type.to_s.camelize}Pipeline")
+ end
+
# Provide autoload paths for filters to prevent a circular dependency error
autoload :AutolinkFilter, 'gitlab/markdown/autolink_filter'
autoload :CommitRangeReferenceFilter, 'gitlab/markdown/commit_range_reference_filter'
@@ -91,172 +105,18 @@ module Gitlab
autoload :UserReferenceFilter, 'gitlab/markdown/user_reference_filter'
autoload :UploadLinkFilter, 'gitlab/markdown/upload_link_filter'
- def self.gfm_filters
- @gfm_filters ||= [
- Gitlab::Markdown::SyntaxHighlightFilter,
- Gitlab::Markdown::SanitizationFilter,
-
- Gitlab::Markdown::UploadLinkFilter,
- Gitlab::Markdown::EmojiFilter,
- Gitlab::Markdown::TableOfContentsFilter,
- Gitlab::Markdown::AutolinkFilter,
- Gitlab::Markdown::ExternalLinkFilter,
-
- Gitlab::Markdown::UserReferenceFilter,
- Gitlab::Markdown::IssueReferenceFilter,
- Gitlab::Markdown::ExternalIssueReferenceFilter,
- Gitlab::Markdown::MergeRequestReferenceFilter,
- Gitlab::Markdown::SnippetReferenceFilter,
- Gitlab::Markdown::CommitRangeReferenceFilter,
- Gitlab::Markdown::CommitReferenceFilter,
- Gitlab::Markdown::LabelReferenceFilter,
-
- Gitlab::Markdown::TaskListFilter
- ]
- end
-
- def self.all_filters
- @all_filters ||= {
- plain_markdown: [
- Gitlab::Markdown::MarkdownFilter
- ],
- gfm: gfm_filters,
-
- full: [:plain_markdown, :gfm],
- atom: :full,
- email: :full,
- description: :full,
- note: :full,
- single_line: :gfm,
-
- asciidoc: [
- Gitlab::Markdown::RelativeLinkFilter
- ],
-
- post_process: [
- Gitlab::Markdown::RelativeLinkFilter,
- Gitlab::Markdown::RedactorFilter
- ],
-
- reference_extraction: [
- Gitlab::Markdown::ReferenceGathererFilter
- ]
- }
- end
-
- def self.all_context_transformers
- @all_context_transformers ||= {
- gfm: {
- only_path: true,
-
- # EmojiFilter
- asset_host: Gitlab::Application.config.asset_host,
- asset_root: Gitlab.config.gitlab.base_url
- },
- full: :gfm,
-
- atom: [
- :full,
- {
- only_path: false,
- xhtml: true
- }
- ],
- email: [
- :full,
- {
- only_path: false
- }
- ],
- note: [
- :full,
- {
- # TableOfContentsFilter
- no_header_anchors: true
- }
- ],
- description: [
- :full,
- {
- # SanitizationFilter
- inline_sanitization: true
- }
- ],
- single_line: :gfm,
-
- post_process: {
- post_process: true
- }
- }
- end
-
- def self.html_filters
- @html_filters ||= Hash.new do |hash, pipeline|
- filters = get_filters(pipeline)
- hash[pipeline] = filters if pipeline.is_a?(Symbol)
- filters
- end
- end
-
- def self.html_pipelines
- @html_pipelines ||= Hash.new do |hash, pipeline|
- filters = get_filters(pipeline)
- html_pipeline = HTML::Pipeline.new(filters)
- hash[pipeline] = html_pipeline if pipeline.is_a?(Symbol)
- html_pipeline
- end
- end
-
- def self.context_transformers
- @context_transformers ||= Hash.new do |hash, pipeline|
- transformers = get_context_transformers(pipeline)
- hash[pipeline] = transformers if pipeline.is_a?(Symbol)
- transformers
- end
- end
-
- def self.get_filters(pipelines)
- Array.wrap(pipelines).flat_map do |pipeline|
- case pipeline
- when Class
- pipeline
- when Symbol
- html_filters[all_filters[pipeline]]
- when Array
- html_filters[pipeline]
- end
- end.compact
- end
-
- def self.get_context_transformers(pipelines)
- Array.wrap(pipelines).flat_map do |pipeline|
- case pipeline
- when Hash
- ->(context) { context.merge(pipeline) }
- when Proc
- pipeline
- when Symbol
- context_transformers[all_context_transformers[pipeline]]
- when Array
- context_transformers[pipeline]
- end
- end.compact
- end
-
- def self.cacheless_render(text, context = {})
- result = render_result(text, context)
- output = result[:output]
- if output.respond_to?(:to_html)
- output.to_html
- else
- output.to_s
- end
- end
-
- def self.full_cache_key(cache_key, pipeline = :full)
- return unless cache_key && pipeline.is_a?(Symbol)
-
- ["markdown", *cache_key, pipeline]
- end
+ autoload :AsciidocPipeline, 'gitlab/markdown/asciidoc_pipeline'
+ autoload :AtomPipeline, 'gitlab/markdown/atom_pipeline'
+ autoload :CombinedPipeline, 'gitlab/markdown/combined_pipeline'
+ autoload :DescriptionPipeline, 'gitlab/markdown/description_pipeline'
+ autoload :EmailPipeline, 'gitlab/markdown/email_pipeline'
+ autoload :FullPipeline, 'gitlab/markdown/full_pipeline'
+ autoload :GfmPipeline, 'gitlab/markdown/gfm_pipeline'
+ autoload :NotePipeline, 'gitlab/markdown/note_pipeline'
+ autoload :Pipeline, 'gitlab/markdown/pipeline'
+ autoload :PlainMarkdownPipeline, 'gitlab/markdown/plain_markdown_pipeline'
+ autoload :PostProcessPipeline, 'gitlab/markdown/post_process_pipeline'
+ autoload :ReferenceExtractionPipeline, 'gitlab/markdown/reference_extraction_pipeline'
+ autoload :SingleLinePipeline, 'gitlab/markdown/single_line_pipeline'
end
end
diff --git a/lib/gitlab/markdown/asciidoc_pipeline.rb b/lib/gitlab/markdown/asciidoc_pipeline.rb
new file mode 100644
index 00000000000..6829b4acb95
--- /dev/null
+++ b/lib/gitlab/markdown/asciidoc_pipeline.rb
@@ -0,0 +1,13 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class AsciidocPipeline < Pipeline
+ def self.filters
+ [
+ Gitlab::Markdown::RelativeLinkFilter
+ ]
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/atom_pipeline.rb b/lib/gitlab/markdown/atom_pipeline.rb
new file mode 100644
index 00000000000..e151f8f5e5a
--- /dev/null
+++ b/lib/gitlab/markdown/atom_pipeline.rb
@@ -0,0 +1,14 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class AtomPipeline < FullPipeline
+ def self.transform_context(context)
+ super(context).merge(
+ only_path: false,
+ xhtml: true
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/combined_pipeline.rb b/lib/gitlab/markdown/combined_pipeline.rb
new file mode 100644
index 00000000000..a3d717550f5
--- /dev/null
+++ b/lib/gitlab/markdown/combined_pipeline.rb
@@ -0,0 +1,25 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ module CombinedPipeline
+ def self.new(*pipelines)
+ Class.new(Pipeline) do
+ const_set :PIPELINES, pipelines
+
+ def self.filters
+ pipelines.flat_map(&:filters)
+ end
+
+ def self.transform_context(context)
+ pipelines.reduce(context) { |context, pipeline| pipeline.transform_context(context) }
+ end
+
+ def self.pipelines
+ self::PIPELINES
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/description_pipeline.rb b/lib/gitlab/markdown/description_pipeline.rb
new file mode 100644
index 00000000000..76f6948af8f
--- /dev/null
+++ b/lib/gitlab/markdown/description_pipeline.rb
@@ -0,0 +1,14 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class DescriptionPipeline < FullPipeline
+ def self.transform_context(context)
+ super(context).merge(
+ # SanitizationFilter
+ inline_sanitization: true
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/email_pipeline.rb b/lib/gitlab/markdown/email_pipeline.rb
new file mode 100644
index 00000000000..b88cb790270
--- /dev/null
+++ b/lib/gitlab/markdown/email_pipeline.rb
@@ -0,0 +1,13 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class EmailPipeline < FullPipeline
+ def self.transform_context(context)
+ super(context).merge(
+ only_path: false
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/full_pipeline.rb b/lib/gitlab/markdown/full_pipeline.rb
new file mode 100644
index 00000000000..553e9367c1c
--- /dev/null
+++ b/lib/gitlab/markdown/full_pipeline.rb
@@ -0,0 +1,9 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class FullPipeline < CombinedPipeline.new(PlainMarkdownPipeline, GfmPipeline)
+
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/gfm_pipeline.rb b/lib/gitlab/markdown/gfm_pipeline.rb
new file mode 100644
index 00000000000..ca90bd75d77
--- /dev/null
+++ b/lib/gitlab/markdown/gfm_pipeline.rb
@@ -0,0 +1,41 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class GfmPipeline < Pipeline
+ def self.filters
+ @filters ||= [
+ Gitlab::Markdown::SyntaxHighlightFilter,
+ Gitlab::Markdown::SanitizationFilter,
+
+ Gitlab::Markdown::UploadLinkFilter,
+ Gitlab::Markdown::EmojiFilter,
+ Gitlab::Markdown::TableOfContentsFilter,
+ Gitlab::Markdown::AutolinkFilter,
+ Gitlab::Markdown::ExternalLinkFilter,
+
+ Gitlab::Markdown::UserReferenceFilter,
+ Gitlab::Markdown::IssueReferenceFilter,
+ Gitlab::Markdown::ExternalIssueReferenceFilter,
+ Gitlab::Markdown::MergeRequestReferenceFilter,
+ Gitlab::Markdown::SnippetReferenceFilter,
+ Gitlab::Markdown::CommitRangeReferenceFilter,
+ Gitlab::Markdown::CommitReferenceFilter,
+ Gitlab::Markdown::LabelReferenceFilter,
+
+ Gitlab::Markdown::TaskListFilter
+ ]
+ end
+
+ def self.transform_context(context)
+ context.merge(
+ only_path: true,
+
+ # EmojiFilter
+ asset_host: Gitlab::Application.config.asset_host,
+ asset_root: Gitlab.config.gitlab.base_url
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/note_pipeline.rb b/lib/gitlab/markdown/note_pipeline.rb
new file mode 100644
index 00000000000..a8bf5f42d8e
--- /dev/null
+++ b/lib/gitlab/markdown/note_pipeline.rb
@@ -0,0 +1,14 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class NotePipeline < FullPipeline
+ def self.transform_context(context)
+ super(context).merge(
+ # TableOfContentsFilter
+ no_header_anchors: true
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/pipeline.rb b/lib/gitlab/markdown/pipeline.rb
new file mode 100644
index 00000000000..3c0b676a073
--- /dev/null
+++ b/lib/gitlab/markdown/pipeline.rb
@@ -0,0 +1,29 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class Pipeline
+ def self.filters
+ []
+ end
+
+ def self.transform_context(context)
+ context
+ end
+
+ def self.html_pipeline
+ @html_pipeline ||= HTML::Pipeline.new(filters)
+ end
+
+ class << self
+ %i(call to_document to_html).each do |meth|
+ define_method(meth) do |text, context|
+ context = transform_context(context)
+
+ html_pipeline.send(meth, text, context)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/plain_markdown_pipeline.rb b/lib/gitlab/markdown/plain_markdown_pipeline.rb
new file mode 100644
index 00000000000..0abb93f8a03
--- /dev/null
+++ b/lib/gitlab/markdown/plain_markdown_pipeline.rb
@@ -0,0 +1,13 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class PlainMarkdownPipeline < Pipeline
+ def self.filters
+ [
+ Gitlab::Markdown::MarkdownFilter
+ ]
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/post_process_pipeline.rb b/lib/gitlab/markdown/post_process_pipeline.rb
new file mode 100644
index 00000000000..60cc32f490e
--- /dev/null
+++ b/lib/gitlab/markdown/post_process_pipeline.rb
@@ -0,0 +1,20 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class PostProcessPipeline < Pipeline
+ def self.filters
+ [
+ Gitlab::Markdown::RelativeLinkFilter,
+ Gitlab::Markdown::RedactorFilter
+ ]
+ end
+
+ def self.transform_context(context)
+ context.merge(
+ post_process: true
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/reference_extraction_pipeline.rb b/lib/gitlab/markdown/reference_extraction_pipeline.rb
new file mode 100644
index 00000000000..a89ab462bac
--- /dev/null
+++ b/lib/gitlab/markdown/reference_extraction_pipeline.rb
@@ -0,0 +1,13 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class ReferenceExtractionPipeline < Pipeline
+ def self.filters
+ [
+ Gitlab::Markdown::ReferenceGathererFilter
+ ]
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/markdown/single_line_pipeline.rb b/lib/gitlab/markdown/single_line_pipeline.rb
new file mode 100644
index 00000000000..2f24927b879
--- /dev/null
+++ b/lib/gitlab/markdown/single_line_pipeline.rb
@@ -0,0 +1,9 @@
+require 'gitlab/markdown'
+
+module Gitlab
+ module Markdown
+ class SingleLinePipeline < GfmPipeline
+
+ end
+ end
+end