Updated to latest Maruku.

This commit is contained in:
Jacques Distler 2007-01-23 09:26:45 -06:00
parent 29b4c4b837
commit 1c05a94d1b
9 changed files with 280 additions and 98 deletions

View file

@ -49,7 +49,6 @@ lust cartoon
mijneigenweblog mijneigenweblog
Mortage Mortage
myspace myspace
naked
netfirms\.com netfirms\.com
nice site nice site
overflow:\s*auto overflow:\s*auto

View file

@ -23,8 +23,10 @@ module MaRuKu
Globals = { Globals = {
:unsafe_features => false, :unsafe_features => false,
:on_error => :warning,
:debug_keep_ials => false,
:use_numbered_headers => false,
:maruku_signature => false, :maruku_signature => false,
:code_background_color => '#fef', :code_background_color => '#fef',
@ -37,7 +39,12 @@ Globals = {
:html_png_resolution => 200, :html_png_resolution => 200,
:html_use_syntax => false, :html_use_syntax => false,
:on_error => :warning
:latex_use_listings => false,
:latex_cjk => false,
:debug_keep_ials => false,
} }
class MDElement class MDElement

View file

@ -29,12 +29,13 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
include MaRuKu::Strings include MaRuKu::Strings
Tag = %r{^<(/)?(\w+)\s*([^>]*)>}m Tag = %r{^<(/)?(\w+)\s*([^>]*)>}m
PartialTag = %r{^<.*}m
EverythingElse = %r{^[^<]+}m EverythingElse = %r{^[^<]+}m
CommentStart = %r{^<!--}x CommentStart = %r{^<!--}x
CommentEnd = %r{^.*-->} CommentEnd = %r{^.*-->}
TO_SANITIZE = ['img','hr'] TO_SANITIZE = ['img','hr']
# attr_accessor :inside_comment
attr_reader :rest attr_reader :rest
def initialize def initialize
@ -42,72 +43,61 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
@tag_stack = [] @tag_stack = []
@m = nil @m = nil
@already = "" @already = ""
@inside_comment = false self.state = :inside_element
end end
attr_accessor :state # :inside_element, :inside_tag, :inside_comment,
def eat_this(line) def eat_this(line)
@rest = line + @rest @rest = line + @rest
things_read = 0 things_read = 0
until @rest.empty? until @rest.empty?
if @inside_comment case self.state
if @m = CommentEnd.match(@rest) when :inside_comment
@inside_comment = false if @m = CommentEnd.match(@rest)
@already += @m.pre_match + @m.to_s @already += @m.pre_match + @m.to_s
@rest = @m.post_match @rest = @m.post_match
elsif @m = EverythingElse.match(@rest) self.state = :inside_element
@already += @m.pre_match + @m.to_s else
@rest = @m.post_match @already += @rest
end @rest = ""
else self.state = :inside_comment
if @m = CommentStart.match(@rest)
things_read += 1
@inside_comment = true
@already += @m.pre_match + @m.to_s
@rest = @m.post_match
elsif @m = Tag.match(@rest)
things_read += 1
@already += @m.pre_match
@rest = @m.post_match
is_closing = !!@m[1]
tag = @m[2]
attributes = @m[3]
is_single = false
if attributes =~ /\A(.*)\/\Z/
attributes = $1
is_single = true
end end
when :inside_element
if TO_SANITIZE.include? tag if @m = CommentStart.match(@rest)
attributes.strip! things_read += 1
# puts "Attributes: #{attributes.inspect}" @already += @m.pre_match + @m.to_s
if attributes.size > 0 @rest = @m.post_match
@already += '<%s %s />' % [tag, attributes] self.state = :inside_comment
else elsif @m = Tag.match(@rest) then
@already += '<%s />' % [tag] things_read += 1
end handle_tag
elsif is_closing self.state = :inside_element
@already += @m.to_s elsif @m = PartialTag.match(@rest) then
if @tag_stack.empty? @already += @m.pre_match
error "Malformed: closing tag #{tag.inspect} "+ @rest = @m.post_match
"in empty list" @partial_tag = @m.to_s
end self.state = :inside_tag
if @tag_stack.last != tag elsif @m = EverythingElse.match(@rest)
error "Malformed: tag <#{tag}> "+ @already += @m.pre_match + @m.to_s
"closes <#{@tag_stack.last}>" @rest = @m.post_match
end self.state = :inside_element
@tag_stack.pop else
elsif not is_single error "Malformed HTML: not complete: #{@rest.inspect}"
@tag_stack.push tag end
@already += @m.to_s when :inside_tag
if @m = /^[^>]*>/.match(@rest) then
@partial_tag += @m.to_s
@rest = @partial_tag + @m.post_match
@partial_tag = nil
self.state = :inside_element
else
@partial_tag += @rest
@rest = ""
self.state = :inside_tag
end end
elsif @m = EverythingElse.match(@rest)
@already += @m.pre_match + @m.to_s
@rest = @m.post_match
else else
error "Malformed HTML: not complete: #{@rest.inspect}" raise "Bug bug: state = #{self.state.inspect}"
end
end # not inside comment end # not inside comment
# puts inspect # puts inspect
@ -116,12 +106,53 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
end end
end end
def handle_tag()
@already += @m.pre_match
@rest = @m.post_match
is_closing = !!@m[1]
tag = @m[2]
attributes = @m[3]
is_single = false
if attributes =~ /\A(.*)\/\Z/
attributes = $1
is_single = true
end
# puts "READ TAG #{@m.to_s.inspect} tag = #{tag} closing? #{is_closing} single = #{is_single}"
if TO_SANITIZE.include? tag
attributes.strip!
# puts "Attributes: #{attributes.inspect}"
if attributes.size > 0
@already += '<%s %s />' % [tag, attributes]
else
@already += '<%s />' % [tag]
end
elsif is_closing
@already += @m.to_s
if @tag_stack.empty?
error "Malformed: closing tag #{tag.inspect} "+
"in empty list"
end
if @tag_stack.last != tag
error "Malformed: tag <#{tag}> "+
"closes <#{@tag_stack.last}>"
end
@tag_stack.pop
else
@already += @m.to_s
@tag_stack.push(tag) unless is_single
end
end
def error(s) def error(s)
raise Exception, "Error: #{s} \n"+ inspect, caller raise Exception, "Error: #{s} \n"+ inspect, caller
end end
def inspect; "HTML READER\n comment=#{@inside_comment} "+ def inspect; "HTML READER\n state=#{self.state} "+
"match=#{@m.to_s.inspect}\n"+ "match=#{@m.to_s.inspect}\n"+
"Tag stack = #{@tag_stack.inspect} \n"+ "Tag stack = #{@tag_stack.inspect} \n"+
"Before:\n"+ "Before:\n"+
@ -137,7 +168,7 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
end end
def is_finished? def is_finished?
not @inside_comment and @tag_stack.empty? (self.state == :inside_element) and @tag_stack.empty?
end end
end # html helper end # html helper

View file

@ -557,6 +557,11 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
when ?[ # link ref when ?[ # link ref
ref_id = read_ref_id(src,con) ref_id = read_ref_id(src,con)
if ref_id if ref_id
if ref_id.size == 0
ref_id = children.to_s.downcase.gsub(' ','_')
else
ref_id = ref_id.downcase
end
con.push_element md_link(children, ref_id) con.push_element md_link(children, ref_id)
else else
maruku_error "Could not read ref_id", src, con maruku_error "Could not read ref_id", src, con
@ -566,7 +571,8 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser
return return
end end
else # empty [link] else # empty [link]
con.push_element md_link(children, "") id = children.to_s.downcase.gsub(' ','_')
con.push_element md_link(children, id)
end end
end # read link end # read link

View file

@ -44,11 +44,12 @@ module MaRuKu; module Strings
return :definition if l =~ Definition return :definition if l =~ Definition
# I had a bug with emails and urls at the beginning of the # I had a bug with emails and urls at the beginning of the
# line that were mistaken for raw_html # line that were mistaken for raw_html
return :text if l=~EMailAddress or l=~ URL return :text if l=~ /^#{EMailAddress}/
return :text if l=~ /^<http:/
# raw html is like PHP Markdown Extra: at most three spaces before # raw html is like PHP Markdown Extra: at most three spaces before
return :xml_instr if l =~ %r{^\s*<\?} return :xml_instr if l =~ %r{^\s*<\?}
return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?</?\s*\w+} return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?</?\s*\w+}
return :raw_html if l =~ %r{[ ]{0,3}<\!\-\-} return :raw_html if l =~ %r{^[ ]?[ ]?[ ]?<\!\-\-}
return :ulist if l =~ /^\s?([\*\-\+])\s+.*\w+/ return :ulist if l =~ /^\s?([\*\-\+])\s+.*\w+/
return :olist if l =~ /^\s?\d+\..*\w+/ return :olist if l =~ /^\s?\d+\..*\w+/
return :header1 if l =~ /^(=)+/ return :header1 if l =~ /^(=)+/
@ -137,5 +138,4 @@ module MaRuKu; module Strings
EMailAddress = /<([^:]+@[^:]+)>/ EMailAddress = /<([^:]+@[^:]+)>/
URL = /^<http:/
end end end end

View file

@ -21,8 +21,6 @@
require 'rexml/document' require 'rexml/document'
class String class String
# A string is rendered into HTML by creating # A string is rendered into HTML by creating
# a REXML::Text node. REXML takes care of all the encoding. # a REXML::Text node. REXML takes care of all the encoding.
@ -101,6 +99,52 @@ xhtml11_mathml2_svg11 =
def xml_newline() Text.new("\n") end def xml_newline() Text.new("\n") end
=begin maruku_doc
Attribute: title
Scope: document
Sets the title of the document.
If a title is not specified, the first header will be used.
These should be equivalent:
Title: my document
Content
and
my document
===========
Content
In both cases, the title is set to "my document".
=end
=begin maruku_doc
Attribute: subject
Scope: document
Synonim for `title`.
=end
=begin maruku_doc
Attribute: css
Scope: document
Output: HTML
Summary: Activates CSS stylesheets for HTML.
`css` should be a space-separated list of urls.
Example:
CSS: style.css math.css
=end
# Render to a complete HTML document (returns a REXML document tree) # Render to a complete HTML document (returns a REXML document tree)
def to_html_document_tree def to_html_document_tree
doc = Document.new(nil,{:respect_whitespace =>:all}) doc = Document.new(nil,{:respect_whitespace =>:all})
@ -121,6 +165,7 @@ xhtml11_mathml2_svg11 =
# me.attributes['content'] = 'text/html;charset=utf-8' # me.attributes['content'] = 'text/html;charset=utf-8'
me.attributes['content'] = 'application/xhtml+xml;charset=utf-8' me.attributes['content'] = 'application/xhtml+xml;charset=utf-8'
# Create title element # Create title element
doc_title = self.attributes[:title] || self.attributes[:subject] || "" doc_title = self.attributes[:title] || self.attributes[:subject] || ""
title = Element.new 'title', head title = Element.new 'title', head
@ -243,6 +288,34 @@ xhtml11_mathml2_svg11 =
m m
end end
=begin maruku_doc
Attribute: id
Scope: element
Output: LaTeX, HTML
It is copied as a standard HTML attribute.
Moreover, it used as a label name for hyperlinks in both HTML and
in PDF.
=end
=begin maruku_doc
Attribute: class
Scope: element
Output: HTML
It is copied as a standard HTML attribute.
=end
=begin maruku_doc
Attribute: style
Scope: element
Output: HTML
It is copied as a standard HTML attribute.
=end
StandardAttributes = [:id, :style, :class] StandardAttributes = [:id, :style, :class]
def create_html_element(name, attributes_to_copy=[]) def create_html_element(name, attributes_to_copy=[])
m = Element.new name m = Element.new name
@ -272,9 +345,20 @@ xhtml11_mathml2_svg11 =
def to_html_strong; wrap_as_element('strong') end def to_html_strong; wrap_as_element('strong') end
def to_html_emphasis; wrap_as_element('em') end def to_html_emphasis; wrap_as_element('em') end
=begin maruku_doc
Attribute: use_numbered_headers
Scope: document
Summary: Activates the numbering of headers.
If `true`, section headers will be numbered.
In LaTeX export, the numbering of headers is managed
by Maruku, to have the same results in both HTML and LaTeX.
=end
# nil if not applicable, else string # nil if not applicable, else string
def section_number def section_number
return nil if not @doc.attributes[:use_numbered_headers] return nil if not get_setting(:use_numbered_headers)
n = @attributes[:section_number] n = @attributes[:section_number]
if n && (not n.empty?) if n && (not n.empty?)
@ -315,14 +399,35 @@ xhtml11_mathml2_svg11 =
=begin maruku_doc =begin maruku_doc
Attribute: html_use_syntax Attribute: html_use_syntax
Scope: document Scope: global, document, element
Output: html Output: HTML
Summary: Enables the use of the `syntax` package. Summary: Enables the use of the `syntax` package.
Related: lang, code_lang Related: lang, code_lang
Default: <?mrk Globals[:html_use_syntax].to_s ?> Default: <?mrk md_code(Globals[:html_use_syntax].to_s) ?>
If true, the `syntax` package is used. It supports the `ruby` and `xml`
languages. Remember to set the `lang` attribute of the code block.
Examples:
require 'maruku'
{:lang=ruby html_use_syntax=true}
and
<div style="text-align:center">Div</div>
{:lang=html html_use_syntax=true}
produces:
require 'maruku'
{:lang=ruby html_use_syntax=true}
and
<div style="text-align:center">Div</div>
{:lang=html html_use_syntax=true}
If false, Maruku does not append a signature to the
generated file.
=end =end
def to_html_code; def to_html_code;
@ -378,6 +483,26 @@ generated file.
element element
end end
=begin maruku_doc
Attribute: code_background_color
Scope: global, document, element
Summary: Background color for code blocks.
The format is either a named color (`green`, `red`) or a CSS color
of the form `#ff00ff`.
* for **HTML output**, the value is put straight in the `background-color` CSS
property of the block.
* for **LaTeX output**, if it is a named color, it must be a color accepted
by the LaTeX `color` packages. If it is of the form `#ff00ff`, Maruku
defines a color using the `\color[rgb]{r,g,b}` macro.
For example, for `#0000ff`, the macro is called as: `\color[rgb]{0,0,1}`.
=end
def to_html_code_using_pre(source) def to_html_code_using_pre(source)
pre = create_html_element 'pre' pre = create_html_element 'pre'
code = Element.new 'code', pre code = Element.new 'code', pre
@ -427,11 +552,6 @@ generated file.
def to_html_link def to_html_link
a = wrap_as_element 'a' a = wrap_as_element 'a'
id = self.ref_id id = self.ref_id
# if empty, use text
if id.size == 0
id = children.to_s.downcase.gsub(' ','_')
end
if ref = @doc.refs[id] if ref = @doc.refs[id]
url = ref[:url] url = ref[:url]

View file

@ -88,7 +88,7 @@ while the default is to add this:
<?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_utf8) ?> <?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_utf8) ?>
=end =end
encoding = @doc.attributes[:latex_cjk] ? encoding = get_setting(:latex_cjk) ?
Latex_preamble_enc_cjk : Latex_preamble_enc_utf8 Latex_preamble_enc_cjk : Latex_preamble_enc_utf8
=begin maruku_doc =begin maruku_doc
@ -190,9 +190,31 @@ Admissible formats:
end end
end end
=begin maruku_doc
Attribute: code_show_spaces
Scope: global, document, element
If `true`, shows spaces and tabs in code blocks.
Example:
One space
Two spaces
Tab, space, tab
Tab, tab, tab and all is green!
{:code_show_spaces code_background_color=#ffeedd}
{:markdown}
That will produce:
One space
Two spaces
Tab, space, tab
Tab, tab, tab and all is green!
{:code_show_spaces code_background_color=#ffeedd}
=end
def to_latex_code;
raw_code = self.raw_code
=begin maruku_doc =begin maruku_doc
Attribute: latex_use_listings Attribute: latex_use_listings
Scope: document Scope: document
@ -213,21 +235,24 @@ Otherwise, a standard `verbatim` environment is used.
Please refer to the documentation of the `listings` package for Please refer to the documentation of the `listings` package for
supported languages. supported languages.
If a language is not supported, the `listings` package will emit If a language is not supported, the `listings` package will emit
a warning during the compilation. Just press enter and nothing a warning during the compilation. Just press enter and nothing
wrong will happen. wrong will happen.
* If the `code_show_spaces` is specified, than spaces and tabs will * If the `code_show_spaces` is specified, than spaces and tabs will
be shown using the macro: be shown using the macro:
\lstset{showspaces=true,showtabs=true} \lstset{showspaces=true,showtabs=true}
* The background color is given by `code_background_color`. * The background color is given by `code_background_color`.
=end =end
def to_latex_code;
raw_code = self.raw_code
if @doc.attributes[:latex_use_listings] if get_setting(:latex_use_listings)
@doc.latex_require_package('listings') @doc.latex_require_package('listings')
s = "\\lstset{columns=fixed,frame=shadowbox}" s = "\\lstset{columns=fixed,frame=shadowbox}"
@ -314,7 +339,7 @@ Otherwise, a standard `verbatim` environment is used.
\\end{#{name}}\n" \\end{#{name}}\n"
end end
SAFE_CHARS = Set.new([?\ ] + (?a..?z).to_a + (?A..?Z).to_a) SAFE_CHARS = Set.new((?a..?z).to_a + (?A..?Z).to_a)
# the ultimate escaping # the ultimate escaping
# (is much better than using \verb) # (is much better than using \verb)
def latex_escape(source) def latex_escape(source)
@ -345,7 +370,6 @@ Otherwise, a standard `verbatim` environment is used.
end end
def to_latex_immediate_link def to_latex_immediate_link
a = create_html_element 'a'
url = self.url url = self.url
text = url.gsub(/^mailto:/,'') # don't show mailto text = url.gsub(/^mailto:/,'') # don't show mailto
# gsub('~','$\sim$') # gsub('~','$\sim$')
@ -372,11 +396,6 @@ Otherwise, a standard `verbatim` environment is used.
def to_latex_link def to_latex_link
id = self.ref_id id = self.ref_id
# if empty, use text
if id.size == 0
id = children.to_s.downcase
end
ref = @doc.refs[id] ref = @doc.refs[id]
if not ref if not ref
$stderr.puts "Could not find id = '#{id}'" $stderr.puts "Could not find id = '#{id}'"

View file

@ -152,10 +152,10 @@ module MaRuKu; module Tests
["\\[a\\]", ["[a]"], 'Escaping 2'], ["\\[a\\]", ["[a]"], 'Escaping 2'],
# This is valid in the new Markdown version # This is valid in the new Markdown version
# ["[a]", ["a"], 'Not a link'], # ["[a]", ["a"], 'Not a link'],
["[a]", [ md_link(["a"],'')], 'Empty link'], ["[a]", [ md_link(["a"],'a')], 'Empty link'],
["[a][]", ], ["[a][]", ],
["[a][]b", [ md_link(["a"],''),'b'], 'Empty link'], ["[a][]b", [ md_link(["a"],'a'),'b'], 'Empty link'],
["[a\\]][]", [ md_link(["a]"],'')], 'Escape inside link'], ["[a\\]][]", [ md_link(["a]"],'a]')], 'Escape inside link'],
["[a", :throw, 'Link not closed'], ["[a", :throw, 'Link not closed'],
["[a][", :throw, 'Ref not closed'], ["[a][", :throw, 'Ref not closed'],

View file

@ -19,7 +19,7 @@
#++ #++
module MaRuKu module MaRuKu
Version = '0.4.2.1' Version = '0.5.0'
MarukuURL = 'http://maruku.rubyforge.org/' MarukuURL = 'http://maruku.rubyforge.org/'