mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Merge pull request #273 from gopesht/implements_markdown
Implements markdown
This commit is contained in:
commit
fbf52b1d69
23 changed files with 3140 additions and 21 deletions
3
Gemfile
3
Gemfile
|
|
@ -81,6 +81,9 @@ gem 'active_model_serializers'
|
|||
# Use FontAwesome for splash themes
|
||||
gem 'font-awesome-rails'
|
||||
|
||||
#Use Redcarpet for Markdown in description
|
||||
gem 'redcarpet'
|
||||
|
||||
# Use rspec and capybara as testing framework
|
||||
group :development, :test do
|
||||
gem 'rspec', '>= 3.0.0.beta'
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ GEM
|
|||
loggability (~> 0.6)
|
||||
rdoc (~> 4.0)
|
||||
yajl-ruby (~> 1.1)
|
||||
redcarpet (3.1.2)
|
||||
referer-parser (0.2.1)
|
||||
request_store (1.0.6)
|
||||
rest-client (1.6.7)
|
||||
|
|
@ -413,6 +414,7 @@ DEPENDENCIES
|
|||
rails (~> 4.1)
|
||||
rails-observers
|
||||
rdoc-generator-fivefish
|
||||
redcarpet
|
||||
rspec (>= 3.0.0.beta)
|
||||
rspec-rails (>= 3.0.0.beta)
|
||||
rubocop
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@
|
|||
//= require dashboard
|
||||
//= require ahoy
|
||||
//= require smoothscroll
|
||||
|
||||
//= require bootstrap-markdown
|
||||
//= require to-markdown
|
||||
//= require markdown
|
||||
$(document).ready(function() {
|
||||
$('a[disabled=disabled]').click(function(event){
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@
|
|||
*= require osem-schedule
|
||||
*= require osem-schedule-print
|
||||
*= require font-awesome
|
||||
*= require bootstrap-markdown.min
|
||||
*/
|
||||
|
|
|
|||
1
app/assets/stylesheets/bootstrap-markdown.min.css
vendored
Normal file
1
app/assets/stylesheets/bootstrap-markdown.min.css
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
.md-editor{display:block;border:1px solid #ddd}.md-editor>.md-header,.md-editor .md-footer{display:block;padding:6px 4px;background:#fff}.md-editor>.md-header{margin: 0;}.md-editor>.md-preview{background:#fff;border-top:1px dashed #ddd;border-bottom:1px dashed #ddd;min-height:10px;overflow:auto}.md-editor>textarea{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:14px;outline:0;outline:thin dotted \9;margin:0;display:block;padding:0;width:100%;border:0;border-top:1px dashed #ddd;border-bottom:1px dashed #ddd;border-radius:0;box-shadow:none;background:#eee}.md-editor>textarea:focus{box-shadow:none;background:#fff}.md-editor.active{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,0.6)}
|
||||
|
|
@ -197,4 +197,18 @@ module ApplicationHelper
|
|||
(short_title_brand(@conference) if @conference) ||
|
||||
default_brand
|
||||
end
|
||||
|
||||
def markdown(text)
|
||||
options = {
|
||||
autolink: true,
|
||||
space_after_headers: true,
|
||||
no_intra_emphasis: true
|
||||
}
|
||||
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, options)
|
||||
markdown.render(text).html_safe
|
||||
end
|
||||
|
||||
def markdown_hint(text="")
|
||||
markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
= f.input :include_cfp_in_splash, label: 'Include Call for Papers in Splash', hint: 'On setting this true you will enable the call for papers to be displayed on the splash page'
|
||||
= f.input :start_date, :as => :string, :input_html => { :id => "conference-start-datepicker", :readonly => "readonly" }
|
||||
= f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" }
|
||||
= f.input :description, :hint => "Welcome text for the Call for Papers"
|
||||
= f.input :description, hint: markdown_hint("Welcome text for the Call for Papers."), input_html: { data: { provide: "markdown-editable" } }
|
||||
= f.input :schedule_changes
|
||||
= f.input :schedule_public
|
||||
= f.input :rating, :hint => "Enter the number of different rating levels you want to have for voting on proposals. Enter 0 if you do not want to vote on proposals."
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
= f.inputs name: 'Banner for Splash' do
|
||||
= f.input :include_banner_in_splash, hint: 'This enable the Banner Photo with description to be displayed on the splash'
|
||||
= f.input :banner_photo, hint: 'This will be the top most component of the splash.This background cover will contain start_date and end_date of the conference and the description'
|
||||
= f.input :description, hint: 'This description will be shown at the bottom of the banner photo of the Splash'
|
||||
= f.input :description, hint: markdown_hint("This description will be shown at the bottom of the banner photo of the Splash."), input_html: { data: { provide: "markdown-editable" } }
|
||||
|
||||
= f.inputs :name => "Scheduling" do
|
||||
= f.input :timezone, :as => :time_zone, :hint => "The conference time zone"
|
||||
|
|
@ -22,11 +22,11 @@
|
|||
= f.input :include_registrations_in_splash, hint: 'On setting this true you will enable the registrations to be displayed on the splash page'
|
||||
= f.input :registration_start_date, :as => :string, :input_html => { :id => "conference-reg-start-datepicker", :readonly => "readonly" }
|
||||
= f.input :registration_end_date, :as => :string, :input_html => { :id => "conference-reg-end-datepicker", :readonly => "readonly" }
|
||||
= f.input :registration_description, hint: 'This description will appear in registration segment of the splash'
|
||||
= f.input :ticket_description, hint: 'This will appear in the Tickets segment of the splash'
|
||||
= f.input :sponsor_description, hint: 'This will appear in the sponsor segment of the splash'
|
||||
= f.input :registration_description, hint: markdown_hint("This description will appear in registration segment of the splash."), input_html: { data: { provide: "markdown-editable" } }
|
||||
= f.input :ticket_description, hint: markdown_hint("This will appear in the Tickets segment of the splash."), input_html: { data: { provide: "markdown-editable" } }
|
||||
= f.input :sponsor_description, hint: markdown_hint("This will appear in the sponsor segment of the splash."), input_html: { data: { provide: "markdown-editable" } }
|
||||
= f.input :sponsor_email, hint: 'This will appear in the sponsor segment of the splash for the sponsors to contact to the organizers'
|
||||
= f.input :lodging_description, hint: 'This will appear in the lodging segment of the splash'
|
||||
= f.input :lodging_description, hint: markdown_hint("This will appear in the lodging segment of the splash."), input_html: { data: { provide: "markdown-editable" } }
|
||||
|
||||
= dynamic_association :photos, "Photos", f
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
<div class="nested-fields">
|
||||
<%= f.inputs do %>
|
||||
<%= f.input :name %>
|
||||
<%= f.input :description, :input_html => {:rows => 2 }, hint: 'Write about the hotel/place,
|
||||
of what they are offering, about types of rooms, prices and address' %>
|
||||
<%= f.input :description, :input_html => {:rows => 2, data: { provide: "markdown-editable" } }, hint: markdown_hint("Write about the hotel/place, of what they are offering, about types of rooms, prices and address.") %>
|
||||
<%= image_tag f.object.photo(:thumb) if !f.object.photo.blank? %>
|
||||
<%= f.input :photo %>
|
||||
<%= f.input :website_link %>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<%= f.inputs do %>
|
||||
<%= f.input :title%>
|
||||
<%= f.input :url %>
|
||||
<%= f.input :description %>
|
||||
<%= f.input :description, hint: markdown_hint, input_html: { data: { provide: "markdown-editable" } } %>
|
||||
<%= f.input :ticket_price, hint: 'Please enter price with currency symbol.
|
||||
For example, $200,₹300' %>
|
||||
<%= remove_association_link :supporter_level, f %>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
<%= f.inputs do %>
|
||||
<%= f.input :name %>
|
||||
<%= f.input :color, :input_html => {:size => 6, :type => "color"}, :required=> true %>
|
||||
<%= f.input :description, :input_html => {:rows => 2 } %>
|
||||
<%= f.input :description, :input_html => {:rows => 2, data: { provide: "markdown-editable" } }, hint: markdown_hint %>
|
||||
<%= remove_association_link :track, f %>
|
||||
<% end %>
|
||||
</div>
|
||||
data: { provide: "markdown-editable" }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
= f.input :name, :input_html => {:rows => 1}
|
||||
= f.input :address, :input_html => {:rows => 1}
|
||||
= f.input :website
|
||||
= f.input :description, :input_html => { :rows => 10, :cols => 20 }
|
||||
= f.input :description, :input_html => { :rows => 10, :cols => 20, data: { provide: "markdown-editable" } }, hint: markdown_hint
|
||||
- unless @venue.photo.blank?
|
||||
= image_tag @venue.photo(:thumb)
|
||||
= f.input :photo
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
Call For Papers
|
||||
- if !@conference.call_for_papers.description.blank?
|
||||
%p
|
||||
= @conference.call_for_papers.description
|
||||
= markdown(@conference.call_for_papers.description)
|
||||
- if !@conference.call_for_papers.start_date.blank? && !@conference.call_for_papers.end_date.blank?
|
||||
%p.lead Proposals will be accepted between
|
||||
#cfp-date
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
%strong #{ @conference.venue.address }
|
||||
- unless @conference.venue.description.blank?
|
||||
%p
|
||||
= @conference.venue.description
|
||||
= markdown(@conference.venue.description)
|
||||
%ul.location-links
|
||||
- unless @conference.venue.address.blank?
|
||||
%li
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
%h2 Lodgings
|
||||
-unless @conference.lodging_description.blank?
|
||||
%p.lead
|
||||
= @conference.lodging_description
|
||||
= markdown(@conference.lodging_description)
|
||||
|
||||
%div.row.text-center
|
||||
- @conference.venue.lodgings.each do |r|
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
-unless r.name.blank?
|
||||
%h4.text-center #{ r.name }
|
||||
-unless r.description.blank?
|
||||
%p.text-left #{ r.description }
|
||||
%p.text-left #{ markdown(r.description) }
|
||||
- unless r.website_link.blank?
|
||||
.text-center
|
||||
= link_to 'Go to Website', r.website_link
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
%h1 Registration
|
||||
- if !@conference.registration_description.blank?
|
||||
%p
|
||||
= @conference.registration_description
|
||||
= markdown(@conference.registration_description)
|
||||
- if @conference.registration_dates_given?
|
||||
-if @conference.registration_end_date >= Date.today
|
||||
%h4 Registration period #{ date_string(@conference.registration_start_date, @conference.registration_end_date) }
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
%div.col-md-12
|
||||
%h2 Sponsors
|
||||
-if !@conference.sponsor_description.blank?
|
||||
%p #{ @conference.sponsor_description }
|
||||
%p
|
||||
= markdown(@conference.sponsor_description)
|
||||
-if !@conference.sponsor_email.blank?
|
||||
%h3= mail_to "#{ @conference.sponsor_email }", 'Become a Sponsor'
|
||||
- if !@conference.sponsorship_levels.blank?
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
%div.row
|
||||
%h3 Tickets
|
||||
-if !@conference.ticket_description.blank?
|
||||
%p #{ @conference.ticket_description }
|
||||
%p
|
||||
= markdown(@conference.ticket_description)
|
||||
- @conference.supporter_levels.each do |s|
|
||||
%div.col-md-6
|
||||
- if !s.title.blank?
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@
|
|||
%h4
|
||||
= t.name
|
||||
%p
|
||||
= t.description
|
||||
= markdown(t.description)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
- unless @conference.description.blank?
|
||||
.row-fluid
|
||||
.col-md-12.lead
|
||||
%p= @conference.description
|
||||
%p
|
||||
= markdown(@conference.description)
|
||||
-unless @conference.photos.blank?
|
||||
= link_to 'Gallery', gallery_photos_conference_path(@conference.short_title), class: 'btn btn-primary btn-lg', id: 'gallery-btn', remote: true
|
||||
= render 'gallery'
|
||||
|
|
|
|||
1293
vendor/assets/javascripts/bootstrap-markdown.js
vendored
Normal file
1293
vendor/assets/javascripts/bootstrap-markdown.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1616
vendor/assets/javascripts/markdown.js
vendored
Normal file
1616
vendor/assets/javascripts/markdown.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
184
vendor/assets/javascripts/to-markdown.js
vendored
Normal file
184
vendor/assets/javascripts/to-markdown.js
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* to-markdown - an HTML to Markdown converter
|
||||
*
|
||||
* Copyright 2011, Dom Christie
|
||||
* Licenced under the MIT licence
|
||||
*
|
||||
*/
|
||||
|
||||
var toMarkdown = function(string) {
|
||||
|
||||
var ELEMENTS = [
|
||||
{
|
||||
patterns: 'p',
|
||||
replacement: function(str, attrs, innerHTML) {
|
||||
return innerHTML ? '\n\n' + innerHTML + '\n' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
patterns: 'br',
|
||||
type: 'void',
|
||||
replacement: '\n'
|
||||
},
|
||||
{
|
||||
patterns: 'h([1-6])',
|
||||
replacement: function(str, hLevel, attrs, innerHTML) {
|
||||
var hPrefix = '';
|
||||
for(var i = 0; i < hLevel; i++) {
|
||||
hPrefix += '#';
|
||||
}
|
||||
return '\n\n' + hPrefix + ' ' + innerHTML + '\n';
|
||||
}
|
||||
},
|
||||
{
|
||||
patterns: 'hr',
|
||||
type: 'void',
|
||||
replacement: '\n\n* * *\n'
|
||||
},
|
||||
{
|
||||
patterns: 'a',
|
||||
replacement: function(str, attrs, innerHTML) {
|
||||
var href = attrs.match(attrRegExp('href')),
|
||||
title = attrs.match(attrRegExp('title'));
|
||||
return href ? '[' + innerHTML + ']' + '(' + href[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')' : str;
|
||||
}
|
||||
},
|
||||
{
|
||||
patterns: ['b', 'strong'],
|
||||
replacement: function(str, attrs, innerHTML) {
|
||||
return innerHTML ? '**' + innerHTML + '**' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
patterns: ['i', 'em'],
|
||||
replacement: function(str, attrs, innerHTML) {
|
||||
return innerHTML ? '_' + innerHTML + '_' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
patterns: 'code',
|
||||
replacement: function(str, attrs, innerHTML) {
|
||||
return innerHTML ? '`' + innerHTML + '`' : '';
|
||||
}
|
||||
},
|
||||
{
|
||||
patterns: 'img',
|
||||
type: 'void',
|
||||
replacement: function(str, attrs, innerHTML) {
|
||||
var src = attrs.match(attrRegExp('src')),
|
||||
alt = attrs.match(attrRegExp('alt')),
|
||||
title = attrs.match(attrRegExp('title'));
|
||||
return '![' + (alt && alt[1] ? alt[1] : '') + ']' + '(' + src[1] + (title && title[1] ? ' "' + title[1] + '"' : '') + ')';
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
for(var i = 0, len = ELEMENTS.length; i < len; i++) {
|
||||
if(typeof ELEMENTS[i].patterns === 'string') {
|
||||
string = replaceEls(string, { tag: ELEMENTS[i].patterns, replacement: ELEMENTS[i].replacement, type: ELEMENTS[i].type });
|
||||
}
|
||||
else {
|
||||
for(var j = 0, pLen = ELEMENTS[i].patterns.length; j < pLen; j++) {
|
||||
string = replaceEls(string, { tag: ELEMENTS[i].patterns[j], replacement: ELEMENTS[i].replacement, type: ELEMENTS[i].type });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replaceEls(html, elProperties) {
|
||||
var pattern = elProperties.type === 'void' ? '<' + elProperties.tag + '\\b([^>]*)\\/?>' : '<' + elProperties.tag + '\\b([^>]*)>([\\s\\S]*?)<\\/' + elProperties.tag + '>',
|
||||
regex = new RegExp(pattern, 'gi'),
|
||||
markdown = '';
|
||||
if(typeof elProperties.replacement === 'string') {
|
||||
markdown = html.replace(regex, elProperties.replacement);
|
||||
}
|
||||
else {
|
||||
markdown = html.replace(regex, function(str, p1, p2, p3) {
|
||||
return elProperties.replacement.call(this, str, p1, p2, p3);
|
||||
});
|
||||
}
|
||||
return markdown;
|
||||
}
|
||||
|
||||
function attrRegExp(attr) {
|
||||
return new RegExp(attr + '\\s*=\\s*["\']?([^"\']*)["\']?', 'i');
|
||||
}
|
||||
|
||||
// Pre code blocks
|
||||
|
||||
string = string.replace(/<pre\b[^>]*>`([\s\S]*)`<\/pre>/gi, function(str, innerHTML) {
|
||||
innerHTML = innerHTML.replace(/^\t+/g, ' '); // convert tabs to spaces (you know it makes sense)
|
||||
innerHTML = innerHTML.replace(/\n/g, '\n ');
|
||||
return '\n\n ' + innerHTML + '\n';
|
||||
});
|
||||
|
||||
// Lists
|
||||
|
||||
// Escape numbers that could trigger an ol
|
||||
// If there are more than three spaces before the code, it would be in a pre tag
|
||||
// Make sure we are escaping the period not matching any character
|
||||
string = string.replace(/^(\s{0,3}\d+)\. /g, '$1\\. ');
|
||||
|
||||
// Converts lists that have no child lists (of same type) first, then works it's way up
|
||||
var noChildrenRegex = /<(ul|ol)\b[^>]*>(?:(?!<ul|<ol)[\s\S])*?<\/\1>/gi;
|
||||
while(string.match(noChildrenRegex)) {
|
||||
string = string.replace(noChildrenRegex, function(str) {
|
||||
return replaceLists(str);
|
||||
});
|
||||
}
|
||||
|
||||
function replaceLists(html) {
|
||||
|
||||
html = html.replace(/<(ul|ol)\b[^>]*>([\s\S]*?)<\/\1>/gi, function(str, listType, innerHTML) {
|
||||
var lis = innerHTML.split('</li>');
|
||||
lis.splice(lis.length - 1, 1);
|
||||
|
||||
for(i = 0, len = lis.length; i < len; i++) {
|
||||
if(lis[i]) {
|
||||
var prefix = (listType === 'ol') ? (i + 1) + ". " : "* ";
|
||||
lis[i] = lis[i].replace(/\s*<li[^>]*>([\s\S]*)/i, function(str, innerHTML) {
|
||||
|
||||
innerHTML = innerHTML.replace(/^\s+/, '');
|
||||
innerHTML = innerHTML.replace(/\n\n/g, '\n\n ');
|
||||
// indent nested lists
|
||||
innerHTML = innerHTML.replace(/\n([ ]*)+(\*|\d+\.) /g, '\n$1 $2 ');
|
||||
return prefix + innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
return lis.join('\n');
|
||||
});
|
||||
return '\n\n' + html.replace(/[ \t]+\n|\s+$/g, '');
|
||||
}
|
||||
|
||||
// Blockquotes
|
||||
var deepest = /<blockquote\b[^>]*>((?:(?!<blockquote)[\s\S])*?)<\/blockquote>/gi;
|
||||
while(string.match(deepest)) {
|
||||
string = string.replace(deepest, function(str) {
|
||||
return replaceBlockquotes(str);
|
||||
});
|
||||
}
|
||||
|
||||
function replaceBlockquotes(html) {
|
||||
html = html.replace(/<blockquote\b[^>]*>([\s\S]*?)<\/blockquote>/gi, function(str, inner) {
|
||||
inner = inner.replace(/^\s+|\s+$/g, '');
|
||||
inner = cleanUp(inner);
|
||||
inner = inner.replace(/^/gm, '> ');
|
||||
inner = inner.replace(/^(>([ \t]{2,}>)+)/gm, '> >');
|
||||
return inner;
|
||||
});
|
||||
return html;
|
||||
}
|
||||
|
||||
function cleanUp(string) {
|
||||
string = string.replace(/^[\t\r\n]+|[\t\r\n]+$/g, ''); // trim leading/trailing whitespace
|
||||
string = string.replace(/\n\s+\n/g, '\n\n');
|
||||
string = string.replace(/\n{3,}/g, '\n\n'); // limit consecutive linebreaks to 2
|
||||
return string;
|
||||
}
|
||||
|
||||
return cleanUp(string);
|
||||
};
|
||||
|
||||
if (typeof exports === 'object') {
|
||||
exports.toMarkdown = toMarkdown;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue