diff --git a/app/controllers/markdown_controller.rb b/app/controllers/markdown_controller.rb index 93d4d3b6..137ed1ef 100644 --- a/app/controllers/markdown_controller.rb +++ b/app/controllers/markdown_controller.rb @@ -1,14 +1,5 @@ class MarkdownController < ApplicationController - skip_before_action :authenticate_user!, only: [:preview] - respond_to :js - def preview - if params[:source] - markdown_source = params[:source].to_str.gsub(/(?<=^|\s):([\w+-]+):(?=\s|$)/) do |match| - %(![add-emoji](https://github.githubassets.com/images/icons/emoji/#{match.to_str.tr(':', '')}.png)) - end - end - @rendered = MarkdownHelper.render markdown_source - respond_with @rendered + @markdown_source = helpers.enrich_markdown(markdown: params[:source]) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2be35b8e..98599ad6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -21,12 +21,4 @@ def active_page_size(page_size, param = nil) 'active' end end - - def emojify(content) - if content.present? - content.to_str.gsub(/(?<=^|\s):([\w+-]+):(?=\s|$)/) do |match| - %(![add-emoji](https://github.githubassets.com/images/icons/emoji/#{match.to_str.tr(':', '')}.png)) - end.html_safe - end - end end diff --git a/app/helpers/markdown_helper.rb b/app/helpers/markdown_helper.rb index 0ec16acb..a81529e7 100644 --- a/app/helpers/markdown_helper.rb +++ b/app/helpers/markdown_helper.rb @@ -1,9 +1,22 @@ module MarkdownHelper - def self.render(markdown_source) - Haml::Filters::Markdown.new.render markdown_source + def mdpreview(markdown_source, lines: 3) + markdown_source.lines[0..lines - 1].join end - def mdpreview(markdown_source, lines: 3) - markdown_source.lines.grep_v(/\[comment\]/).grep(/\S/)[0..lines - 1].join + def enrich_markdown(markdown:) + # replace :smiley: with a link to github.com emojis + markdown.gsub!(/(?<=^|\s):([\w+-]+):(?=\s|$)/) do |match| + %(![add-emoji](https://github.githubassets.com/images/icons/emoji/#{match.to_str.tr(':', '')}.png)) + end + # replace @hans with a link to the user with the login hans + markdown.gsub!(/([^\w]|^)@([-\w]+)([^\w]|$)/) do + "#{Regexp.last_match(1)}[@#{Regexp.last_match(2)}](#{::Rails.application.routes.url_helpers(only_path: true).user_path(Regexp.last_match(2))})#{Regexp.last_match(3)}" + end + # replace hw#my-project with a link to the project with the slug my-project + markdown.gsub!(/([^\w]|^)hw#([-\w]+)([^\w]|$)/) do + "#{Regexp.last_match(1)}[hw##{Regexp.last_match(2)}](#{::Rails.application.routes.url_helpers(only_path: true).project_path(Regexp.last_match(2))})#{Regexp.last_match(3)}" + end + + markdown end end diff --git a/app/views/comments/_comment.html.haml b/app/views/comments/_comment.html.haml index ce1c010c..8533196d 100644 --- a/app/views/comments/_comment.html.haml +++ b/app/views/comments/_comment.html.haml @@ -16,7 +16,7 @@ Edit %p :markdown - #{ emojify comment.text } + #{ enrich_markdown(markdown: comment.text) } - if !comment.comments.empty? %ul.media-list = render :partial => 'comments/comment', :collection => comment.comments, object: comment @@ -46,7 +46,7 @@ .modal-body %p :markdown - #{ emojify comment.text } + #{ enrich_markdown(markdown: comment.text) } %hr #replyform = render partial: 'comments/form', locals: { comment: @new_comment, parent: comment, id: rand(36**10).to_s(36).upcase[0,5] } diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 61a9e868..4ff6643d 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -13,7 +13,7 @@ .comment-form-body .tab-content .tab-pane.active.fade.in{ role: 'tab-pane', id: "markdown-source#{id}" } - = f.text_area :text, :placeholder => "Your comment. You can use markdown.", :class => 'form-control input-lg markdown-source-text', :required => "required" + = f.text_area :text, :placeholder => "Your comment. You can use markdown.", :class => 'form-control input-lg', :required => "required" .tab-pane.fade{ role: 'tab-pane', id: "markdown-preview#{id}" } .loading-spinner = icon('fas', 'spinner pulse 3x') diff --git a/app/views/comments/_help.html.haml b/app/views/comments/_help.html.haml index 77f44d75..caa59ffb 100644 --- a/app/views/comments/_help.html.haml +++ b/app/views/comments/_help.html.haml @@ -8,12 +8,13 @@ Use two asterisks for **strong emphasis** - * Use asterisks - * for lists + - Use hyphens + - for unordereed + - lists - This is an [example link](http://example.com/) + This is an [link to example.com](http://example.com/) - This is an ![example image](http://paste.opensuse.org/view/raw/68957446) + This is an image ![an openSUSE geeko icon](https://en.opensuse.org/images/d/d0/Icon-distribution.png) This is a user link @hans diff --git a/app/views/keywords/edit.html.haml b/app/views/keywords/edit.html.haml index c2ae5ac6..9d684d8d 100644 --- a/app/views/keywords/edit.html.haml +++ b/app/views/keywords/edit.html.haml @@ -15,7 +15,7 @@ .form-group = f.label('Description (maximum 255 characters)') - = f.text_area :description, maxlength: "255", rows: 5, id: 'keyword_description', class: 'form-control input-lg markdown-source-text' + = f.text_area :description, maxlength: "255", rows: 5, id: 'keyword_description', class: 'form-control input-lg' .form-group = f.label('Keyword Logo (Will be resized to 150x150 Pixels)') = f.file_field :avatar diff --git a/app/views/markdown/_preview.html.haml b/app/views/markdown/_preview.html.haml new file mode 100644 index 00000000..df2172a4 --- /dev/null +++ b/app/views/markdown/_preview.html.haml @@ -0,0 +1,2 @@ +:markdown + #{markdown_source} diff --git a/app/views/markdown/preview.js.erb b/app/views/markdown/preview.js.erb index 5c46d7ff..bcc3864b 100644 --- a/app/views/markdown/preview.js.erb +++ b/app/views/markdown/preview.js.erb @@ -1,4 +1,4 @@ -$('#<%= params[:form_parent]%> .preview-contents').html("<%=j raw @rendered %>"); +$('#<%= params[:form_parent]%> .preview-contents').html("<%= escape_javascript(render partial: 'preview', locals: { markdown_source: @markdown_source }) %>"); $('#<%= params[:form_parent]%> .loading-spinner').addClass('hidden'); $('#<%= params[:form_parent]%> .preview-contents').removeClass('hidden'); $('input[name="authenticity_token"]').val('<%= form_authenticity_token %>'); diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 8de36055..c6f875d2 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -28,7 +28,7 @@ #markdown-source.tab-pane.active.fade.in{ role: 'tab-pane' } .form-group = f.text_area :description, rows: 20, id: 'project_description', - class: 'form-control input-lg markdown-source-text' + class: 'form-control input-lg' #markdown-preview.tab-pane.fade{ role: 'tab-pane' } .loading-spinner = icon('fas', 'spinner pulse 3x') diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 4c57d69e..16f7f830 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -3,5 +3,16 @@ .row .col-sm-12.project - %h2 Create a project + %h2 + Create a project + %p + Please use the description to give an overview about the state of your project. + %ul + %li + What are your goals to be achieved at the end of this Hack Week? + %li + What kind collaboration are you looking for, which skills are needed? + %li + Link to sources, documentation or your detailed project plan. + You can edit this at any time later and provide updates = render 'form' diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index d70c09c6..15a7b102 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -27,7 +27,7 @@ .row .col-sm-8.project-style :markdown - #{ emojify @project.description } + #{ enrich_markdown(markdown: @project.description) } .col-sm-4 .row .col-sm-12 diff --git a/config/new_project_template.md b/config/new_project_template.md index 4452bc7e..6575a515 100644 --- a/config/new_project_template.md +++ b/config/new_project_template.md @@ -1,20 +1,8 @@ -[comment]: # (Please use the project description to give an overview and updates) -[comment]: # (about the current state of your project) -[comment]: # (Why do you start this project, what's your interest?) +## Description -## Project Description +## Goals -[comment]: # (What are your goals to be achieved at the end of this Hackweek?) - -## Goal for this Hackweek - - -[comment]: # (Please link to sources and other data here.) -[comment]: # (Prefer public repositories, such as GitHub!) ## Resources -[comment]: # (After creating the project, please add some keywords:) -[comment]: # (* What type of project mates are you looking for, which skills do you need or lack?) -[comment]: # (* Which keywords will help other people to find your project?) diff --git a/lib/haml/filters/markdown.rb b/lib/haml/filters/markdown.rb deleted file mode 100644 index 8c6c5256..00000000 --- a/lib/haml/filters/markdown.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'redcarpet' -require 'rouge/plugins/redcarpet' - -module Haml - class Filters - class Markdown < TiltBase - # remove_filter('Markdown') # remove the existing Markdown filter - - class RougeRender < ::Redcarpet::Render::HTML - include Rouge::Plugins::Redcarpet - end - - def render(text) - # replace @user with a link to user - text.gsub!(/([^\w]|^)@([-\w]+)([^\w]|$)/) do - "#{Regexp.last_match(1)}[@#{Regexp.last_match(2)}](#{::Rails.application.routes.url_helpers(only_path: true).user_path(Regexp.last_match(2))})#{Regexp.last_match(3)}" - end - # replace hw#slug with a link to project - text.gsub!(/([^\w]|^)hw#([-\w]+)([^\w]|$)/) do - "#{Regexp.last_match(1)}[hw##{Regexp.last_match(2)}](#{::Rails.application.routes.url_helpers(only_path: true).project_path(Regexp.last_match(2))})#{Regexp.last_match(3)}" - end - - renderer_options = { escape_html: true, - safe_links_only: true } - markdown_options = { fenced_code_blocks: true, - disable_indented_code_blocks: true, - autolink: true } - Redcarpet::Markdown.new(RougeRender.new(renderer_options), markdown_options).render(text) - end - - def compile(node) - compile_with_tilt(node, 'markdown') - end - end - end -end diff --git a/spec/controllers/markdown_controller_spec.rb b/spec/controllers/markdown_controller_spec.rb index 606ab10b..138bdc30 100644 --- a/spec/controllers/markdown_controller_spec.rb +++ b/spec/controllers/markdown_controller_spec.rb @@ -1,14 +1,13 @@ require 'rails_helper' RSpec.describe MarkdownController, type: :controller do - describe 'GET #preview' do - it 'correctly assigns rendered html' do - source = '*italic*' - - get :preview, xhr: true, params: { source: source } + render_views - expect(response).to be_successful - expect(assigns(:rendered)).to eq "

italic

\n" + describe 'GET #preview' do + it 'renders a markdown preview' do + sign_in create :user + get :preview, xhr: true, params: { source: '**hans**' } + expect(response.body).to include('$(\'# .preview-contents\').html("

hans<\/strong><\/p>\n\n");') end end end diff --git a/spec/helpers/markdown_helper_spec.rb b/spec/helpers/markdown_helper_spec.rb index 59a7b48f..8fddf190 100644 --- a/spec/helpers/markdown_helper_spec.rb +++ b/spec/helpers/markdown_helper_spec.rb @@ -1,17 +1,20 @@ require 'rails_helper' -# Specs in this file have access to a helper object that includes -# the MarkdownHelper. For example: -# -# describe MarkdownHelper do -# describe "string concat" do -# it "concats two strings with spaces" do -# expect(helper.concat_strings("this","that")).to eq("this that") -# end -# end -# end RSpec.describe MarkdownHelper, type: :helper do - describe '#render' do - it_behaves_like 'a markdown renderer' + describe '.enrich_markdown' do + it 'translates emoji' do + text = 'I need :coffee: so badly, working openSUSE:Factory:Staging:F' + expect(enrich_markdown(markdown: text)).to eq('I need ![add-emoji](https://github.githubassets.com/images/icons/emoji/coffee.png) so badly, working openSUSE:Factory:Staging:F') + end + + it 'translate @user links' do + text = 'Hey @hans, how are you?' + expect(enrich_markdown(markdown: text)).to eq('Hey [@hans](/users/hans), how are you?') + end + + it 'translates hw#slug links' do + text = 'Have you seen hw#super-cool? Its awesome' + expect(enrich_markdown(markdown: text)).to eq('Have you seen [hw#super-cool](/projects/super-cool)? Its awesome') + end end end diff --git a/spec/lib/haml/filters/markdown_spec.rb b/spec/lib/haml/filters/markdown_spec.rb deleted file mode 100644 index b268e5ce..00000000 --- a/spec/lib/haml/filters/markdown_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'rails_helper' - -describe Haml::Filters::Markdown do - describe '#render' do - it_behaves_like 'a markdown renderer' - end -end diff --git a/spec/support/shared_examples/a_markdown_renderer.rb b/spec/support/shared_examples/a_markdown_renderer.rb deleted file mode 100644 index 4f02b2ed..00000000 --- a/spec/support/shared_examples/a_markdown_renderer.rb +++ /dev/null @@ -1,24 +0,0 @@ -RSpec.shared_examples 'a markdown renderer' do - it 'correctly renders simple tags' do - source = '**bold**' - expect(subject.render(source)).to eq "

bold

\n" - end - - it 'escapes HTML tags' do - source = '' - escaped_source = "

<img src=1 onerror=alert(&#34;pwned&#34;)>

\n" - expect(subject.render(source)).to eq escaped_source - end - - it 'supports @user links' do - source = 'Hey @hans, how are you?' - escaped_source = "

Hey @hans, how are you?

\n" - expect(subject.render(source)).to eq escaped_source - end - - it 'supports hw#slug links' do - source = 'Have you seen hw#super-cool? Its awesome' - escaped_source = "

Have you seen hw#super-cool? Its awesome

\n" - expect(subject.render(source)).to eq escaped_source - end -end