diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb index 111982e9147ed5627ca4fda209f25d11263529ab..e737f0a6b6bdd5286f5299f39d0a936a7e6ab008 100644 --- a/app/helpers/gitlab_markdown_helper.rb +++ b/app/helpers/gitlab_markdown_helper.rb @@ -26,7 +26,7 @@ module GitlabMarkdownHelper unless @markdown gitlab_renderer = Redcarpet::Render::GitlabHTML.new(self, # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch- - filter_html: true, + filter_html: false, with_toc_data: true, hard_wrap: true) @markdown = Redcarpet::Markdown.new(gitlab_renderer, @@ -44,3 +44,4 @@ module GitlabMarkdownHelper @markdown.render(text).html_safe end end + diff --git a/app/views/help/markdown.html.haml b/app/views/help/markdown.html.haml index aa608ed6d9a96269b64bab565eeed97c431b584c..97254d8f38777b76627141f9779f7b6d4542d3a2 100644 --- a/app/views/help/markdown.html.haml +++ b/app/views/help/markdown.html.haml @@ -60,6 +60,25 @@ GFM will autolink standard URLs you copy and paste into your text. So if you want to link to a URL (instead of a textual link), you can simply put the URL in verbatim and it will be turned into a link to that URL. + %h4 Tables + +.row + .span8 + %p + GFM will generate tables if you use PHP-Markdown Extra like syntax: + %pre= %Q{First Header | Second Header\n---------------|---------------\nContent Cell 1 | Content Cell 2\nContent Cell 3 | Content Cell 4\nContent Cell 5 | Content Cell 6} + %p becomes + = markdown %Q{First Header | Second Header\n---------------|---------------\nContent Cell 1 | Content Cell 2\nContent Cell 3 | Content Cell 4\nContent Cell 5 | Content Cell 6} + + .span4 + .alert.alert-info + %p + Consult the + %strong= link_to "PHP-Markdown Extra Tables", "http://michelf.ca/projects/php-markdown/extra/#table" + for more details. + +.row + .span8 %h4 Fenced code blocks %p @@ -71,6 +90,16 @@ %p becomes = markdown %Q{```ruby\nrequire 'redcarpet'\nmarkdown = Redcarpet.new("Hello World!")\nputs markdown.to_html\n```} + %h4 Table of contents (TOC) generation + + %p + GFM can automatically generate a TOC from the headers in the text. + To have the TOC generated just place ~toc~ on the first line. + + %pre= %Q{~toc~\n# Header 1\n## Header 2\n# Header 1} + %p becomes + = markdown %Q{* [Header 1](#toc_0)\n * [Header 2](#toc_1)\n* [Header 1](#toc_2)\n\n# Header 1\n## Header 2\n# Header 1} + %h4 Emoji .row @@ -94,6 +123,15 @@ .row .span8 + %h4 Custom HTML + + %p + If you still want to, you can use custom HTML for specific tasks. + + %pre= %Q{\n

This line is in HTML

\n
} + %p becomes + = markdown %Q{\n

This line is in HTML

\n
} + %h4 Special GitLab references %p diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 9eb35b84d42528f94afb00e39dc4a8d853512ac6..e57812e6245f1b2cb0197e70e033c550b7e7aabb 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -73,7 +73,7 @@ module Gitlab extractions[$1] end - sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class) + sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class), tags: ActionView::Base.sanitized_allowed_tags + %w(table tr td th) end private @@ -88,6 +88,7 @@ module Gitlab def parse(text) parse_references(text) if @project parse_emoji(text) + text = parse_toc(text) text end @@ -122,6 +123,35 @@ module Gitlab end end + # If the user wants TOC we run a Render::HTML_TOC + # See http://dev.af83.com/2012/02/27/howto-extend-the-redcarpet2-markdown-lib.html + # TODO: Allow TOC to be placed in the middle of the document, not only at top + def parse_toc(text) + if text.lines.first.match("~toc~") != nil + html_text = text.dup.to_str + + # First we must convert HTML headers back to Markdown headers + html_text.gsub!(/]*>/, "# ") + html_text.gsub!(/]*>/, "## ") + html_text.gsub!(/]*>/, "### ") + html_text.gsub!(/]*>/, "#### ") + html_text.gsub!(/]*>/, "##### ") + html_text.gsub!(/]*>/, "###### ") + + html_text.gsub!(/<\/?h\d[^>]*>/, "") + + + html_toc = Redcarpet::Markdown.new(Redcarpet::Render::HTML_TOC, space_after_headers: true) + toc = html_toc.render(html_text) + + text["~toc~"]= "" + + toc + text + else + text + end + end + # Private: Checks if an emoji icon exists in the image asset directory # # emoji - Identifier of the emoji as a string (e.g., "+1", "heart")