Fenced Code Blocks, Fortran Syntax Colouring

Support Marhdown Extra's fenced code blocks. [From Jason Blevins]
Fortran syntax colouring. [From Jason Blevins]
Turn on Syntax colouring, by default.
Point to Michel Fortin's Markdown Extra page.
master
Jacques Distler 2009-12-31 15:54:01 -06:00
parent b72ca42199
commit f66fc4de4d
11 changed files with 229 additions and 62 deletions

View File

@ -1,3 +1,3 @@
<h3>Markdown+itex2MML formatting tips (<a target="_new" href="http://daringfireball.net/projects/markdown/syntax">basics</a>, <a target="_new" href="http://maruku.rubyforge.org/maruku.html#extra">extended syntax</a>, <a target="_new" href="http://maruku.rubyforge.org/proposal.html">metadata</a>, <a target="_new" href="http://golem.ph.utexas.edu/instiki/show/Theorems">theorems</a>)</h3>
<h3>Markdown+itex2MML formatting tips (<a target="_new" href="http://daringfireball.net/projects/markdown/syntax">basics</a>, <a target="_new" href="http://michelf.com/projects/php-markdown/extra/">extended syntax</a>, <a target="_new" href="http://maruku.rubyforge.org/proposal.html">metadata</a>, <a target="_new" href="http://golem.ph.utexas.edu/instiki/show/Theorems">theorems</a>)</h3>
<p>For a complete list of LaTeX commands supported here, see the <a href="http://golem.ph.utexas.edu/~distler/blog/itex2MMLcommands.html">itex2MML Commands Summary</a>.</p>
<%= render(:file => "markdown_table") -%>

View File

@ -1,3 +1,3 @@
<h3>Markdown+blahtex/PNG formatting tips (<a target="_new" href="http://daringfireball.net/projects/markdown/syntax">basics</a>, <a target="_new" href="http://maruku.rubyforge.org/#extra">extended syntax</a>, <a target="_new" href="http://maruku.rubyforge.org/proposal.html">metadata</a>)</h3>
<h3>Markdown+blahtex/PNG formatting tips (<a target="_new" href="http://daringfireball.net/projects/markdown/syntax">basics</a>, <a target="_new" href="http://michelf.com/projects/php-markdown/extra/">extended syntax</a>, <a target="_new" href="http://maruku.rubyforge.org/proposal.html">metadata</a>)</h3>
<p>For a list of the LaTeX commands supported here, see the <a href="http://www.blahtex.org/manual.html">BlahTeX manual</a>.</p>
<%= render(:file => "markdown_table") -%>

View File

@ -1,2 +1,2 @@
<h3>Markdown formatting tips (<a target="_new" href="http://daringfireball.net/projects/markdown/syntax">basics</a>, <a target="_new" href="http://maruku.rubyforge.org/#extra">extended syntax</a>, <a target="_new" href="http://maruku.rubyforge.org/proposal.html">metadata</a>)</h3>
<h3>Markdown formatting tips (<a target="_new" href="http://daringfireball.net/projects/markdown/syntax">basics</a>, <a target="_new" href="http://michelf.com/projects/php-markdown/extra/">extended syntax</a>, <a target="_new" href="http://maruku.rubyforge.org/proposal.html">metadata</a>)</h3>
<%= render(:file => "markdown_table") -%>

View File

@ -3,9 +3,9 @@
####
# Make sure we are using the latest rexml
rexml_versions = ['', File.dirname(__FILE__) + '/../vendor/plugins/rexml/lib/'].collect { |v|
`ruby -r #{v + 'rexml/rexml'} -e 'p REXML::VERSION'`.split('.').collect {|n| n.to_i} }
$:.unshift(File.dirname(__FILE__) + '/../vendor/plugins/rexml/lib') if (rexml_versions[0] <=> rexml_versions[1]) == -1
rexml_versions = ['', File.join(File.dirname(__FILE__), '..', 'vendor', 'plugins', 'rexml', 'lib', '')].collect { |v|
`ruby -r "#{v + 'rexml/rexml'}" -e 'p REXML::VERSION'`.split('.').collect {|n| n.to_i} }
$:.unshift(File.join(File.dirname(__FILE__), '..', 'vendor', 'plugins', 'rexml', 'lib')) if (rexml_versions[0] <=> rexml_versions[1]) == -1
require File.join(File.dirname(__FILE__), 'boot')

View File

@ -99,5 +99,5 @@ pre.ruby span.ident { color: #229; }
pre.ruby span.punct { color: #4838AB; }
pre.yaml .key { color: #833; }
pre.ansic .preprocessor { color: #808; }
pre.javascript .other { color: #F0F; }
pre.fortran .number { color: #808; }
pre.xml .punct { color: #059; font-weight: bold; }

View File

@ -1,7 +1,7 @@
pre.ansic .normal {}
pre.ansic .comment { color: #00F; }
pre.ansic .keyword { color: #A00; }
pre.ansic .predefined_types { color: #DD0000; }
pre.ansic .predefined_types { color: #D00; }
pre.ansic .char { color: #F07; }
pre.ansic .ident { color: #004; }
pre.ansic .hex { color: #F99; }
@ -9,9 +9,18 @@ pre.ansic .oct { color: #F99; }
pre.ansic .integer { color: #F99; }
pre.ansic .float { color: #F99; }
pre.ansic .string { color: #494; }
pre.ansic .preprocessor { color: #FF00FF; }
pre.ansic .preprocessor { color: #D0D; }
pre.ansic .other { color: black; }
pre.fortran .normal {}
pre.fortran .string { color: #494; }
pre.fortran .number { color: #D0D; }
pre.fortran .comment { color: #00F; }
pre.fortran .keyword { color: #A00; }
pre.fortran .type { color: #D00; }
pre.fortran .symbol { color: #008B8B; }
pre.fortran .function { color: #F07; }
pre.css21 .normal {}
pre.css21 .comment { color: #888; }
pre.css21 .cdo { color: #666; }

View File

@ -113,6 +113,8 @@ require 'maruku/toc'
# Support for div Markdown extension
require 'maruku/ext/div'
# Support for fenced codeblocks extension
require 'maruku/ext/fenced_code'
# Version and URL
require 'maruku/version'

View File

@ -77,58 +77,6 @@ end
module MaRuKu; module In; module Markdown; module SpanLevelParser
def unit_tests_for_attribute_lists
[
[ "", [], "Empty lists are allowed" ],
[ "=", :throw, "Bad char to begin a list with." ],
[ "a =b", :throw, "No whitespace before `=`." ],
[ "a= b", :throw, "No whitespace after `=`." ],
[ "a b", [[:ref, 'a'],[:ref, 'b']], "More than one ref" ],
[ "a b c", [[:ref, 'a'],[:ref, 'b'],[:ref, 'c']], "More than one ref" ],
[ "hello notfound", [[:ref, 'hello'],[:ref, 'notfound']]],
[ "'a'", [[:ref, 'a']], "Quoted value." ],
[ '"a"' ],
[ "a=b", [['a','b']], "Simple key/val" ],
[ "'a'=b" ],
[ "'a'='b'" ],
[ "a='b'" ],
[ 'a="b\'"', [['a',"b\'"]], "Key/val with quotes" ],
[ 'a=b\''],
[ 'a="\\\'b\'"', [['a',"\'b\'"]], "Key/val with quotes" ],
['"', :throw, "Unclosed quotes"],
["'"],
["'a "],
['"a '],
[ "#a", [[:id, 'a']], "Simple ID" ],
[ "#'a'" ],
[ '#"a"' ],
[ "#", :throw, "Unfinished '#'." ],
[ ".", :throw, "Unfinished '.'." ],
[ "# a", :throw, "No white-space after '#'." ],
[ ". a", :throw, "No white-space after '.' ." ],
[ "a=b c=d", [['a','b'],['c','d']], "Tabbing" ],
[ " \ta=b \tc='d' "],
[ "\t a=b\t c='d'\t\t"],
[ ".\"a'", :throw, "Mixing quotes is bad." ],
].map { |s, expected, comment|
@expected = (expected ||= @expected)
@comment = (comment ||= (last=@comment) )
(comment == last && (comment += (@count+=1).to_s)) || @count = 1
expected = [md_ial(expected)] if expected.kind_of? Array
["{#{MagicChar}#{s}}", expected, "Attributes: #{comment}"]
}
end
def md_al(s=[]); AttributeList.new(s) end
# returns nil or an AttributeList

View File

@ -43,7 +43,7 @@ Globals = {
:html_png_url => 'pngs/',
:html_png_resolution => 200,
:html_use_syntax => false,
:html_use_syntax => true,
:latex_use_listings => false,
:latex_cjk => false,

View File

@ -0,0 +1,65 @@
# fenced_code.rb -- Maruku extension for fenced code blocks
#
# Copyright (C) 2009 Jason R. Blevins
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Fenced code blocks begin with three or more tildes and are terminated
# by a closing line with at least as many tildes as the opening line.
# Optionally, an attribute list may appear at the end of the opening
# line. For example:
#
# ~~~~~~~~~~~~~ {: lang=ruby }
# puts 'Hello world'
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OpenFence = /^(~~~+?)\s*(\{([^{}]*?|".*?"|'.*?')*\})?\s*$/
MaRuKu::In::Markdown::register_block_extension(
:regexp => OpenFence,
:handler => lambda { |doc, src, context|
first = src.shift_line
first =~ OpenFence
close_fence = /^#{$1}~*$/
ial = $2
lines = []
# read until CloseFence
while src.cur_line
if src.cur_line =~ close_fence
src.shift_line
break
else
lines.push src.shift_line
end
end
ial = nil unless (ial && ial.size > 0)
al = nil
if ial =~ /^\{(.*?)\}\s*$/
inside = $1
cs = MaRuKu::In::Markdown::SpanLevelParser::CharSource
al = ial &&
doc.read_attribute_list(cs.new(inside),
its_context=nil, break_on=[nil])
end
source = lines.join("\n")
context.push doc.md_codeblock(source, al)
true
})

View File

@ -0,0 +1,143 @@
# fortran.rb -- a free-form Fortran module for the Ruby Syntax library
#
# Copyright (C) 2009 Jason Blevins
# License: 3-clause BSD (the same as Syntax itself)
require 'syntax'
module Syntax
# A tokenizer for free-form Fortran source code.
class Fortran < Tokenizer
# Fortran keywords
LC_KEYWORDS =
%w{ access assign backspace blank block call close common
continue data dimension direct do else endif enddo end entry eof
equivalence err exist external file fmt form format formatted
function go to if implicit include inquire intrinsic iostat
logical named namelist nextrec number open opened parameter pause
print program read rec recl return rewind sequential status stop
subroutine then type unformatted unit write save } +
# Fortran 90 keywords
%w{ allocate allocatable case contains cycle deallocate
elsewhere exit interface intent module only operator
optional pointer private procedure public result recursive
select sequence target use while where } +
# Fortran 95 keywords
%w{ elemental forall pure } +
# Fortran 2003 keywords
%w{ abstract asynchronous bind class delegate static reference
round decimal sign encoding iomsg endfile nextrec pending
pass protected associate flush decorate extends extensible
generic non_overridable enum enumerator typealias move_alloc
volatile }
# List of identifiers recognized as types
LC_TYPES =
%w{ character double integer real precision complex }
# Fortran intrinsic procedures
LC_INTRINSICS = %w{
abs achar acos acosh adjustl adjustr aimag
aint all allocated anint any asin asinh
associated atan atan2 atanh
bessel_j0 bessel_j1 bessel_jn
bessel_y0 bessel_y1 bessel_yn
bit_size btest
c_associated c_f_pointer c_f_procpointer
c_funloc c_loc c_sizeof
ceiling char cmplx command_argument_count
conjg cos cosh count cpu_time cshift
date_and_time dble digits dim dot_product dprod
eoshift epsilon erf erfc erfc_scaled exp exponent
float floor fraction
gamma get_command get_command_argument
get_environment_variable
huge hypot
iachar iand ibclr ibits ibset ichar int ior
is_iostat_end is_iostat_eor ishft ishftc
kind
lbound leadz len len_trim lge lgt lle llt
log log10 log_gamma logical
matmul max maxexponent maxloc maxval merge
min minexponent minloc minval mod modulo
move_alloc mvbits
nearest new_line nint not null
pack precision present product
radix random_number random_seed range real
repeat reshape rrspacing
scale scan selected_char_kind selected_int_kind
selected_real_kind set_exponent shape sign
sin sinh size sngl spacing spread sqrt sum system_clock
tan tanh tiny trailz transfer transpose trim
ubound unpack
verify
}
# Also support all uppercase keywords, types, and procedures
KEYWORDS = Set.new LC_KEYWORDS + LC_KEYWORDS.map { |x| x.upcase }
TYPES = Set.new LC_TYPES + LC_TYPES.map { |x| x.upcase }
INTRINSICS = Set.new LC_INTRINSICS + LC_INTRINSICS.map { |x| x.upcase }
# Step through a single iteration of the tokenization process.
def step
case
when check( /program\s+/ )
start_group :keyword, scan( /program\s+/ )
start_group :function, scan_until( /(?=[;(\s]|#{EOL})/ )
when check( /subroutine\s+/ )
start_group :keyword, scan( /subroutine\s+/ )
start_group :function, scan_until( /(?=[;(\s]|#{EOL})/ )
when check( /function\s+/ )
start_group :keyword, scan( /function\s+/ )
start_group :function, scan_until( /(?=[;(\s]|#{EOL})/ )
when check( /module\s+/ )
start_group :keyword, scan( /module\s+/ )
start_group :function, scan_until( /(?=[;\s]|#{EOL})/ )
when check( /\.true\.|\.false\.|\.TRUE\.|\.FALSE\./ )
start_group :constant,
scan(/\.true\.|\.false\.|\.TRUE\.|\.FALSE\./)
when scan( /(\d+\.?\d*|\d*\.?\d+)([eEdDqQ][+-]?\d+)?(_\w+)?/ )
start_group :number, matched
when scan( /[bB]\'[01]+\'|[oO]\'[0-7]+\'|[zZ]\'[0-9a-fA-F]+\'/ )
start_group :number, matched
else
case peek(1)
when /[\n\r]/
start_group :normal, scan( /\s+/ )
when /\s/
start_group :normal, scan( /\s+/ )
when "!"
start_group :comment, scan( /![^\n\r]*/ )
when /[A-Za-z]/
word = scan( /\w+/ )
if KEYWORDS.include?(word)
start_group :keyword, word
elsif TYPES.include?(word)
start_group :type, word
elsif INTRINSICS.include?(word)
start_group :function, word
elsif
start_group :ident, word
end
when '"'
# allow for continuation characters within strings
start_group :string, scan(/"([^"]*(&[ ]*[\n\r]+)?)*"/)
when "'"
# allow for continuation characters within strings
start_group :string, scan(/'([^']*(&[ ]*[\n\r]+)?)*'/)
when /[-!?*\/+=<>()\[\]\{}:;,&|%]/
start_group :punct, scan(/./)
else
# pass everything else through
append getch
end
end
end
end
SYNTAX["fortran"] = Fortran
end