Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
GitLab
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
projects.thm.de
GitLab
Commits
ed41333a
Commit
ed41333a
authored
Oct 14, 2015
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Gitlab::Markdown.render with :pipeline option rather than different methods
parent
4a5b7718
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
181 additions
and
177 deletions
+181
-177
app/helpers/gitlab_markdown_helper.rb
app/helpers/gitlab_markdown_helper.rb
+10
-27
app/views/events/_commit.html.haml
app/views/events/_commit.html.haml
+1
-1
app/views/projects/commit/_commit_box.html.haml
app/views/projects/commit/_commit_box.html.haml
+2
-2
app/views/projects/commits/_commit.html.haml
app/views/projects/commits/_commit.html.haml
+1
-1
app/views/projects/issues/show.html.haml
app/views/projects/issues/show.html.haml
+1
-1
app/views/projects/merge_requests/show/_mr_box.html.haml
app/views/projects/merge_requests/show/_mr_box.html.haml
+1
-1
app/views/projects/merge_requests/widget/_open.html.haml
app/views/projects/merge_requests/widget/_open.html.haml
+1
-1
app/views/projects/milestones/show.html.haml
app/views/projects/milestones/show.html.haml
+1
-1
app/views/projects/repositories/_feed.html.haml
app/views/projects/repositories/_feed.html.haml
+1
-1
lib/gitlab/markdown.rb
lib/gitlab/markdown.rb
+112
-124
lib/gitlab/markdown/markdown_filter.rb
lib/gitlab/markdown/markdown_filter.rb
+39
-0
lib/gitlab/markdown/relative_link_filter.rb
lib/gitlab/markdown/relative_link_filter.rb
+1
-1
lib/gitlab/markdown/sanitization_filter.rb
lib/gitlab/markdown/sanitization_filter.rb
+1
-5
lib/gitlab/reference_extractor.rb
lib/gitlab/reference_extractor.rb
+9
-11
No files found.
app/helpers/gitlab_markdown_helper.rb
View file @
ed41333a
...
...
@@ -20,7 +20,7 @@ def link_to_gfm(body, url, html_options = {})
end
user
=
current_user
if
defined?
(
current_user
)
gfm_body
=
Gitlab
::
Markdown
.
gfm
(
escaped_body
,
project:
@project
,
current_user:
user
)
gfm_body
=
Gitlab
::
Markdown
.
render
(
escaped_body
,
project:
@project
,
current_user:
user
,
pipeline: :single_line
)
fragment
=
Nokogiri
::
HTML
::
DocumentFragment
.
parse
(
gfm_body
)
if
fragment
.
children
.
size
==
1
&&
fragment
.
children
[
0
].
name
==
'a'
...
...
@@ -48,37 +48,20 @@ def link_to_gfm(body, url, html_options = {})
def
markdown
(
text
,
context
=
{})
return
""
unless
text
.
present?
context
.
reverse_merge!
(
path:
@path
,
pipeline: :default
,
project:
@project
,
project_wiki:
@project_wiki
,
ref:
@ref
)
user
=
current_user
if
defined?
(
current_user
)
context
[
:project
]
||=
@project
html
=
Gitlab
::
Markdown
.
render
(
text
,
context
)
Gitlab
::
Markdown
.
post_process
(
html
,
pipeline:
context
[
:pipeline
],
project:
@project
,
user:
user
)
end
# TODO (rspeicher): Remove all usages of this helper and just call `markdown`
# with a custom pipeline depending on the content being rendered
def
gfm
(
text
,
options
=
{})
return
""
unless
text
.
present?
context
.
merge!
(
current_user:
(
current_user
if
defined?
(
current_user
)),
options
.
reverse_merge!
(
path:
@path
,
pipeline: :default
,
project:
@project
,
project_wiki:
@project_wiki
,
ref:
@ref
# RelativeLinkFilter
requested_path:
@path
,
project_wiki:
@project_wiki
,
ref:
@ref
)
user
=
current_user
if
defined?
(
current_user
)
html
=
Gitlab
::
Markdown
.
gfm
(
text
,
options
)
Gitlab
::
Markdown
.
post_process
(
html
,
pipeline:
options
[
:pipeline
],
project:
@project
,
user:
user
)
Gitlab
::
Markdown
.
post_process
(
html
,
context
)
end
def
asciidoc
(
text
)
...
...
app/views/events/_commit.html.haml
View file @
ed41333a
...
...
@@ -2,4 +2,4 @@
.commit-row-title
=
link_to
truncate_sha
(
commit
[
:id
]),
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
[
:id
]),
class:
"commit_short_id"
,
alt:
''
·
=
gfm
event_commit_title
(
commit
[
:message
]),
project:
project
=
markdown
event_commit_title
(
commit
[
:message
]),
project:
project
,
pipeline: :single_line
app/views/projects/commit/_commit_box.html.haml
View file @
ed41333a
...
...
@@ -50,10 +50,10 @@
.commit-box.gray-content-block.middle-block
%h3
.commit-title
=
gfm
escape_once
(
@commit
.
title
)
=
markdown
escape_once
(
@commit
.
title
),
pipeline: :single_line
-
if
@commit
.
description
.
present?
%pre
.commit-description
=
preserve
(
gfm
(
escape_once
(
@commit
.
description
)
))
=
preserve
(
markdown
(
escape_once
(
@commit
.
description
),
pipeline: :single_line
))
:coffeescript
$(".commit-info-row.branches").load("
#{
branches_namespace_project_commit_path
(
@project
.
namespace
,
@project
,
@commit
.
id
)
}
")
app/views/projects/commits/_commit.html.haml
View file @
ed41333a
...
...
@@ -32,7 +32,7 @@
-
if
commit
.
description?
.commit-row-description.js-toggle-content
%pre
=
preserve
(
gfm
(
escape_once
(
commit
.
description
)
))
=
preserve
(
markdown
(
escape_once
(
commit
.
description
),
pipeline: :single_line
))
.commit-row-info
=
commit_author_link
(
commit
,
avatar:
true
,
size:
24
)
...
...
app/views/projects/issues/show.html.haml
View file @
ed41333a
...
...
@@ -37,7 +37,7 @@
.gray-content-block.middle-block
%h2
.issue-title
=
gfm
escape_once
(
@issue
.
title
)
=
markdown
escape_once
(
@issue
.
title
),
pipeline: :single_line
%div
-
if
@issue
.
description
.
present?
.description
{
class:
can?
(
current_user
,
:update_issue
,
@issue
)
?
'js-task-list-container'
:
''
}
...
...
app/views/projects/merge_requests/show/_mr_box.html.haml
View file @
ed41333a
.gray-content-block.middle-block
%h2
.issue-title
=
gfm
escape_once
(
@merge_request
.
title
)
=
markdown
escape_once
(
@merge_request
.
title
),
pipeline: :single_line
%div
-
if
@merge_request
.
description
.
present?
...
...
app/views/projects/merge_requests/widget/_open.html.haml
View file @
ed41333a
...
...
@@ -24,4 +24,4 @@
%i
.fa.fa-check
Accepting this merge request will close
#{
"issue"
.
pluralize
(
@closes_issues
.
size
)
}
=
succeed
'.'
do
!=
gfm
(
issues_sentence
(
@closes_issues
))
!=
markdown
issues_sentence
(
@closes_issues
),
pipeline: :gfm
app/views/projects/milestones/show.html.haml
View file @
ed41333a
...
...
@@ -31,7 +31,7 @@
%span
All issues for this milestone are closed. You may close milestone now.
%h3
.issue-title
=
gfm
escape_once
(
@milestone
.
title
)
=
markdown
escape_once
(
@milestone
.
title
),
pipeline: :single_line
%div
-
if
@milestone
.
description
.
present?
.description
...
...
app/views/projects/repositories/_feed.html.haml
View file @
ed41333a
...
...
@@ -12,7 +12,7 @@
=
link_to
namespace_project_commits_path
(
@project
.
namespace
,
@project
,
commit
.
id
)
do
%code
=
commit
.
short_id
=
image_tag
avatar_icon
(
commit
.
author_email
),
class:
""
,
width:
16
,
alt:
''
=
gfm
escape_once
(
truncate
(
commit
.
title
,
length:
40
))
=
markdown
escape_once
(
truncate
(
commit
.
title
,
length:
40
)),
pipeline: :single_line
%td
%span
.pull-right.cgray
=
time_ago_with_tooltip
(
commit
.
committed_date
)
lib/gitlab/markdown.rb
View file @
ed41333a
...
...
@@ -19,51 +19,15 @@ module Markdown
# context - Hash of context options passed to our HTML Pipeline
#
# Returns an HTML-safe String
def
self
.
render
(
markdown
,
context
=
{})
html
=
renderer
.
render
(
markdown
)
html
=
gfm
(
html
,
context
)
def
self
.
render
(
text
,
context
=
{})
pipeline
=
context
[
:pipeline
]
||
:full
html
.
html_safe
end
html_pipeline
=
html_pipelines
[
pipeline
]
# Convert a Markdown String into HTML without going through the HTML
# Pipeline.
#
# Note that because the pipeline is skipped, SanitizationFilter is as well.
# Do not output the result of this method to the user.
#
# markdown - Markdown String
#
# Returns a String
def
self
.
render_without_gfm
(
markdown
)
renderer
.
render
(
markdown
)
end
transformers
=
get_context_transformers
(
pipeline
)
context
=
transformers
.
reduce
(
context
)
{
|
context
,
transformer
|
transformer
.
call
(
context
)
}
# Perform post-processing on an HTML String
#
# This method is used to perform state-dependent changes to a String of
# HTML, such as removing references that the current user doesn't have
# permission to make (`RedactorFilter`).
#
# html - String to process
# options - Hash of options to customize output
# :pipeline - Symbol pipeline type
# :project - Project
# :user - User object
#
# Returns an HTML-safe String
def
self
.
post_process
(
html
,
options
)
context
=
{
project:
options
[
:project
],
current_user:
options
[
:user
]
}
doc
=
post_processor
.
to_document
(
html
,
context
)
if
options
[
:pipeline
]
==
:atom
doc
.
to_html
(
save_with:
Nokogiri
::
XML
::
Node
::
SaveOptions
::
AS_XHTML
)
else
doc
.
to_html
end
.
html_safe
html_pipeline
.
to_html
(
text
,
context
)
end
# Provide autoload paths for filters to prevent a circular dependency error
...
...
@@ -75,6 +39,7 @@ def self.post_process(html, options)
autoload
:ExternalLinkFilter
,
'gitlab/markdown/external_link_filter'
autoload
:IssueReferenceFilter
,
'gitlab/markdown/issue_reference_filter'
autoload
:LabelReferenceFilter
,
'gitlab/markdown/label_reference_filter'
autoload
:MarkdownFilter
,
'gitlab/markdown/markdown_filter'
autoload
:MergeRequestReferenceFilter
,
'gitlab/markdown/merge_request_reference_filter'
autoload
:RedactorFilter
,
'gitlab/markdown/redactor_filter'
autoload
:RelativeLinkFilter
,
'gitlab/markdown/relative_link_filter'
...
...
@@ -85,98 +50,38 @@ def self.post_process(html, options)
autoload
:TaskListFilter
,
'gitlab/markdown/task_list_filter'
autoload
:UserReferenceFilter
,
'gitlab/markdown/user_reference_filter'
# Public: Parse the provided HTML with GitLab-Flavored Markdown
# Perform post-processing on an HTML String
#
# This method is used to perform state-dependent changes to a String of
# HTML, such as removing references that the current user doesn't have
# permission to make (`RedactorFilter`).
#
# 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
# html - String to process
# context - Hash of options to customize output
# :pipeline - Symbol pipeline type
# :project - Project
# :user - User object
#
# Returns an HTML-safe String
def
self
.
gfm
(
html
,
options
=
{})
return
''
unless
html
.
present?
@pipeline
||=
HTML
::
Pipeline
.
new
(
filters
)
context
=
{
# SanitizationFilter
pipeline:
options
[
:pipeline
],
# EmojiFilter
asset_host:
Gitlab
::
Application
.
config
.
asset_host
,
asset_root:
Gitlab
.
config
.
gitlab
.
base_url
,
# ReferenceFilter
only_path:
only_path_pipeline?
(
options
[
:pipeline
]),
project:
options
[
:project
],
# RelativeLinkFilter
project_wiki:
options
[
:project_wiki
],
ref:
options
[
:ref
],
requested_path:
options
[
:path
],
# TableOfContentsFilter
no_header_anchors:
options
[
:no_header_anchors
]
}
def
self
.
post_process
(
html
,
context
)
doc
=
html_pipelines
[
:post_process
].
to_document
(
html
,
context
)
@pipeline
.
to_html
(
html
,
context
).
html_safe
end
private
# Check if a pipeline enables the `only_path` context option
#
# Returns Boolean
def
self
.
only_path_pipeline?
(
pipeline
)
case
pipeline
when
:atom
,
:email
false
if
context
[
:xhtml
]
doc
.
to_html
(
save_with:
Nokogiri
::
XML
::
Node
::
SaveOptions
::
AS_XHTML
)
else
true
end
end
def
self
.
redcarpet_options
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@redcarpet_options
||=
{
fenced_code_blocks:
true
,
footnotes:
true
,
lax_spacing:
true
,
no_intra_emphasis:
true
,
space_after_headers:
true
,
strikethrough:
true
,
superscript:
true
,
tables:
true
}.
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
])
doc
.
to_html
end
.
html_safe
end
# Filters used in our pipeline
#
# SanitizationFilter should come first so that all generated reference HTML
# goes through untouched.
#
# See https://github.com/jch/html-pipeline#filters for more filters.
def
self
.
filters
[
private
FILTERS
=
{
plain_markdown:
[
Gitlab
::
Markdown
::
MarkdownFilter
],
gfm:
[
Gitlab
::
Markdown
::
SyntaxHighlightFilter
,
Gitlab
::
Markdown
::
SanitizationFilter
,
Gitlab
::
Markdown
::
RelativeLinkFilter
,
Gitlab
::
Markdown
::
EmojiFilter
,
Gitlab
::
Markdown
::
TableOfContentsFilter
,
Gitlab
::
Markdown
::
AutolinkFilter
,
...
...
@@ -192,7 +97,90 @@ def self.filters
Gitlab
::
Markdown
::
LabelReferenceFilter
,
Gitlab
::
Markdown
::
TaskListFilter
],
full:
[
:plain_markdown
,
:gfm
],
atom: :full
,
email: :full
,
description: :full
,
single_line: :gfm
,
post_process:
[
Gitlab
::
Markdown
::
RelativeLinkFilter
,
Gitlab
::
Markdown
::
RedactorFilter
]
}
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
}
],
description:
[
:full
,
{
# SanitizationFilter
inline_sanitization:
true
}
],
single_line: :gfm
,
post_process:
{
post_process:
true
}
}
def
self
.
html_pipelines
@html_pipelines
||=
Hash
.
new
do
|
hash
,
pipeline
|
filters
=
get_filters
(
pipeline
)
HTML
::
Pipeline
.
new
(
filters
)
end
end
def
self
.
get_filters
(
pipelines
)
Array
.
wrap
(
pipelines
).
flat_map
do
|
pipeline
|
case
pipeline
when
Class
pipeline
when
Symbol
get_filters
(
FILTERS
[
pipeline
])
when
Array
get_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
get_context_transformers
(
CONTEXT_TRANSFORMERS
[
pipeline
])
when
Array
get_context_transformers
(
pipeline
)
end
end
.
compact
end
end
end
lib/gitlab/markdown/markdown_filter.rb
0 → 100644
View file @
ed41333a
module
Gitlab
module
Markdown
class
MarkdownFilter
<
HTML
::
Pipeline
::
TextFilter
def
initialize
(
text
,
context
=
nil
,
result
=
nil
)
super
text
,
context
,
result
@text
=
@text
.
gsub
"
\r
"
,
''
end
def
call
html
=
self
.
class
.
renderer
.
render
(
@text
)
html
.
rstrip!
html
end
private
def
self
.
redcarpet_options
# https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
@redcarpet_options
||=
{
fenced_code_blocks:
true
,
footnotes:
true
,
lax_spacing:
true
,
no_intra_emphasis:
true
,
space_after_headers:
true
,
strikethrough:
true
,
superscript:
true
,
tables:
true
}.
freeze
end
def
self
.
renderer
@renderer
||=
begin
renderer
=
Redcarpet
::
Render
::
HTML
.
new
Redcarpet
::
Markdown
.
new
(
renderer
,
redcarpet_options
)
end
end
end
end
end
lib/gitlab/markdown/relative_link_filter.rb
View file @
ed41333a
...
...
@@ -16,7 +16,7 @@ class RelativeLinkFilter < HTML::Pipeline::Filter
def
call
return
doc
unless
linkable_files?
doc
.
search
(
'a'
).
each
do
|
el
|
doc
.
search
(
'a
:not(.gfm)
'
).
each
do
|
el
|
process_link_attr
el
.
attribute
(
'href'
)
end
...
...
lib/gitlab/markdown/sanitization_filter.rb
View file @
ed41333a
...
...
@@ -11,7 +11,7 @@ class SanitizationFilter < HTML::Pipeline::SanitizationFilter
def
whitelist
# Descriptions are more heavily sanitized, allowing only a few elements.
# See http://git.io/vkuAN
if
pipeline
==
:description
if
context
[
:inline_sanitization
]
whitelist
=
LIMITED
whitelist
[
:elements
]
-=
%w(pre code img ol ul li)
else
...
...
@@ -25,10 +25,6 @@ def whitelist
private
def
pipeline
context
[
:pipeline
]
||
:default
end
def
customized?
(
transformers
)
transformers
.
last
.
source_location
[
0
]
==
__FILE__
end
...
...
lib/gitlab/reference_extractor.rb
View file @
ed41333a
...
...
@@ -13,7 +13,8 @@ def initialize(project, current_user = nil, load_lazy_references: true)
def
analyze
(
text
)
references
.
clear
@text
=
Gitlab
::
Markdown
.
render_without_gfm
(
text
)
@document
=
Gitlab
::
Markdown
.
render
(
text
,
project:
project
)
end
%i(user label issue merge_request snippet commit commit_range)
.
each
do
|
type
|
...
...
@@ -44,20 +45,13 @@ def pipeline_result(filter_type)
filter
=
Gitlab
::
Markdown
.
const_get
(
klass
)
context
=
{
project:
project
,
current_user:
current_user
,
# We don't actually care about the links generated
only_path:
true
,
ignore_blockquotes:
true
,
# ReferenceGathererFilter
project:
project
,
current_user:
current_user
,
load_lazy_references:
false
,
reference_filter:
filter
}
pipeline
=
HTML
::
Pipeline
.
new
([
filter
,
Gitlab
::
Markdown
::
ReferenceGathererFilter
],
context
)
result
=
pipeline
.
call
(
@text
)
result
=
self
.
class
.
pipeline
.
call
(
@document
,
context
)
values
=
result
[
:references
][
filter_type
].
uniq
...
...
@@ -67,5 +61,9 @@ def pipeline_result(filter_type)
values
end
def
self
.
pipeline
@pipeline
||=
HTML
::
Pipeline
.
new
([
Gitlab
::
Markdown
::
ReferenceGathererFilter
])
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment