Skip to content
Snippets Groups Projects
Commit 72c6be2d authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Merge pull request #1183 from riyad/gitlab-flavored-markdown

Gitlab flavored markdown
parents c120457a 5443021a
No related branches found
No related tags found
No related merge requests found
Showing
with 126 additions and 56 deletions
Loading
Loading
@@ -90,6 +90,7 @@ class RefsController < ApplicationController
 
@repo = project.repo
@commit = project.commit(@ref)
@commit = CommitDecorator.decorate(@commit)
@tree = Tree.new(@commit.tree, project, @ref, params[:path])
@tree = TreeDecorator.new(@tree)
@hex_path = Digest::SHA1.hexdigest(params[:path] || "/")
Loading
Loading
Loading
Loading
@@ -42,8 +42,88 @@ module ApplicationHelper
grouped_options_for_select(options, @ref || @project.default_branch)
end
 
def gfm(text, html_options = {})
return text if text.nil?
raise "@project is not set" if @project.nil?
# Extract pre blocks
# from http://github.github.com/github-flavored-markdown/
extractions = {}
text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) do |match|
md5 = Digest::MD5.hexdigest(match)
extractions[md5] = match
"{gfm-extraction-#{md5}}"
end
# match 1 2 3 4 5 6
text.gsub!(/(\W)?(@([\w\._]+)|[#!$](\d+)|([\h]{6,40}))(\W)?/) do |match|
prefix = $1
reference = $2
user_name = $3
issue_id = $4
merge_request_id = $4
snippet_id = $4
commit_id = $5
suffix = $6
# TODO: add popups with additional information
ref_link = case reference
# team member: @foo
when /^@/
user = @project.users.where(:name => user_name).first
member = @project.users_projects.where(:user_id => user).first if user
link_to("@#{user_name}", project_team_member_path(@project, member), html_options.merge(:class => "gfm gfm-team_member #{html_options[:class]}")) if member
# issue: #123
when /^#/
# avoid HTML entities
unless prefix.try(:end_with?, "&") && suffix.try(:start_with?, ";")
issue = @project.issues.where(:id => issue_id).first
link_to("##{issue_id}", project_issue_path(@project, issue), html_options.merge(:title => "Issue: #{issue.title}", :class => "gfm gfm-issue #{html_options[:class]}")) if issue
end
# merge request: !123
when /^!/
merge_request = @project.merge_requests.where(:id => merge_request_id).first
link_to("!#{merge_request_id}", project_merge_request_path(@project, merge_request), html_options.merge(:title => "Merge Request: #{merge_request.title}", :class => "gfm gfm-merge_request #{html_options[:class]}")) if merge_request
# snippet: $123
when /^\$/
snippet = @project.snippets.where(:id => snippet_id).first
link_to("$#{snippet_id}", project_snippet_path(@project, snippet), html_options.merge(:title => "Snippet: #{snippet.title}", :class => "gfm gfm-snippet #{html_options[:class]}")) if snippet
# commit: 123456...
when /^\h/
commit = @project.commit(commit_id)
link_to(commit_id, project_commit_path(@project, :id => commit.id), html_options.merge(:title => "Commit: #{commit.author_name} - #{CommitDecorator.new(commit).title}", :class => "gfm gfm-commit #{html_options[:class]}")) if commit
end # case
ref_link.nil? ? match : "#{prefix}#{ref_link}#{suffix}"
end # gsub
# Insert pre block extractions
text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
extractions[$1]
end
text.html_safe
end
# circumvents nesting links, which will behave bad in browsers
def link_to_gfm(body, url, html_options = {})
gfm_body = gfm(body, html_options)
gfm_body.gsub!(%r{<a.*?>.*?</a>}m) do |match|
"</a>#{match}#{link_to("", url, html_options)[0..-5]}" # "</a>".length +1
end
link_to(gfm_body.html_safe, url, html_options)
end
def markdown(text)
@__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new({ filter_html: true, with_toc_data: true }), {
@__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new(self, filter_html: true, with_toc_data: true), {
no_intra_emphasis: true,
tables: true,
fenced_code_blocks: true,
Loading
Loading
module CommitsHelper
def commit_msg_with_link_to_issues(project, message)
return '' unless message
out = ''
message.split(/(#[0-9]+)/m).each do |m|
if m =~ /(#([0-9]+))/m
begin
issue = project.issues.find($2)
out += link_to($1, project_issue_path(project, $2))
rescue
out += $1
end
else
out += m
end
end
preserve out
end
def identification_type(line)
if line[0] == "+"
"new"
Loading
Loading
Loading
Loading
@@ -16,59 +16,69 @@ class Notify < ActionMailer::Base
 
def new_issue_email(issue_id)
@issue = Issue.find(issue_id)
mail(:to => @issue.assignee_email, :subject => "gitlab | New Issue was created")
@project = @issue.project
mail(:to => @issue.assignee_email, :subject => "gitlab | new issue ##{@issue.id} | #{@issue.title} | #{@project.name}")
end
 
def note_wall_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
mail(:to => recipient.email, :subject => "gitlab | #{@note.project_name} ")
@project = @note.project
mail(:to => recipient.email, :subject => "gitlab | #{@project.name}")
end
 
def note_commit_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@commit = @note.target
mail(:to => recipient.email, :subject => "gitlab | note for commit | #{@note.project_name} ")
@commit = CommitDecorator.decorate(@commit)
@project = @note.project
mail(:to => recipient.email, :subject => "gitlab | note for commit #{@commit.short_id} | #{@commit.title} | #{@project.name}")
end
 
def note_merge_request_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@merge_request = @note.noteable
mail(:to => recipient.email, :subject => "gitlab | note for merge request | #{@note.project_name} ")
@project = @note.project
mail(:to => recipient.email, :subject => "gitlab | note for merge request !#{@merge_request.id} | #{@project.name}")
end
 
def note_issue_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@issue = @note.noteable
mail(:to => recipient.email, :subject => "gitlab | note for issue #{@issue.id} | #{@note.project_name} ")
@project = @note.project
mail(:to => recipient.email, :subject => "gitlab | note for issue ##{@issue.id} | #{@project.name}")
end
 
def note_wiki_email(recipient_id, note_id)
recipient = User.find(recipient_id)
@note = Note.find(note_id)
@wiki = @note.noteable
mail(:to => recipient.email, :subject => "gitlab | note for wiki | #{@note.project_name}")
@project = @note.project
mail(:to => recipient.email, :subject => "gitlab | note for wiki | #{@project.name}")
end
 
def new_merge_request_email(merge_request_id)
@merge_request = MergeRequest.find(merge_request_id)
mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request | #{@merge_request.title} ")
@project = @merge_request.project
mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}")
end
 
def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
recipient = User.find(recipient_id)
@merge_request = MergeRequest.find(merge_request_id)
@previous_assignee ||= User.find(previous_assignee_id)
mail(:to => recipient.email, :subject => "gitlab | merge request changed | #{@merge_request.title} ")
@project = @merge_request.project
mail(:to => recipient.email, :subject => "gitlab | changed merge request !#{@merge_request.id} | #{@merge_request.title} | #{@project.name}")
end
 
def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
recipient = User.find(recipient_id)
@issue = Issue.find(issue_id)
@previous_assignee ||= User.find(previous_assignee_id)
mail(:to => recipient.email, :subject => "gitlab | changed issue | #{@issue.title} ")
@project = @issue.project
mail(:to => recipient.email, :subject => "gitlab | changed issue ##{@issue.id} | #{@issue.title} | #{@project.name}")
end
end
Loading
Loading
@@ -7,7 +7,7 @@
%strong.cgray= commit.author_name
&ndash;
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
= link_to truncate(commit.title, :length => 50), project_commit_path(@project, :id => commit.id), :class => "row_title"
= link_to_gfm truncate(commit.title, :length => 50), project_commit_path(@project, :id => commit.id), :class => "row_title"
 
%span.committed_ago
= time_ago_in_words(commit.committed_date)
Loading
Loading
Loading
Loading
@@ -11,10 +11,10 @@
= link_to tree_project_ref_path(@project, @commit.id), :class => "browse-button primary grouped" do
%strong Browse Code »
%h3.commit-title.page_title
= commit_msg_with_link_to_issues(@project, @commit.title)
= gfm @commit.title
- if @commit.description.present?
%pre.commit-description
= commit_msg_with_link_to_issues(@project, @commit.description)
= gfm @commit.description
.commit-info
.row
.span4
Loading
Loading
Loading
Loading
@@ -17,7 +17,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.name commit.author_name
xml.email commit.author_email
end
xml.summary commit.description
xml.summary gfm(commit.description)
end
end
end
Loading
Loading
@@ -8,8 +8,8 @@
- if @issues.any?
- @issues.group_by(&:project).each do |group|
%div.ui-box
- project = group[0]
%h5= project.name
- @project = group[0]
%h5= @project.name
%ul.unstyled.issues_table
- group[1].each do |issue|
= render(:partial => 'issues/show', :locals => {:issue => issue})
Loading
Loading
Loading
Loading
@@ -7,8 +7,8 @@
- if @merge_requests.any?
- @merge_requests.group_by(&:project).each do |group|
%ul.unstyled.ui-box
- project = group[0]
%h5= project.name
- @project = group[0]
%h5= @project.name
- group[1].each do |merge_request|
= render(:partial => 'merge_requests/merge_request', :locals => {:merge_request => merge_request})
%hr
Loading
Loading
Loading
Loading
@@ -5,5 +5,5 @@
%strong.cdark= commit.author_name
&ndash;
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
= truncate(commit.title, :length => 50) rescue "--broken encoding"
= gfm truncate(commit.title, :length => 50), project_commit_path(project, :id => commit.id) rescue "--broken encoding"
 
Loading
Loading
@@ -25,7 +25,7 @@
- else
= image_tag "no_avatar.png", :class => "avatar"
 
%p= link_to truncate(issue.title, :length => 100), project_issue_path(issue.project, issue), :class => "row_title"
%p= link_to_gfm truncate(issue.title, :length => 100), project_issue_path(issue.project, issue), :class => "row_title"
 
%span.update-author
%small.cdark= "##{issue.id}"
Loading
Loading
Loading
Loading
@@ -31,7 +31,7 @@
.alert-message.error.status_info Closed
- else
.alert-message.success.status_info Open
= @issue.title
= gfm @issue.title
 
.middle_box_content
%cite.cgray Created by
Loading
Loading
@@ -46,7 +46,7 @@
- if @issue.milestone
- milestone = @issue.milestone
%cite.cgray and attached to milestone
%strong= link_to truncate(milestone.title, :length => 20), project_milestone_path(milestone.project, milestone)
%strong= link_to_gfm truncate(milestone.title, :length => 20), project_milestone_path(milestone.project, milestone)
 
.right
- @issue.labels.each do |label|
Loading
Loading
Loading
Loading
@@ -16,7 +16,7 @@
= merge_request.target_branch
= image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
 
%p= link_to truncate(merge_request.title, :length => 80), project_merge_request_path(merge_request.project, merge_request), :class => "row_title"
%p= link_to_gfm truncate(merge_request.title, :length => 80), project_merge_request_path(merge_request.project, merge_request), :class => "row_title"
 
%span.update-author
%small.cdark= "##{merge_request.id}"
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@
.alert-message.error.status_info Closed
- else
.alert-message.success.status_info Open
= @merge_request.title
= gfm @merge_request.title
 
.middle_box_content
%div
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@
- if can? current_user, :admin_milestone, milestone.project
= link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), :class => "btn small edit-milestone-link grouped"
%h4
= link_to truncate(milestone.title, :length => 100), project_milestone_path(milestone.project, milestone), :class => "row_title"
= link_to_gfm truncate(milestone.title, :length => 100), project_milestone_path(milestone.project, milestone), :class => "row_title"
%small
= milestone.expires_at
%br
Loading
Loading
Loading
Loading
@@ -21,7 +21,7 @@
.alert-message.error.status_info Closed
- else
.alert-message.success.status_info Open
= @milestone.title
= gfm @milestone.title
%small.right= @milestone.expires_at
 
.middle_box_content
Loading
Loading
@@ -51,7 +51,7 @@
= link_to [@project, issue] do
%span.badge.badge-info ##{issue.id}
&ndash;
= link_to truncate(issue.title, :length => 60), [@project, issue]
= link_to_gfm truncate(issue.title, :length => 60), [@project, issue]
%br
= paginate @issues, :theme => "gitlab"
 
Loading
Loading
Loading
Loading
@@ -10,7 +10,6 @@
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%td{:align => "left", :style => "padding: 20px 0 0;"}
%h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
= link_to project_issue_url(@issue.project, @issue), :title => @issue.title do
= "Issue ##{@issue.id.to_s}"
= truncate(@issue.title, :length => 45)
= "Issue ##{@issue.id}"
= link_to_gfm truncate(@issue.title, :length => 45), project_issue_url(@issue.project, @issue), :title => @issue.title
%br
Loading
Loading
@@ -4,8 +4,8 @@
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%td{:align => "left", :style => "padding: 20px 0 0;"}
%h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
New Merge Request
= link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request)
= "New Merge Request !#{@merge_request.id}"
= link_to_gfm truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request)
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%tr
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
Loading
Loading
Loading
Loading
@@ -4,8 +4,8 @@
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%td{:align => "left", :style => "padding: 20px 0 0;"}
%h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
New comment for commit
= link_to truncate(@commit.id.to_s, :length => 16), project_commit_url(@note.project, :id => @commit.id, :anchor => "note_#{@note.id}")
= "New comment for Commit #{@commit.short_id}"
= link_to_gfm truncate(@commit.title, :length => 16), project_commit_url(@note.project, :id => @commit.id, :anchor => "note_#{@note.id}")
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%tr
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
Loading
Loading
Loading
Loading
@@ -4,10 +4,8 @@
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%td{:align => "left", :style => "padding: 20px 0 0;"}
%h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
New comment -
= link_to project_issue_url(@issue.project, @issue, :anchor => "note_#{@note.id}") do
= "Issue ##{@issue.id.to_s}"
= truncate(@issue.title, :length => 35)
= "New comment for Issue ##{@issue.id}"
= link_to_gfm truncate(@issue.title, :length => 35), project_issue_url(@issue.project, @issue, :anchor => "note_#{@note.id}")
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%tr
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment