mirror of
https://github.com/moparisthebest/android.moparisthebest.org
synced 2024-11-16 06:05:00 -05:00
Code plugin refactoring
- Unified handling of key, value options - Added url, link_text, and title options - Gists can now accept start, end, range, title, url, link_text, linenos and marks options - Code accessibility improvements (hiding line numbers) #864
This commit is contained in:
parent
be443098d6
commit
0fcbc225e4
@ -125,17 +125,12 @@ figure.code {
|
||||
overflow-x: auto;
|
||||
|
||||
// allows line number to be read by screen readers but won't be selected when copying code
|
||||
[data-line]:before {
|
||||
content: attr(data-line);
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
[data-line]:before { content: attr(data-line); }
|
||||
|
||||
td {
|
||||
line-height: 1.45em;
|
||||
font-size: 13px;
|
||||
div { padding: .8em; }
|
||||
pre { padding: .8em; }
|
||||
}
|
||||
|
||||
.main {
|
||||
|
@ -12,22 +12,28 @@ module BacktickCodeBlock
|
||||
markup = $1 || ''
|
||||
code = $2.to_s
|
||||
|
||||
linenos = get_linenos(markup)
|
||||
markup = replace_linenos(markup)
|
||||
|
||||
marks = get_marks(markup)
|
||||
markup = replace_marks(markup)
|
||||
|
||||
start = get_start(markup)
|
||||
markup = replace_start(markup)
|
||||
options = parse_markup(markup)
|
||||
@lang = options[:lang]
|
||||
@title = options[:title]
|
||||
@lineos = options[:lineos]
|
||||
@marks = options[:marks]
|
||||
@url = options[:url]
|
||||
@link_text = options[:link_text]
|
||||
@start = options[:start]
|
||||
markup = clean_markup(markup)
|
||||
|
||||
if markup =~ AllOptions
|
||||
highlight(code, $1, {caption: $2, url: $3, anchor: $4 || 'Link', linenos: linenos, start: start, marks: marks})
|
||||
@lang ||= $1
|
||||
@title ||= $2
|
||||
@url ||= $3
|
||||
@link_text ||= $4
|
||||
elsif markup =~ LangCaption
|
||||
highlight(code, $1, {caption: $2 || nil, linenos: linenos, start: start, marks: marks})
|
||||
@lang ||= $1
|
||||
@title ||= $2
|
||||
else
|
||||
highlight(code, 'plain', {linenos: linenos, start: start})
|
||||
end
|
||||
@lang = 'plain'
|
||||
end
|
||||
highlight(code, @lang, {title: @title, url: @url, link_text: @link_text, linenos: @linenos, marks: @marks, start: @start })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Title: Simple Code Blocks for Jekyll
|
||||
# Author: Brandon Mathis http://brandonmathis.com
|
||||
# Description: Write codeblocks with semantic HTML5 <figure> and <figcaption> elements and optional syntax highlighting — all with a simple, intuitive interface.
|
||||
# Description: Write codeblocks with semantic HTML5 <figure> and <figtitle> elements and optional syntax highlighting — all with a simple, intuitive interface.
|
||||
#
|
||||
# Syntax:
|
||||
# {% codeblock [title] [url] [link text] %}
|
||||
@ -25,7 +25,7 @@
|
||||
# Output:
|
||||
#
|
||||
# <figure class='code'>
|
||||
# <figcaption><span>Got pain? painrelief.sh</span> <a href="http://site.com/painrelief.sh">Download it!</a>
|
||||
# <figtitle><span>Got pain? painrelief.sh</span> <a href="http://site.com/painrelief.sh">Download it!</a>
|
||||
# <div class="highlight"><pre><code class="sh">
|
||||
# -- nicely escaped highlighted code --
|
||||
# </code></pre></div>
|
||||
@ -48,44 +48,42 @@ module Jekyll
|
||||
|
||||
class CodeBlock < Liquid::Block
|
||||
include HighlightCode
|
||||
CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i
|
||||
CaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i
|
||||
Caption = /(\S[\S\s]*)/
|
||||
TitleUrlLinkText = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)\s+(.+)/i
|
||||
TitleUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i
|
||||
Title = /(\S[\S\s]*)/
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@caption = nil
|
||||
@url = nil
|
||||
@title = nil
|
||||
|
||||
@lang = get_lang(markup)
|
||||
markup = replace_lang(markup)
|
||||
options = parse_markup(markup)
|
||||
@lang = options[:lang]
|
||||
@title = options[:title]
|
||||
@lineos = options[:lineos]
|
||||
@marks = options[:marks]
|
||||
@url = options[:url]
|
||||
@link_text = options[:link_text]
|
||||
@start = options[:start]
|
||||
markup = clean_markup(markup)
|
||||
|
||||
@linenos = get_linenos(markup)
|
||||
markup = replace_linenos(markup)
|
||||
|
||||
@marks = get_marks(markup)
|
||||
markup = replace_marks(markup)
|
||||
|
||||
@start = get_start(markup)
|
||||
markup = replace_start(markup)
|
||||
|
||||
if markup =~ CaptionUrlTitle
|
||||
@caption = $1
|
||||
@url = $2 + $3
|
||||
@anchor = $4
|
||||
elsif markup =~ CaptionUrl
|
||||
@caption = $1
|
||||
@url = $2 + $3
|
||||
elsif markup =~ Caption
|
||||
@caption = $1
|
||||
if markup =~ TitleUrlLinkText
|
||||
@title ||= $1
|
||||
@url ||= $2 + $3
|
||||
@link_text ||= $4
|
||||
elsif markup =~ TitleUrl
|
||||
@title ||= $1
|
||||
@url ||= $2 + $3
|
||||
elsif markup =~ Title
|
||||
@title ||= $1
|
||||
end
|
||||
if @caption =~ /\S[\S\s]*\w+\.(\w+)/ && @lang.nil?
|
||||
@lang = $1
|
||||
# grab lang from filename in title
|
||||
if @title =~ /\S[\S\s]*\w+\.(\w+)/ && @lang.nil?
|
||||
@lang ||= $1
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
code = super.strip
|
||||
code = highlight(code, @lang, {caption: @caption, url: @url, anchor: @anchor, start: @start, marks: @marks, linenos: @linenos})
|
||||
code = highlight(code, @lang, {title: @title, url: @url, link_text: @link_text, start: @start, marks: @marks, linenos: @linenos})
|
||||
code = context['pygments_prefix'] + code if context['pygments_prefix']
|
||||
code = code + context['pygments_suffix'] if context['pygments_suffix']
|
||||
code
|
||||
|
@ -15,18 +15,42 @@ require './plugins/pygments_code'
|
||||
module Jekyll
|
||||
class GistTag < Liquid::Tag
|
||||
include HighlightCode
|
||||
def initialize(tag_name, text, token)
|
||||
def initialize(tag_name, markup, token)
|
||||
super
|
||||
@text = text
|
||||
@cache_disabled = false
|
||||
@cache_folder = File.expand_path "../.gist-cache", File.dirname(__FILE__)
|
||||
|
||||
options = parse_markup(markup)
|
||||
@lang = options[:lang]
|
||||
@title = options[:title]
|
||||
@lineos = options[:lineos]
|
||||
@marks = options[:marks]
|
||||
@url = options[:url]
|
||||
@link_text = options[:link_text]
|
||||
@start = options[:start]
|
||||
@end = options[:end]
|
||||
@markup = clean_markup(markup)
|
||||
|
||||
FileUtils.mkdir_p @cache_folder
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if parts = @text.match(/([\d]*) (.*)/)
|
||||
if parts = @markup.match(/([\d]*) (.*)/)
|
||||
gist, file = parts[1].strip, parts[2].strip
|
||||
get_cached_gist(gist, file) || get_gist_from_web(gist, file)
|
||||
code = get_cached_gist(gist, file) || get_gist_from_web(gist, file)
|
||||
|
||||
length = code.lines.count
|
||||
@end ||= length
|
||||
return "#{file} is #{length} lines long, cannot begin at line #{@start}" if @start > length
|
||||
return "#{file} is #{length} lines long, cannot read beyond line #{@end}" if @end > length
|
||||
if @start > 1 or @end < length
|
||||
code = code.split(/\n/).slice(@start -1, @end + 1 - @start).join("\n")
|
||||
end
|
||||
|
||||
lang = file.empty? ? @lang || '' : file.split('.')[-1]
|
||||
link = "https://gist.github.com/#{gist}"
|
||||
title = file.empty? ? "Gist: #{gist}" : file
|
||||
highlight(code, lang, { title: @title || title, url: link, link_text: @link_text || 'Gist page', marks: @marks, linenos: @linenos, start: @start })
|
||||
else
|
||||
""
|
||||
end
|
||||
@ -71,18 +95,15 @@ module Jekyll
|
||||
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
request = Net::HTTP::Get.new raw_uri.request_uri
|
||||
data = https.request request
|
||||
lang = file.empty? ? '' : file.split('.')[-1]
|
||||
link = "https://gist.github.com/#{gist}"
|
||||
caption = file.empty? ? "Gist: #{gist}" : file
|
||||
data = highlight(data.body, lang, { linenos: true, start: 1, caption: caption, url: link, anchor: 'Gist page' })
|
||||
cache gist, file, data unless @cache_disabled
|
||||
code = data.body.to_s
|
||||
|
||||
data
|
||||
cache gist, file, code unless @cache_disabled
|
||||
code
|
||||
end
|
||||
end
|
||||
|
||||
class GistTagNoCache < GistTag
|
||||
def initialize(tag_name, text, token)
|
||||
def initialize(tag_name, markup, token)
|
||||
super
|
||||
@cache_disabled = true
|
||||
end
|
||||
|
@ -10,14 +10,14 @@
|
||||
#
|
||||
# This will import test.js from source/downloads/code/javascripts/test.js
|
||||
# and output the contents in a syntax highlighted code block inside a figure,
|
||||
# with a figcaption listing the file name and download link
|
||||
# with a figtitle listing the file name and download link
|
||||
#
|
||||
# Example 2:
|
||||
# You can also include an optional title for the <figcaption>
|
||||
# You can also include an optional title for the <figtitle>
|
||||
#
|
||||
# {% include_code javascripts/test.js Example 2 %}
|
||||
#
|
||||
# will output a figcaption with the title: Example 2 (test.js)
|
||||
# will output a figtitle with the title: Example 2 (test.js)
|
||||
#
|
||||
|
||||
require './plugins/pygments_code'
|
||||
@ -32,31 +32,22 @@ module Jekyll
|
||||
@title = nil
|
||||
@title_old = nil
|
||||
|
||||
@lang = get_lang(markup)
|
||||
markup = replace_lang(markup)
|
||||
|
||||
@linenos = get_linenos(markup)
|
||||
markup = replace_linenos(markup)
|
||||
|
||||
@marks = get_marks(markup)
|
||||
markup = replace_marks(markup)
|
||||
|
||||
@start = get_start(markup)
|
||||
markup = replace_start(markup)
|
||||
|
||||
@end = get_end(markup)
|
||||
markup = replace_end(markup)
|
||||
|
||||
range = get_range(markup, @start, @end)
|
||||
@start = range[:start]
|
||||
@end = range[:end]
|
||||
markup = replace_range(markup)
|
||||
options = parse_markup(markup)
|
||||
@lang = options[:lang]
|
||||
@title = options[:title]
|
||||
@lineos = options[:lineos]
|
||||
@marks = options[:marks]
|
||||
@url = options[:url]
|
||||
@link_text = options[:link_text]
|
||||
@start = options[:start]
|
||||
@end = options[:end]
|
||||
markup = clean_markup(markup)
|
||||
|
||||
if markup.strip =~ /(^\S*\.\S+) *(.+)?/i
|
||||
@file = $1
|
||||
@title = $2 || nil
|
||||
@title ||= $2
|
||||
elsif markup.strip =~ /(.*?)(\S*\.\S+)\Z/i # Title before file is deprecated in 2.1
|
||||
@title_old = $1 || nil
|
||||
@title_old = $1
|
||||
@file = $2
|
||||
end
|
||||
super
|
||||
@ -68,7 +59,7 @@ module Jekyll
|
||||
file = code_path + @file
|
||||
|
||||
unless @title_old.nil?
|
||||
@title = @title_old
|
||||
@title ||= @title_old
|
||||
puts "### ------------ WARNING ------------ ###"
|
||||
puts "This include_code syntax is deprecated "
|
||||
puts "Correct syntax: path/to/file.ext [title]"
|
||||
@ -90,6 +81,7 @@ module Jekyll
|
||||
code = file.read
|
||||
length = code.lines.count
|
||||
@end ||= length
|
||||
@start ||= 1
|
||||
return "#{file} is #{length} lines long, cannot begin at line #{@start}" if @start > length
|
||||
return "#{file} is #{length} lines long, cannot read beyond line #{@end}" if @end > length
|
||||
if @start > 1 or @end < length
|
||||
@ -98,7 +90,7 @@ module Jekyll
|
||||
@lang = file.extname.sub('.','') unless @lang
|
||||
title = @title ? "#{@title} (#{file.basename})" : file.basename
|
||||
url = "/#{code_dir}/#{@file}"
|
||||
highlight(code, @lang, {caption: title, url: url, anchor: 'view raw', start: @start, marks: @marks, linenos: @linenos })
|
||||
highlight(code, @lang, {title: title, url: url, link_text: @link_text || 'view raw', start: @start, marks: @marks, linenos: @linenos })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -38,13 +38,13 @@ module HighlightCode
|
||||
lang = 'csharp' if lang == 'cs'
|
||||
lang = 'plain' if lang == '' or lang.nil? or !lang
|
||||
|
||||
caption = options[:caption] || nil
|
||||
url = options[:url] || nil
|
||||
anchor = options[:anchor] || nil
|
||||
title = options[:title] || (url ? ' ' : nil)
|
||||
link_text = options[:link_text] || nil
|
||||
wrap = options[:wrap] || true
|
||||
marks = options[:marks]
|
||||
linenos = options[:linenos]
|
||||
start = options[:start]
|
||||
start = options[:start] || 1
|
||||
|
||||
if lang == 'plain'
|
||||
# Escape html tags
|
||||
@ -58,27 +58,26 @@ module HighlightCode
|
||||
end
|
||||
|
||||
code = tableize_code(code, lang, { linenos: linenos, start: start, marks: marks })
|
||||
caption = captionize(caption, url, anchor) if caption
|
||||
title = captionize(title, url, link_text) if title
|
||||
|
||||
figure = "<figure class='code'>#{caption}#{code}</figure>"
|
||||
figure = "<figure class='code'>#{title}#{code}</figure>"
|
||||
figure = safe_wrap(figure) if wrap
|
||||
figure
|
||||
end
|
||||
|
||||
def captionize (caption, url, anchor)
|
||||
def captionize (caption, url, link_text)
|
||||
figcaption = "<figcaption>#{caption}"
|
||||
figcaption += "<a href='#{url}'>#{anchor.strip || 'link'}</a>" if url
|
||||
figcaption += "<a href='#{url}'>#{(link_text || 'link').strip}</a>" if url
|
||||
figcaption += "</figcaption>"
|
||||
end
|
||||
|
||||
def tableize_code (code, lang, options = {})
|
||||
start = options[:start]
|
||||
lines = options[:linenos].nil? ? true : options[:linenos]
|
||||
start = options[:start] || 1
|
||||
lines = options[:linenos] || true
|
||||
marks = options[:marks] || []
|
||||
table = "<table class='highlight'>"
|
||||
table += number_lines(start, code.lines.count, marks) if lines
|
||||
table += "<td class='main #{'unnumbered' unless lines} #{lang}'><div>"
|
||||
if marks.size
|
||||
table += "<td class='main #{'unnumbered' unless lines} #{lang}'><pre>"
|
||||
code.lines.each_with_index do |line,index|
|
||||
classes = 'line'
|
||||
if marks.include? index + start
|
||||
@ -86,17 +85,15 @@ module HighlightCode
|
||||
classes += ' start' unless marks.include? index - 1 + start
|
||||
classes += ' end' unless marks.include? index + 1 + start
|
||||
end
|
||||
table += "<pre data-line='line #{index + start}' class='#{classes}'>#{line}</pre>"
|
||||
line = line.strip.empty? ? ' ' : line
|
||||
table += "<div class='#{classes}'>#{line}</div>"
|
||||
end
|
||||
else
|
||||
table += code.gsub /^((.+)?(\n?))/, '<span class=\'line\'>\1</span>'
|
||||
end
|
||||
table +="</div></td></tr></table>"
|
||||
table +="</pre></td></tr></table>"
|
||||
end
|
||||
|
||||
def number_lines (start, count, marks)
|
||||
start ||= 1
|
||||
lines = "<td class='line-numbers' aria-hidden='true'><div>"
|
||||
lines = "<td class='line-numbers' aria-hidden='true'><pre>"
|
||||
count.times do |index|
|
||||
classes = 'line-number'
|
||||
if marks.include? index + start
|
||||
@ -104,21 +101,44 @@ module HighlightCode
|
||||
classes += ' start' unless marks.include? index - 1 + start
|
||||
classes += ' end' unless marks.include? index + 1 + start
|
||||
end
|
||||
lines += "<pre class='#{classes}'>#{index + start}</pre>"
|
||||
lines += "<div data-line='#{index + start}' class='#{classes}'></div>"
|
||||
end
|
||||
lines += "</div></td>"
|
||||
lines += "</pre></td>"
|
||||
end
|
||||
|
||||
def get_lang (input)
|
||||
lang = nil
|
||||
if input =~ /\s*lang:(\w+)/i
|
||||
lang = $1
|
||||
end
|
||||
lang
|
||||
def parse_markup (input)
|
||||
lang = input.match(/\s*lang:(\w+)/i)
|
||||
title = input.match(/\s*title:\s*(("(.+?)")|('(.+?)')|(\S+))/i)
|
||||
linenos = input.match(/\s*linenos:(\w+)/i)
|
||||
marks = get_marks(input)
|
||||
url = input.match(/\s*url:\s*(("(.+?)")|('(.+?)')|(\S+))/i)
|
||||
link_text = input.match(/\s*link_text:\s*(("(.+?)")|('(.+?)')|(\S+))/i)
|
||||
start = input.match(/\s*start:(\d+)/i)
|
||||
endline = input.match(/\s*end:(\d+)/i)
|
||||
|
||||
opts = {
|
||||
lang: (lang.nil? ? nil : lang[1]),
|
||||
title: (title.nil? ? nil : title[3] || title[5] || title[6]),
|
||||
linenos: (linenos.nil? ? nil : linenos[1]),
|
||||
marks: marks,
|
||||
url: (url.nil? ? nil : url[3] || url[5] || url[6]),
|
||||
start: (start.nil? ? nil : start[1].to_i),
|
||||
end: (endline.nil? ? nil : endline[1].to_i),
|
||||
link_text: (link_text.nil? ? nil : link_text[3] || link_text[5] || link_text[6])
|
||||
}
|
||||
opts.merge(get_range(input, opts[:start], opts[:end]))
|
||||
end
|
||||
|
||||
def replace_lang (input)
|
||||
input.sub(/ *lang:\w+/i, '')
|
||||
def clean_markup (input)
|
||||
input.sub(/\s*lang:\w+/i, ''
|
||||
).sub(/\s*title:\s*(("(.+?)")|('(.+?)')|(\S+))/i, ''
|
||||
).sub(/\s*url:(\S+)/i, ''
|
||||
).sub(/\s*link_text:\s*(("(.+?)")|('(.+?)')|(\S+))/i, ''
|
||||
).sub(/\s*mark:\d\S*/i,''
|
||||
).sub(/\s*linenos:false/i,''
|
||||
).sub(/\s*start:\d+/i,''
|
||||
).sub(/\s*end:\d+/i,''
|
||||
).sub(/\s*range:\d+-\d+/i,'')
|
||||
end
|
||||
|
||||
def get_marks (input)
|
||||
@ -135,46 +155,6 @@ module HighlightCode
|
||||
marks
|
||||
end
|
||||
|
||||
def replace_marks (input)
|
||||
input.sub(/ *mark:\d\S*/i,'')
|
||||
end
|
||||
|
||||
def get_linenos (input)
|
||||
linenos = true
|
||||
if input =~ / *linenos:false/i
|
||||
linenos = false
|
||||
end
|
||||
linenos
|
||||
end
|
||||
|
||||
def replace_linenos (input)
|
||||
input.sub(/ *linenos:false/i,'')
|
||||
end
|
||||
|
||||
def get_start (input)
|
||||
start = 1
|
||||
if input =~ / *start:(\d+)/i
|
||||
start = $1.to_i
|
||||
end
|
||||
start
|
||||
end
|
||||
|
||||
def replace_start (input)
|
||||
input.sub(/ *start:\d+/i,'')
|
||||
end
|
||||
|
||||
def get_end (input)
|
||||
endline = nil
|
||||
if input =~ / *end:(\d+)/i
|
||||
endline = $1.to_i
|
||||
end
|
||||
endline
|
||||
end
|
||||
|
||||
def replace_end (input)
|
||||
input.sub(/ *end:\d+/i,'')
|
||||
end
|
||||
|
||||
def get_range (input, start, endline)
|
||||
if input =~ / *range:(\d+)-(\d+)/i
|
||||
start = $1.to_i
|
||||
@ -182,7 +162,4 @@ module HighlightCode
|
||||
end
|
||||
{start: start, end: endline}
|
||||
end
|
||||
def replace_range (input)
|
||||
input.sub(/ *range:\d+-\d+/i,'')
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user