maruku-0.7.2/0000755000004100000410000000000012347070213013053 5ustar www-datawww-datamaruku-0.7.2/data/0000755000004100000410000000000012347070213013764 5ustar www-datawww-datamaruku-0.7.2/data/entities.xml0000644000004100000410000003235512347070213016342 0ustar www-datawww-data maruku-0.7.2/bin/0000755000004100000410000000000012347070213013623 5ustar www-datawww-datamaruku-0.7.2/bin/maruku0000755000004100000410000001125112347070213015055 0ustar www-datawww-data#!/usr/bin/env ruby dir = File.join(File.dirname(__FILE__), '..', 'lib') $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir) require 'maruku' require 'optparse' def cli_puts(s) $stderr.puts(s) if MaRuKu::Globals[:verbose] end def benchmark(section) t = Time.now res = yield cli_puts("%s finished in %.2f seconds." % [section, Time.now - t]) res end export = :html break_on_error = false using_math = false using_mathml = false output_file = nil opt = OptionParser.new do |opts| opts.banner = "Usage: #{File.basename($0)} [options] [file1.md] [file2.md] ..." opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| MaRuKu::Globals[:verbose] = v end opts.on("-u", "--[no-]unsafe", "Use unsafe features") do |v| MaRuKu::Globals[:unsafe_features] = v end opts.on("-b", "--[no-]break", "Break on error") do |v| break_on_error = v end opts.on("-i", "--math-images ENGINE", "Use ENGINE to render TeX to PNG") do |s| using_math = true MaRuKu::Globals[:html_math_output_png] = true MaRuKu::Globals[:html_math_output_mathml] = false MaRuKu::Globals[:html_png_engine] = s cli_puts "Using png engine #{s}." end opts.on("-m", "--math-engine ENGINE", "Use ENGINE to render MathML") do |s| MaRuKu::Globals[:html_math_output_png] = false MaRuKu::Globals[:html_math_output_mathml] = true using_math = true using_mathml = true MaRuKu::Globals[:html_math_engine] = s end opts.on("-o", "--output FILE", "Output filename (`-o -' writes to stdout)") {|s| output_file = s} opts.on_tail("--pdf", "Output PDF;", "first writes LaTeX, then calls pdflatex") {export = :pdf} opts.on_tail("--s5", "Output S5 slideshow") {export = :s5} opts.on_tail("--html", "Output HTML") {export = :html} opts.on_tail("--html-frag", "Output the contents of the tag") {export = :html_frag} opts.on_tail("--tex", "Output LaTeX" ) {export = :tex} opts.on_tail("--markdown", "Output Markdown" ) {export = :markdown} opts.on_tail("--inspect", "Output the parse tree") {export = :inspect} opts.on_tail("--ext EXTENSIONS", "Use Maruku extensions (comma separated)") do |s| s.split(",").each {|e| require "maruku/ext/#{e}"} end opts.on_tail("-h", "--help", "Show this help message") do puts opts exit end opts.on_tail("--version", "Show version") do puts "Maruku #{MaRuKu::Version}" exit end end begin opt.parse! rescue OptionParser::InvalidOption => e $stderr.puts e $stderr.puts opt exit 1 end if using_math cli_puts "Using Math extensions." require 'maruku/ext/math' end unless ARGV.empty? if ARGV.size > 1 && output_file $stderr.puts "Can't write #{ARGV.map {|f| f.inspect}.join(' and ')} to #{output_file.inspect}" exit 1 end # If we are given filenames, convert each file ARGV.map do |f| # read file content cli_puts "Reading from file #{f.inspect}." [f, File.read(f)] end else export = :html_frag if export == :html export = :tex_frag if export == :tex cli_puts "Reading from standard input." [[nil, $stdin.read]] end.each do |filename, input| doc = benchmark("Parsing") {Maruku.new(input, :on_error => (break_on_error ? :raise : :warning))} out = "" suffix = "?" benchmark("Rendering") do case export when :html suffix = using_mathml ? '.xhtml' : '.html' out = doc.to_html_document when :html_frag suffix = '.html_frag' out = doc.to_html when :pdf, :tex suffix = '.tex' out = doc.to_latex_document when :tex_frag suffix = '.tex_frag' out = doc.to_latex when :inspect suffix = '.txt' out = doc.inspect when :markdown suffix = '.md' out = doc.to_md when :s5 suffix = '_s5slides.html' out = doc.to_s5(:content_only => false, :print_slides => true) end end if (output_file.nil? && filename.nil?) || output_file == "-" if export == :pdf $stderr.puts "Can't write PDF to stdout" exit 1 end cli_puts "Writing to standard output" $stdout.puts out next end if output_file job = File.basename(output_file, File.extname(output_file)) else dir = File.dirname(filename) job = File.join(dir, File.basename(filename, File.extname(filename))) output_file = job + suffix end if export == :pdf cli_puts "Writing to #{job}.tex" File.open("#{job}.tex", 'w') {|f| f.puts out} cmd = ["pdflatex", "#{job}.tex", "-interaction=nonstopmode"] cmd << "-output-directory=#{dir}" if dir cli_puts "maruku: executing $ #{cmd.join(' ')}" # run twice for cross references system *cmd system *cmd next end cli_puts "Writing to #{output_file.inspect}" File.open(output_file, 'w') {|f| f.puts out} end maruku-0.7.2/bin/marutex0000755000004100000410000000013312347070213015233 0ustar www-datawww-data#!/usr/bin/env ruby ARGV.unshift "--pdf" load File.join(File.dirname(__FILE__), "maruku") maruku-0.7.2/data.tar.gz.sig0000444000004100000410000000040012347070213015664 0ustar www-datawww-data"h[! s2%iItͫ4%ޫi=4V=OH;(\c-+&amaruku-0.7.2/spec/0000755000004100000410000000000012347070213014005 5ustar www-datawww-datamaruku-0.7.2/spec/block_spec.rb0000644000004100000410000000666012347070213016446 0ustar www-datawww-data# encoding: UTF-8 Encoding.default_external=('UTF-8') if ''.respond_to?(:force_encoding) require File.dirname(__FILE__) + '/spec_helper' require 'rspec' require 'maruku' require 'nokogiri/diff' # Allow us to test both HTML parser backends MaRuKu::Globals[:html_parser] = ENV['HTML_PARSER'] if ENV['HTML_PARSER'] puts "Using HTML parser: #{MaRuKu::Globals[:html_parser]}" # :to_md and :to_s tests are disabled for now METHODS = [:to_html, :to_latex] def which(cmd) exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| exts.each { |ext| exe = File.join(path, "#{cmd}#{ext}") return exe if File.executable? exe } end return nil end if which('blahtex') HAS_BLAHTEX = true else HAS_BLAHTEX = false puts "Install 'blahtex' to run blahtex math tests" end describe "A Maruku doc" do before(:all) do @old_stderr = $stderr $stderr = StringIO.new end after(:all) do $stderr = @old_stderr end Dir[File.dirname(__FILE__) + "/block_docs/**/*.md"].each do |md| next if md =~ /blahtex/ && !HAS_BLAHTEX md_pretty = md.sub(File.dirname(__FILE__) + '/', '') describe "#{md_pretty} (using #{MaRuKu::Globals[:html_parser]})" do input = File.read(md).split(/\n\*{3}[^*\n]+\*{3}\n/m) input = ["Write a comment here", "{}", input.first] if input.size == 1 comment = input.shift.strip params = input.shift || '' markdown = input.shift || '' ast = input.shift || '' expected = METHODS.zip(input).inject({}) {|h, (k, v)| h[k] = v ? v.strip : '' ; h} pending "#{comment} - #{md_pretty}" and next if comment.start_with?("PENDING") pending "#{comment} - #{md_pretty}" and next if comment.start_with?("REXML PENDING") && MaRuKu::Globals[:html_parser] == 'rexml' pending "#{comment} - #{md_pretty}" and next if comment.start_with?("JRUBY PENDING") && RUBY_PLATFORM == 'java' pending "#{comment} - #{md_pretty}" and next if comment.start_with?("JRUBY NOKOGIRI PENDING") && RUBY_PLATFORM == 'java' && MaRuKu::Globals[:html_parser] == 'nokogiri' before(:each) do $already_warned_itex2mml = false @doc = Maruku.new(markdown, eval(params)) end it "should read in the output of #inspect as the same document" do Maruku.new.instance_eval("#coding: utf-8\n#{@doc.inspect}", md).should == @doc end unless ast.strip.empty? it "should produce the given AST" do @doc.should == Maruku.new.instance_eval(ast, md) end end unless expected[:to_html].strip.empty? it "should have the expected to_html output" do res = @doc.to_html.strip pending "install itex2mml to run these tests" if $already_warned_itex2mml resdoc = Nokogiri::XML("#{res}") expdoc = Nokogiri::XML("#{expected[:to_html]}") diff = "" changed = false expdoc.diff(resdoc) do |change, node| diff << "#{change} #{node.inspect}\n" changed = true unless change == ' ' || (node.text? && node.content =~ /\A\s*\Z/m) end if changed res.should == expected[:to_html] end end end unless expected[:to_latex].strip.empty? it "should have the expected to_latex output" do res = @doc.to_latex.strip res.should == expected[:to_latex] end end end end end maruku-0.7.2/spec/cli_spec.rb0000644000004100000410000000032612347070213016114 0ustar www-datawww-datarequire File.dirname(__FILE__) + '/spec_helper' describe "The maruku CLI" do it "has a nonzero exit code on invalid options" do `ruby -Ilib bin/maruku --foo 2>&1` $?.exitstatus.should_not == 0 end end maruku-0.7.2/spec/spec_helper.rb0000644000004100000410000000014412347070213016622 0ustar www-datawww-datarequire 'json' require 'simplecov' SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/..')) maruku-0.7.2/spec/to_html_utf8_spec.rb0000644000004100000410000000054612347070213017765 0ustar www-datawww-data# encoding: UTF-8 require File.dirname(__FILE__) + '/spec_helper' require 'rspec' require 'maruku' describe "Maruku to_html" do # This test used to hang in JRuby! it "can produce HTML for a document that contains non-ASCII characters" do doc = Maruku.new.instance_eval 'md_el(:document,["è"],{},[])' doc.to_html.strip.should == "è" end end maruku-0.7.2/spec/span_spec.rb0000644000004100000410000002437512347070213016320 0ustar www-datawww-datarequire File.dirname(__FILE__) + '/spec_helper' require 'rspec' require 'maruku' EXPECTATIONS = Maruku.new.instance_eval do [ ["", [], 'Empty string gives empty list'], ["a", ["a"], 'Easy char'], [" a", ["a"], 'First space in the paragraph is ignored'], ["a\n \n", ["a"], 'Last spaces in the paragraphs are ignored'], [' ', [], 'One char => nothing'], [' ', [], 'Two chars => nothing'], ['a b', ['a b'], 'Spaces are compressed'], ['a b', ['a b'], 'Newlines are spaces'], ["a\nb", ['a b'], 'Newlines are spaces'], ["a\n b", ['a b'], 'Compress newlines 1'], ["a \nb", ['a b'], 'Compress newlines 2'], [" \nb", ['b'], 'Compress newlines 3'], ["\nb", ['b'], 'Compress newlines 4'], ["b\n", ['b'], 'Compress newlines 5'], ["\n", [], 'Compress newlines 6'], ["\n\n\n", [], 'Compress newlines 7'], # Code blocks ["`" , :raise, 'Unclosed single ticks'], ["``" , [md_entity("ldquo")], 'Empty code block'], ["`a`" , [md_code('a')], 'Simple inline code'], ["`` ` ``" , [md_code('`')], ], ["`` \\` ``" , [md_code('\\`')], ], ["``a``" , [md_code('a')], ], ["`` a ``" , [md_code('a')], ], # Newlines ["a \n", ['a',md_el(:linebreak)], 'Two spaces give br.'], ["a \n", ['a'], 'Newlines 2'], [" \n", [md_el(:linebreak)], 'Newlines 3'], [" \n \n", [md_el(:linebreak),md_el(:linebreak)],'Newlines 4'], [" \na \n", [md_el(:linebreak),'a',md_el(:linebreak)],'Newlines 5'], # Inline HTML ["a < b", ['a < b'], '< can be on itself'], ["
", [md_html('
')], 'HR will be sanitized'], ["
", [md_html('
')], 'Closed tag is ok'], ["
", [md_html('
')], 'Closed tag is ok 2'], ["
a", [md_html('
'),'a'], 'Closed tag is ok 2'], ["a", [md_html(''),'a'], 'Inline HTML 1'], ["ea", [md_html('e'),'a'], 'Inline HTML 2'], ["aeb", ['a',md_html('e'),'b'], 'Inline HTML 3'], ["eaf", [md_html('e'),'a',md_html('f')], 'Inline HTML 4'], ["efa", [md_html('e'),md_html('f'),'a'], 'Inline HTML 5'], ["", [md_html("")], 'Attributes'], [""], # emphasis ["**", :raise, 'Unclosed double **'], ["\\*", ['*'], 'Escaping of *'], ["a *b* ", ['a ', md_em('b')], 'Emphasis 1'], ["a *b*", ['a ', md_em('b')], 'Emphasis 2'], ["a * b", ['a * b'], 'Emphasis 3'], ["a * b*", :raise, 'Unclosed emphasis'], # same with underscore ["__", :raise, 'Unclosed double __'], ["\\_", ['_'], 'Escaping of _'], ["a _b_ ", ['a ', md_em('b')], 'Emphasis 4'], ["a _b_", ['a ', md_em('b')], 'Emphasis 5'], ["a _ b", ['a _ b'], 'Emphasis 6'], ["a _ b_", :raise, 'Unclosed emphasis'], ["_b_", [md_em('b')], 'Emphasis 7'], ["_b_ _c_", [md_em('b'),' ',md_em('c')], 'Emphasis 8'], ["_b__c_", [md_em('b'),md_em('c')], 'Emphasis 9', true], # PENDING # underscores in word ["mod_ruby", ['mod_ruby'], 'Word with underscore'], # strong ["**a*", :raise, 'Unclosed double ** 2'], ["\\**a*", ['*', md_em('a')], 'Escaping of *'], ["a **b** ", ['a ', md_strong('b')], 'Emphasis 1'], ["a **b**", ['a ', md_strong('b')], 'Emphasis 2'], ["a ** b", ['a ** b'], 'Emphasis 3'], ["a ** b**", :raise, 'Unclosed emphasis'], ["**b****c**", [md_strong('b'),md_strong('c')], 'Emphasis 9'], ["*italic***bold***italic*", [md_em('italic'), md_strong('bold'), md_em('italic')], 'Bold inbetween italics'], # Issue #103 # strong (with underscore) ["__a_", :raise, 'Unclosed double __ 2'], ["a __b__ ", ['a ', md_strong('b')], 'Emphasis 1'], ["a __b__", ['a ', md_strong('b')], 'Emphasis 2'], ["a __ b", ['a __ b'], 'Emphasis 3'], ["a __ b__", :raise, 'Unclosed emphasis'], ["__b____c__", [md_strong('b'),md_strong('c')], 'Emphasis 9'], # extra strong ["***a**", :raise, 'Unclosed triple *** '], ["\\***a**", ['*', md_strong('a')], 'Escaping of *'], ["a ***b*** ", ['a ', md_emstrong('b')], 'Strong elements'], ["a ***b***", ['a ', md_emstrong('b')]], ["a *** b", ['a *** b']], ["a ** * b", ['a ** * b']], ["***b******c***", [md_emstrong('b'),md_emstrong('c')]], ["a *** b***", :raise, 'Unclosed emphasis'], # same with underscores ["___a__", :raise, 'Unclosed triple *** '], ["a ___b___ ", ['a ', md_emstrong('b')], 'Strong elements'], ["a ___b___", ['a ', md_emstrong('b')]], ["a ___ b", ['a ___ b']], ["a __ _ b", ['a __ _ b']], ["___b______c___", [md_emstrong('b'),md_emstrong('c')]], ["a ___ b___", :raise, 'Unclosed emphasis'], # mixing is bad ["*a_", :raise, 'Mixing is bad'], ["_a*", :raise], ["**a__", :raise], ["__a**", :raise], ["___a***", :raise], ["***a___", :raise], ["*This is in italic, and this is **bold**.*", [md_em(["This is in italic, and this is ", md_strong("bold"), "."])], 'Issue #23'], # links of the form [text][ref] ["\\[a]", ["[a]"], 'Escaping 1'], ["\\[a\\]", ["[a]"], 'Escaping 2'], # This is valid in the new Markdown version ["[a]", [ md_link(["a"],nil)], 'Empty link'], ["[a][]", [ md_link(["a"],'')] ], ["[a][]b", [ md_link(["a"],''),'b'], 'Empty link'], ["[a\\]][]", [ md_link(["a]"],'')], 'Escape inside link (throw ?] away)'], ["[a", :raise, 'Link not closed'], ["[a][", :raise, 'Ref not closed'], # links of the form [text](url) ["\\[a](b)", ["[a](b)"], 'Links'], ["[a](url)c", [md_im_link(['a'],'url'),'c'], 'url'], ["[a]( url )c" ], ["[a] ( url )c" ], ["[a] ( url)c" ], ["[a](ur:/l/ 'Title')", [md_im_link(['a'],'ur:/l/','Title')], 'url and title'], ["[a] ( ur:/l/ \"Title\")" ], ["[a] ( ur:/l/ \"Title\")" ], ["[a]( ur:/l/ Title)", :raise, "Must quote title" ], ["[a](url 'Tit\\\"l\\\\e')", [md_im_link(['a'],'url','Tit"l\\e')], 'url and title escaped'], ["[a] ( url \"Tit\\\"l\\\\e\")" ], ["[a] ( url \"Tit\\\"l\\\\e\" )" ], ['[a] ( url "Tit\\"l\\\\e" )' ], ["[a]()", [md_im_link(['a'],'')], 'No URL is OK'], ["[a](\"Title\")", :raise, "No url specified" ], ["[a](url \"Title)", :raise, "Unclosed quotes" ], ["[a](url \"Title\\\")", :raise], ["[a](url \"Title\" ", :raise], ["[a](url \'Title\")", :raise, "Mixing is bad" ], ["[a](url \"Title\')"], ["[a](/url)", [md_im_link(['a'],'/url')], 'Funny chars in url'], ["[a](#url)", [md_im_link(['a'],'#url')]], ["[a]()", [md_im_link(['a'],'/script?foo=1&bar=2')]], # Links to URLs that contain closing parentheses. #128 ['[a](url())', [md_im_link(['a'],'url()')], 'Link with parentheses 1', true], # PENDING ['[a](url\(\))', [md_im_link(['a'],'url()')], 'Link with parentheses 2', true], # PENDING ['[a](url()foo)', [md_im_link(['a'],'url()foo')], 'Link with parentheses 3', true], # PENDING ['[a](url(foo))', [md_im_link(['a'],'url(foo)')], 'Link with parentheses 4', true], # PENDING # Images ["\\![a](url)", ['!', md_im_link(['a'],'url') ], 'Escaping images'], ["![a](url)", [md_im_image(['a'],'url')], 'Image no title'], ["![a]( url )" ], ["![a] ( url )" ], ["![a] ( url)" ], ["![a](url 'ti\"tle')", [md_im_image(['a'],'url','ti"tle')], 'Image with title'], ['![a]( url "ti\\"tle")' ], ["![a](url", :raise, 'Invalid images'], ["![a( url )" ], ["![a] ('url )" ], ["![a][imref]", [md_image(['a'],'imref')], 'Image with ref'], ["![a][ imref]", [md_image(['a'],' imref')], 'Image with ref'], ["![a][ imref ]", [md_image(['a'],' imref ' )], 'Image with ref'], ["![a][\timref\t]", [md_image(['a'],"\timref\t")], 'Image with ref'], ['', [md_url('http://example.com/?foo=1&bar=2')], 'Immediate link'], ['', [md_url('https://example.com/?foo=1&bar=2')], 'Immediate link https'], ['ab', ['a',md_url('http://example.com/?foo=1&bar=2'),'b'] ], ['', [md_email('andrea@censi.org')], 'Email address'], [''], ["Developmen ", ["Developmen ", md_url("http://rubyforge.org/projects/maruku/")]], ["ab", ['a',md_html(''),'b'], 'HTML Comment'], ["a *** Output of inspect *** md_el(:document,[md_html(""), md_html("")]) *** Output of to_html *** maruku-0.7.2/spec/block_docs/abbrev.md0000644000004100000410000016604112347070213017702 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** WebKit (Safari 3.1) and the CSS @font-face declaration ====================================================== I'm a big fan of typography in general. If you check out [my homepage](http://elliottcable.name) or my [contact elliottcable](http://elliottcable.name/contact.xhtml) page, and you're using Safari/WebKit or Opera/Kestrel, you'll notice the typefaces (fonts, as colloquialized) are *very* non-standard. (As of this writing, I'm using [Museo][] and [Diavlo][][^jos] heavily on both.) The internet has not be a friendly place for typohiles like myself, up to this point, at least. One might even say it was a frightful, mentally scarring environment for those akin to yours truly. We've been restricted to reading page after page after page on day after day after day for year after year after year abominations of markup and design enslaved by the horrible overlords we know as Lucida, Verdana, Arial, Helvetica, Geneva, Georgia, Courier, and... dare I invoke ye, thou my terrible overlord? Times New Roman. Wherefore art thou, my glorious Archer? And thee as well, my beautiful Garamond? The technical restrictions of that horrible monster we know as the Web Browser hath forced us all too long to use those most banal, those most common, and those most abused, out of all of the typefaces of the world. All hyperbole aside, I'm extremely happy to see the advent of a standard `@font-face` declaration in CSS. Internet Explorer first implemented a crutched, basic version of this way back in version 4, but nothing ever really came of it - their decision to create the proprietary .EOT[^eot] format to appease overly restrictive type foundries' worries about intellectual property (aka. the cold, hard dominatrix that we know only as Ms. Profit) truly and completely killed that initial attempt at bringing astute typography and it's advocates to the web. This new run at `@font-face` by an established, trusted, and open group (the [W3C][] itself, responsible for helping to make much of what we use as designers on the web standard and cross-system compatible) has a much better chance, in my humble opinion - and I am quite looking forward to the consequences if it succeeds. Now, onwards to the topic of my post as declared in the header (yes, I know, a slow start - but it's an interesting topic with an interesting history!). WebKit, the open source rendering engine behind the wonderfulness that is Safari, and how it handles the 'new' `@font-face` declaration. No, it's not really 'new', but yes, it feels like it is. To put it simply, and to be very blunt, it's broken. The [CSS spec section][spec] for `@font-face` is very specific - typefaces are to be selected based on a wide array of criteria placed in the `@font-face` declaration block itself. Various textual CSS attributes may be defined within the `@font-face` declaration, and then they will be checked when the typeface is referred to later in the CSS. For instance, if I have two `@font-face` declarations for the Diavlo family - one for regular text, and one for a heavier weighted version of the typeface - then I later utilize Diavlo in a `font-family:` attribute, it should refer to the basic Diavlo font defined in the first `@font-face`. However, if I were to do the same, but also specify a heavy `font-weight:`, then it should use the heavier version of Diavlo. To place this example in code: @font-face { font-family: 'Diavlo'; src: url(./Diavlo/Diavlo_Book.otf) format("opentype"); } @font-face { font-family: 'Diavlo'; font-weight: 900; src: url(./Diavlo/Diavlo_Black.otf) format("opentype"); } h1, h2, h3, h4, h5, h6 { font-family: 'Diavlo'; font-weight: 900; } div#content { font-family: 'Diavlo'; } As you can see, my headings should use the typeface defined in `Diavlo_Black.otf`, while my body content should use `Diavlo_Book.otf`. However, in WebKit, this doesn't work - it completely ignores any attribute except `font-family:` and `src:` in a `@font-face` declaration! Completely ignores them! Not only that - not *only* that - it disregards all but the last `@font-face` for a given `font-family:` attribute string! The implication here is that, to make `@font-face` work as it is currently implemented in WebKit (and thus, Safari 3.1), I have to declare *completely imaginary, non-existent type families* to satisfy WebKit alone. Here's the method I have used in the places I current implement `@font-face`: @font-face { font-family: 'Diavlo Book'; src: url(./Diavlo/Diavlo_Book.otf) format("opentype"); } @font-face { font-family: 'Diavlo Black'; src: url(./Diavlo/Diavlo_Black.otf) format("opentype"); } h1, h2, h3, h4, h5, h6 { font-family: 'Diavlo Black'; } div#content { font-family: 'Diavlo Book'; } Isn't it horrible? Seriously, my eyes, they bleed. There's lots of problems with this far beyond the lack of semanticity when it comes to the typeface names... let me see how many ways this breaks the purpose of `@font-face`: - You remove a large element our control over the display of the page. As soon as we begin to use `@font-face` in our page, we can no longer make any use of any other textual control attribute - `font-weight:`, `font-style:`, and `font-variant:` are no longer available to us, because they no longer correctly map to technical typeface variant/features. Also, many default elements are destroyed, unusable, without 'fixing' - for instance, `` would have no effect in a page styled for WebKit as above; We would have to specify something like `b {font-family: 'Diavlo Black';}` - how broken is that? Unless we caught all such default elements and re-styled them to use the bastardized names instead of the correct attributes, lots of basic HTML formatting would be broken. I myself may never use in-document formatting (separation of design and content!), but what about comments forms? Forum posts? Direct HTML-literal quotes? If we want to use Javascript to modify the display of the content, we can't simply adjust the mentioned textual control attributes - we have to know and change the entire `font-family:` array of strings. - You make us very wet. And by wet, I mean 'not DRY'. What if we decide to change one of the bastardized font names? Or use a different font entirely? We have to go through all of our CSS, all of our Javascript, and make sure we update every occurrence of the typeface's bastardized name. - You remove our user's user choice, and waste bandwidth. Since the names refer to families that don't, in fact, exist, the browser can't override the declaration with a user's installed version of the typeface. This means that, regardless of whether the user already has the typeface installed on their own computer, the browser won't use that - it doesn't know to use 'Diavlo', which the user has installed, because it was told to use 'Diavlo Black', which no user in the entire world has installed on their computer. This whole thing is rather worrying - I've heard Opera has `@font-face` support, though I haven't had time to test this myself, so I don't know if it actually does - or, for that matter, if it does it 'correctly', or has the same problems as WebKit. But either way, WebKit is one of the first two implementations to ever attempt to support `@font-face` (Microsoft's unrelated `@font-face` declaration notwithstanding) - I really don't want to see it's early mistakes carried on to FireFox in a few years, and then Internet Explorer a few decades after that. That will leave us stuck with this broken system forever, as it has been demonstrated time and time again that if nobody else supports an old standard correctly, a newcomer to the standard will not do it correctly either. I for one would really, really, hate that. In summary... come on, WebKit team, this isn't like you - you're always the ones with the closest-to-standard implementation, and the cleanest code, and... hell, overall? Webkit is the most secure/fastest browser available. But this is making me lose my faith in you, guys, please get it right. You're pioneering a leap into the future when it comes to the Web - this is as important, or _more_ important, than Mosiac's allowing of images was. To put it succinctly - don't fuck this up, y'all. [Museo]: (Jos Buivenga's Museo free typeface) [Diavlo]: (Jos Buivenga's free Diavlo typeface) [^jos]: These are fonts by [Jos Buivenga][jos], quite the amazing person. His (free) fonts are, uniquely, released for use on the web in `@font-face` declarations - unlike the vast majority of other (even free to download) typefaces, which have ridiculously restricting licenses and terms of use statements. Props, Jos - you're a pioneer, and deserve recognition as such. *[CSS]: Cascading Style Sheets *[.EOT]: Embedded OpenType [^eot]: To give Microsoft a little credit, something I rarely do... Yes, I'm aware Microsoft submitted EOT to the W3C as a proposal - the problem isn't with their attempts to make it non-proprietary, but with the basic concept of making typefaces on the web DRMed. Look what such attempts have done to the music and video industry - simply decimated it. Do we really want to see the same thing happen to our beloved medium as typography moves into the 21st century? *[W3C]: World Wide Web Consortium [W3C]: (World Wide Web Consortium) [spec]: () *[DRY]: Don't Repeat Yourself [jos]: jos *** Output of inspect *** md_el(:document,[ md_el(:header,[ "WebKit (Safari 3.1) and the ", md_el(:abbr,["CSS"],{:title=>"Cascading Style Sheets"},[]), " @font-face declaration" ],{:level=>1},[]), md_par([ "I", md_entity("rsquo"), "m a big fan of typography in general. If you check out ", md_im_link(["my homepage"], "http://elliottcable.name", nil), " or my ", md_im_link(["contact elliottcable"], "http://elliottcable.name/contact.xhtml", nil), " page, and you", md_entity("rsquo"), "re using Safari/WebKit or Opera/Kestrel, you", md_entity("rsquo"), "ll notice the typefaces (fonts, as colloquialized) are ", md_em(["very"]), " non-standard. (As of this writing, I", md_entity("rsquo"), "m using ", md_link(["Museo"],""), " and ", md_link(["Diavlo"],""), md_foot_ref("^jos"), " heavily on both.)" ]), md_par([ "The internet has not be a friendly place for typohiles like myself, up to this point, at least. One might even say it was a frightful, mentally scarring environment for those akin to yours truly. We", md_entity("rsquo"), "ve been restricted to reading page after page after page on day after day after day for year after year after year abominations of markup and design enslaved by the horrible overlords we know as Lucida, Verdana, Arial, Helvetica, Geneva, Georgia, Courier, and", md_entity("hellip"), " dare I invoke ye, thou my terrible overlord? Times New Roman." ]), md_par([ "Wherefore art thou, my glorious Archer? And thee as well, my beautiful Garamond? The technical restrictions of that horrible monster we know as the Web Browser hath forced us all too long to use those most banal, those most common, and those most abused, out of all of the typefaces of the world." ]), md_par([ "All hyperbole aside, I", md_entity("rsquo"), "m extremely happy to see the advent of a standard ", md_code("@font-face"), " declaration in ", md_el(:abbr,["CSS"],{:title=>"Cascading Style Sheets"},[]), ". Internet Explorer first implemented a crutched, basic version of this way back in version 4, but nothing ever really came of it - their decision to create the proprietary ", md_el(:abbr,[".EOT"],{:title=>"Embedded OpenType"},[]), md_foot_ref("^eot"), " format to appease overly restrictive type foundries", md_entity("rsquo"), " worries about intellectual property (aka. the cold, hard dominatrix that we know only as Ms. Profit) truly and completely killed that initial attempt at bringing astute typography and it", md_entity("rsquo"), "s advocates to the web. This new run at ", md_code("@font-face"), " by an established, trusted, and open group (the ", md_link([md_el(:abbr,["W3C"],{:title=>"World Wide Web Consortium"},[])], ""), " itself, responsible for helping to make much of what we use as designers on the web standard and cross-system compatible) has a much better chance, in my humble opinion - and I am quite looking forward to the consequences if it succeeds." ]), md_par([ "Now, onwards to the topic of my post as declared in the header (yes, I know, a slow start - but it", md_entity("rsquo"), "s an interesting topic with an interesting history!). WebKit, the open source rendering engine behind the wonderfulness that is Safari, and how it handles the ", md_entity("lsquo"), "new", md_entity("rsquo"), " ", md_code("@font-face"), " declaration. No, it", md_entity("rsquo"), "s not really ", md_entity("lsquo"), "new", md_entity("rsquo"), ", but yes, it feels like it is." ]), md_par([ "To put it simply, and to be very blunt, it", md_entity("rsquo"), "s broken." ]), md_par([ "The ", md_link([ md_el(:abbr,["CSS"],{:title=>"Cascading Style Sheets"},[]), " spec section" ], "spec"), " for ", md_code("@font-face"), " is very specific - typefaces are to be selected based on a wide array of criteria placed in the ", md_code("@font-face"), " declaration block itself. Various textual ", md_el(:abbr,["CSS"],{:title=>"Cascading Style Sheets"},[]), " attributes may be defined within the ", md_code("@font-face"), " declaration, and then they will be checked when the typeface is referred to later in the ", md_el(:abbr,["CSS"],{:title=>"Cascading Style Sheets"},[]), ". For instance, if I have two ", md_code("@font-face"), " declarations for the Diavlo family - one for regular text, and one for a heavier weighted version of the typeface - then I later utilize Diavlo in a ", md_code("font-family:"), " attribute, it should refer to the basic Diavlo font defined in the first ", md_code("@font-face"), ". However, if I were to do the same, but also specify a heavy ", md_code("font-weight:"), ", then it should use the heavier version of Diavlo. To place this example in code:" ]), md_el(:code,[],{:raw_code=>"@font-face {\n font-family: 'Diavlo';\n src: url(./Diavlo/Diavlo_Book.otf) format(\"opentype\");\n}\n\n@font-face {\n font-family: 'Diavlo';\n font-weight: 900;\n src: url(./Diavlo/Diavlo_Black.otf) format(\"opentype\");\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-family: 'Diavlo';\n font-weight: 900;\n}\n\ndiv#content {\n font-family: 'Diavlo';\n}", :lang=>nil},[]), md_par([ "As you can see, my headings should use the typeface defined in ", md_code("Diavlo_Black.otf"), ", while my body content should use ", md_code("Diavlo_Book.otf"), ". However, in WebKit, this doesn", md_entity("rsquo"), "t work - it completely ignores any attribute except ", md_code("font-family:"), " and ", md_code("src:"), " in a ", md_code("@font-face"), " declaration! Completely ignores them! Not only that - not ", md_em(["only"]), " that - it disregards all but the last ", md_code("@font-face"), " for a given ", md_code("font-family:"), " attribute string!" ]), md_par([ "The implication here is that, to make ", md_code("@font-face"), " work as it is currently implemented in WebKit (and thus, Safari 3.1), I have to declare ", md_em(["completely imaginary, non-existent type families"]), " to satisfy WebKit alone. Here", md_entity("rsquo"), "s the method I have used in the places I current implement ", md_code("@font-face"), ":" ]), md_el(:code,[],{:raw_code=>"@font-face {\n font-family: 'Diavlo Book';\n src: url(./Diavlo/Diavlo_Book.otf) format(\"opentype\");\n}\n\n@font-face {\n font-family: 'Diavlo Black';\n src: url(./Diavlo/Diavlo_Black.otf) format(\"opentype\");\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-family: 'Diavlo Black';\n}\n\ndiv#content {\n font-family: 'Diavlo Book';\n}", :lang=>nil},[]), md_par([ "Isn", md_entity("rsquo"), "t it horrible? Seriously, my eyes, they bleed. There", md_entity("rsquo"), "s lots of problems with this far beyond the lack of semanticity when it comes to the typeface names", md_entity("hellip"), " let me see how many ways this breaks the purpose of ", md_code("@font-face"), ":" ]), md_el(:ul,[ md_el(:li,[ md_par([ "You remove a large element our control over the display of the page." ]), md_par([ "As soon as we begin to use ", md_code("@font-face"), " in our page, we can no longer make any use of any other textual control attribute - ", md_code("font-weight:"), ", ", md_code("font-style:"), ", and ", md_code("font-variant:"), " are no longer available to us, because they no longer correctly map to technical typeface variant/features." ]), md_par([ "Also, many default elements are destroyed, unusable, without ", md_entity("lsquo"), "fixing", md_entity("rsquo"), " - for instance, ", md_code(""), " would have no effect in a page styled for WebKit as above; We would have to specify something like ", md_code("b {font-family: 'Diavlo Black';}"), " - how broken is that? Unless we caught all such default elements and re-styled them to use the bastardized names instead of the correct attributes, lots of basic HTML formatting would be broken. I myself may never use in-document formatting (separation of design and content!), but what about comments forms? Forum posts? Direct HTML-literal quotes?" ]), md_par([ "If we want to use Javascript to modify the display of the content, we can", md_entity("rsquo"), "t simply adjust the mentioned textual control attributes - we have to know and change the entire ", md_code("font-family:"), " array of strings." ]) ],{:want_my_paragraph=>true},[]), md_el(:li,[ md_par(["You make us very wet."]), md_par([ "And by wet, I mean ", md_entity("lsquo"), "not ", md_el(:abbr,["DRY"],{:title=>"Don't Repeat Yourself"},[]), md_entity("rsquo"), ". What if we decide to change one of the bastardized font names? Or use a different font entirely? We have to go through all of our ", md_el(:abbr,["CSS"],{:title=>"Cascading Style Sheets"},[]), ", all of our Javascript, and make sure we update every occurrence of the typeface", md_entity("rsquo"), "s bastardized name." ]) ],{:want_my_paragraph=>true},[]), md_el(:li,[ md_par([ "You remove our user", md_entity("rsquo"), "s user choice, and waste bandwidth." ]), md_par([ "Since the names refer to families that don", md_entity("rsquo"), "t, in fact, exist, the browser can", md_entity("rsquo"), "t override the declaration with a user", md_entity("rsquo"), "s installed version of the typeface. This means that, regardless of whether the user already has the typeface installed on their own computer, the browser won", md_entity("rsquo"), "t use that - it doesn", md_entity("rsquo"), "t know to use ", md_entity("lsquo"), "Diavlo", md_entity("rsquo"), ", which the user has installed, because it was told to use ", md_entity("lsquo"), "Diavlo Black", md_entity("rsquo"), ", which no user in the entire world has installed on their computer." ]) ],{:want_my_paragraph=>false},[]) ],{},[]), md_par([ "This whole thing is rather worrying - I", md_entity("rsquo"), "ve heard Opera has ", md_code("@font-face"), " support, though I haven", md_entity("rsquo"), "t had time to test this myself, so I don", md_entity("rsquo"), "t know if it actually does - or, for that matter, if it does it ", md_entity("lsquo"), "correctly", md_entity("rsquo"), ", or has the same problems as WebKit. But either way, WebKit is one of the first two implementations to ever attempt to support ", md_code("@font-face"), " (Microsoft", md_entity("rsquo"), "s unrelated ", md_code("@font-face"), " declaration notwithstanding) - I really don", md_entity("rsquo"), "t want to see it", md_entity("rsquo"), "s early mistakes carried on to FireFox in a few years, and then Internet Explorer a few decades after that. That will leave us stuck with this broken system forever, as it has been demonstrated time and time again that if nobody else supports an old standard correctly, a newcomer to the standard will not do it correctly either. I for one would really, really, hate that." ]), md_par([ "In summary", md_entity("hellip"), " come on, WebKit team, this isn", md_entity("rsquo"), "t like you - you", md_entity("rsquo"), "re always the ones with the closest-to-standard implementation, and the cleanest code, and", md_entity("hellip"), " hell, overall? Webkit is the most secure/fastest browser available. But this is making me lose my faith in you, guys, please get it right. You", md_entity("rsquo"), "re pioneering a leap into the future when it comes to the Web - this is as important, or ", md_em(["more"]), " important, than Mosiac", md_entity("rsquo"), "s allowing of images was." ]), md_par([ "To put it succinctly - don", md_entity("rsquo"), "t fuck this up, y", md_entity("rsquo"), "all." ]), md_ref_def("museo", "http://www.josbuivenga.demon.nl/museo.html", {:title=>"Jos Buivenga's Museo free typeface"}), md_ref_def("diavlo", "http://www.josbuivenga.demon.nl/diavlo.html", {:title=>"Jos Buivenga's free Diavlo typeface"}), md_el(:footnote,[ md_par([ "These are fonts by ", md_link(["Jos Buivenga"], "jos"), ", quite the amazing person. His (free) fonts are, uniquely, released for use on the web in ", md_code("@font-face"), " declarations - unlike the vast majority of other (even free to download) typefaces, which have ridiculously restricting licenses and terms of use statements. Props, Jos - you", md_entity("rsquo"), "re a pioneer, and deserve recognition as such." ]) ],{:footnote_id=>"^jos"},[]), md_el(:abbr_def,[],{:abbr=>"CSS",:text=>"Cascading Style Sheets"},[]), md_el(:abbr_def,[],{:abbr=>".EOT",:text=>"Embedded OpenType"},[]), md_el(:footnote,[ md_par([ "To give Microsoft a little credit, something I rarely do", md_entity("hellip"), " Yes, I", md_entity("rsquo"), "m aware Microsoft submitted EOT to the ", md_el(:abbr,["W3C"],{:title=>"World Wide Web Consortium"},[]), " as a proposal - the problem isn", md_entity("rsquo"), "t with their attempts to make it non-proprietary, but with the basic concept of making typefaces on the web DRMed. Look what such attempts have done to the music and video industry - simply decimated it. Do we really want to see the same thing happen to our beloved medium as typography moves into the 21st century?" ]) ],{:footnote_id=>"^eot"},[]), md_el(:abbr_def,[],{:abbr=>"W3C",:text=>"World Wide Web Consortium"},[]), md_ref_def("w3c", "http://w3c.org", {:title=>"World Wide Web Consortium"}), md_ref_def("spec", "http://?", {:title=>nil}), md_el(:abbr_def,[],{:abbr=>"DRY",:text=>"Don't Repeat Yourself"},[]), md_ref_def("jos", "jos", {:title=>nil}) ],{},[]) *** Output of to_html ***

WebKit (Safari 3.1) and the CSS @font-face declaration

I’m a big fan of typography in general. If you check out my homepage or my contact elliottcable page, and you’re using Safari/WebKit or Opera/Kestrel, you’ll notice the typefaces (fonts, as colloquialized) are very non-standard. (As of this writing, I’m using Museo and Diavlo1 heavily on both.)

The internet has not be a friendly place for typohiles like myself, up to this point, at least. One might even say it was a frightful, mentally scarring environment for those akin to yours truly. We’ve been restricted to reading page after page after page on day after day after day for year after year after year abominations of markup and design enslaved by the horrible overlords we know as Lucida, Verdana, Arial, Helvetica, Geneva, Georgia, Courier, and… dare I invoke ye, thou my terrible overlord? Times New Roman.

Wherefore art thou, my glorious Archer? And thee as well, my beautiful Garamond? The technical restrictions of that horrible monster we know as the Web Browser hath forced us all too long to use those most banal, those most common, and those most abused, out of all of the typefaces of the world.

All hyperbole aside, I’m extremely happy to see the advent of a standard @font-face declaration in CSS. Internet Explorer first implemented a crutched, basic version of this way back in version 4, but nothing ever really came of it - their decision to create the proprietary .EOT2 format to appease overly restrictive type foundries’ worries about intellectual property (aka. the cold, hard dominatrix that we know only as Ms. Profit) truly and completely killed that initial attempt at bringing astute typography and it’s advocates to the web. This new run at @font-face by an established, trusted, and open group (the W3C itself, responsible for helping to make much of what we use as designers on the web standard and cross-system compatible) has a much better chance, in my humble opinion - and I am quite looking forward to the consequences if it succeeds.

Now, onwards to the topic of my post as declared in the header (yes, I know, a slow start - but it’s an interesting topic with an interesting history!). WebKit, the open source rendering engine behind the wonderfulness that is Safari, and how it handles the ‘new’ @font-face declaration. No, it’s not really ‘new’, but yes, it feels like it is.

To put it simply, and to be very blunt, it’s broken.

The CSS spec section for @font-face is very specific - typefaces are to be selected based on a wide array of criteria placed in the @font-face declaration block itself. Various textual CSS attributes may be defined within the @font-face declaration, and then they will be checked when the typeface is referred to later in the CSS. For instance, if I have two @font-face declarations for the Diavlo family - one for regular text, and one for a heavier weighted version of the typeface - then I later utilize Diavlo in a font-family: attribute, it should refer to the basic Diavlo font defined in the first @font-face. However, if I were to do the same, but also specify a heavy font-weight:, then it should use the heavier version of Diavlo. To place this example in code:

@font-face {
  font-family: 'Diavlo';
  src: url(./Diavlo/Diavlo_Book.otf) format("opentype");
}

@font-face {
  font-family: 'Diavlo';
  font-weight: 900;
  src: url(./Diavlo/Diavlo_Black.otf) format("opentype");
}

h1, h2, h3, h4, h5, h6 {
  font-family: 'Diavlo';
  font-weight: 900;
}

div#content {
  font-family: 'Diavlo';
}

As you can see, my headings should use the typeface defined in Diavlo_Black.otf, while my body content should use Diavlo_Book.otf. However, in WebKit, this doesn’t work - it completely ignores any attribute except font-family: and src: in a @font-face declaration! Completely ignores them! Not only that - not only that - it disregards all but the last @font-face for a given font-family: attribute string!

The implication here is that, to make @font-face work as it is currently implemented in WebKit (and thus, Safari 3.1), I have to declare completely imaginary, non-existent type families to satisfy WebKit alone. Here’s the method I have used in the places I current implement @font-face:

@font-face {
  font-family: 'Diavlo Book';
  src: url(./Diavlo/Diavlo_Book.otf) format("opentype");
}

@font-face {
  font-family: 'Diavlo Black';
  src: url(./Diavlo/Diavlo_Black.otf) format("opentype");
}

h1, h2, h3, h4, h5, h6 {
  font-family: 'Diavlo Black';
}

div#content {
  font-family: 'Diavlo Book';
}

Isn’t it horrible? Seriously, my eyes, they bleed. There’s lots of problems with this far beyond the lack of semanticity when it comes to the typeface names… let me see how many ways this breaks the purpose of @font-face:

  • You remove a large element our control over the display of the page.

    As soon as we begin to use @font-face in our page, we can no longer make any use of any other textual control attribute - font-weight:, font-style:, and font-variant: are no longer available to us, because they no longer correctly map to technical typeface variant/features.

    Also, many default elements are destroyed, unusable, without ‘fixing’ - for instance, <b> would have no effect in a page styled for WebKit as above; We would have to specify something like b {font-family: 'Diavlo Black';} - how broken is that? Unless we caught all such default elements and re-styled them to use the bastardized names instead of the correct attributes, lots of basic HTML formatting would be broken. I myself may never use in-document formatting (separation of design and content!), but what about comments forms? Forum posts? Direct HTML-literal quotes?

    If we want to use Javascript to modify the display of the content, we can’t simply adjust the mentioned textual control attributes - we have to know and change the entire font-family: array of strings.

  • You make us very wet.

    And by wet, I mean ‘not DRY’. What if we decide to change one of the bastardized font names? Or use a different font entirely? We have to go through all of our CSS, all of our Javascript, and make sure we update every occurrence of the typeface’s bastardized name.

  • You remove our user’s user choice, and waste bandwidth.

    Since the names refer to families that don’t, in fact, exist, the browser can’t override the declaration with a user’s installed version of the typeface. This means that, regardless of whether the user already has the typeface installed on their own computer, the browser won’t use that - it doesn’t know to use ‘Diavlo’, which the user has installed, because it was told to use ‘Diavlo Black’, which no user in the entire world has installed on their computer.

This whole thing is rather worrying - I’ve heard Opera has @font-face support, though I haven’t had time to test this myself, so I don’t know if it actually does - or, for that matter, if it does it ‘correctly’, or has the same problems as WebKit. But either way, WebKit is one of the first two implementations to ever attempt to support @font-face (Microsoft’s unrelated @font-face declaration notwithstanding) - I really don’t want to see it’s early mistakes carried on to FireFox in a few years, and then Internet Explorer a few decades after that. That will leave us stuck with this broken system forever, as it has been demonstrated time and time again that if nobody else supports an old standard correctly, a newcomer to the standard will not do it correctly either. I for one would really, really, hate that.

In summary… come on, WebKit team, this isn’t like you - you’re always the ones with the closest-to-standard implementation, and the cleanest code, and… hell, overall? Webkit is the most secure/fastest browser available. But this is making me lose my faith in you, guys, please get it right. You’re pioneering a leap into the future when it comes to the Web - this is as important, or more important, than Mosiac’s allowing of images was.

To put it succinctly - don’t fuck this up, y’all.


  1. These are fonts by Jos Buivenga, quite the amazing person. His (free) fonts are, uniquely, released for use on the web in @font-face declarations - unlike the vast majority of other (even free to download) typefaces, which have ridiculously restricting licenses and terms of use statements. Props, Jos - you’re a pioneer, and deserve recognition as such.

  2. To give Microsoft a little credit, something I rarely do… Yes, I’m aware Microsoft submitted EOT to the W3C as a proposal - the problem isn’t with their attempts to make it non-proprietary, but with the basic concept of making typefaces on the web DRMed. Look what such attempts have done to the music and video industry - simply decimated it. Do we really want to see the same thing happen to our beloved medium as typography moves into the 21st century?

*** Output of to_latex *** \hypertarget{webkit_safari_31_and_the_css_fontface_declaration}{}\section*{{WebKit (Safari 3.1) and the CSS @font-face declaration}}\label{webkit_safari_31_and_the_css_fontface_declaration} I'm a big fan of typography in general. If you check out \href{http://elliottcable.name}{my homepage} or my \href{http://elliottcable.name/contact.xhtml}{contact elliottcable} page, and you're using Safari/WebKit or Opera/Kestrel, you'll notice the typefaces (fonts, as colloquialized) are \emph{very} non-standard. (As of this writing, I'm using \href{http://www.josbuivenga.demon.nl/museo.html}{Museo} and \href{http://www.josbuivenga.demon.nl/diavlo.html}{Diavlo}\footnote{These are fonts by \href{jos}{Jos Buivenga}, quite the amazing person. His (free) fonts are, uniquely, released for use on the web in {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declarations - unlike the vast majority of other (even free to download) typefaces, which have ridiculously restricting licenses and terms of use statements. Props, Jos - you're a pioneer, and deserve recognition as such.} heavily on both.) The internet has not be a friendly place for typohiles like myself, up to this point, at least. One might even say it was a frightful, mentally scarring environment for those akin to yours truly. We've been restricted to reading page after page after page on day after day after day for year after year after year abominations of markup and design enslaved by the horrible overlords we know as Lucida, Verdana, Arial, Helvetica, Geneva, Georgia, Courier, and\ldots{} dare I invoke ye, thou my terrible overlord? Times New Roman. Wherefore art thou, my glorious Archer? And thee as well, my beautiful Garamond? The technical restrictions of that horrible monster we know as the Web Browser hath forced us all too long to use those most banal, those most common, and those most abused, out of all of the typefaces of the world. All hyperbole aside, I'm extremely happy to see the advent of a standard {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declaration in CSS. Internet Explorer first implemented a crutched, basic version of this way back in version 4, but nothing ever really came of it - their decision to create the proprietary .EOT\footnote{To give Microsoft a little credit, something I rarely do\ldots{} Yes, I'm aware Microsoft submitted EOT to the W3C as a proposal - the problem isn't with their attempts to make it non-proprietary, but with the basic concept of making typefaces on the web DRMed. Look what such attempts have done to the music and video industry - simply decimated it. Do we really want to see the same thing happen to our beloved medium as typography moves into the 21st century?} format to appease overly restrictive type foundries' worries about intellectual property (aka. the cold, hard dominatrix that we know only as Ms. Profit) truly and completely killed that initial attempt at bringing astute typography and it's advocates to the web. This new run at {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} by an established, trusted, and open group (the \href{http://w3c.org}{W3C} itself, responsible for helping to make much of what we use as designers on the web standard and cross-system compatible) has a much better chance, in my humble opinion - and I am quite looking forward to the consequences if it succeeds. Now, onwards to the topic of my post as declared in the header (yes, I know, a slow start - but it's an interesting topic with an interesting history!). WebKit, the open source rendering engine behind the wonderfulness that is Safari, and how it handles the `new' {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declaration. No, it's not really `new', but yes, it feels like it is. To put it simply, and to be very blunt, it's broken. The \href{http://?}{CSS spec section} for {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} is very specific - typefaces are to be selected based on a wide array of criteria placed in the {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declaration block itself. Various textual CSS attributes may be defined within the {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declaration, and then they will be checked when the typeface is referred to later in the CSS. For instance, if I have two {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declarations for the Diavlo family - one for regular text, and one for a heavier weighted version of the typeface - then I later utilize Diavlo in a {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45family\char58}} attribute, it should refer to the basic Diavlo font defined in the first {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}}. However, if I were to do the same, but also specify a heavy {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45weight\char58}}, then it should use the heavier version of Diavlo. To place this example in code: \begin{verbatim}@font-face { font-family: 'Diavlo'; src: url(./Diavlo/Diavlo_Book.otf) format("opentype"); } @font-face { font-family: 'Diavlo'; font-weight: 900; src: url(./Diavlo/Diavlo_Black.otf) format("opentype"); } h1, h2, h3, h4, h5, h6 { font-family: 'Diavlo'; font-weight: 900; } div#content { font-family: 'Diavlo'; }\end{verbatim} As you can see, my headings should use the typeface defined in {\colorbox[rgb]{1.00,0.93,1.00}{\tt Diavlo\char95Black\char46otf}}, while my body content should use {\colorbox[rgb]{1.00,0.93,1.00}{\tt Diavlo\char95Book\char46otf}}. However, in WebKit, this doesn't work - it completely ignores any attribute except {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45family\char58}} and {\colorbox[rgb]{1.00,0.93,1.00}{\tt src\char58}} in a {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declaration! Completely ignores them! Not only that - not \emph{only} that - it disregards all but the last {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} for a given {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45family\char58}} attribute string! The implication here is that, to make {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} work as it is currently implemented in WebKit (and thus, Safari 3.1), I have to declare \emph{completely imaginary, non-existent type families} to satisfy WebKit alone. Here's the method I have used in the places I current implement {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}}: \begin{verbatim}@font-face { font-family: 'Diavlo Book'; src: url(./Diavlo/Diavlo_Book.otf) format("opentype"); } @font-face { font-family: 'Diavlo Black'; src: url(./Diavlo/Diavlo_Black.otf) format("opentype"); } h1, h2, h3, h4, h5, h6 { font-family: 'Diavlo Black'; } div#content { font-family: 'Diavlo Book'; }\end{verbatim} Isn't it horrible? Seriously, my eyes, they bleed. There's lots of problems with this far beyond the lack of semanticity when it comes to the typeface names\ldots{} let me see how many ways this breaks the purpose of {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}}: \begin{itemize}% \item You remove a large element our control over the display of the page. As soon as we begin to use {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} in our page, we can no longer make any use of any other textual control attribute - {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45weight\char58}}, {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45style\char58}}, and {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45variant\char58}} are no longer available to us, because they no longer correctly map to technical typeface variant/features. Also, many default elements are destroyed, unusable, without `fixing' - for instance, {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char60b\char62}} would have no effect in a page styled for WebKit as above; We would have to specify something like {\colorbox[rgb]{1.00,0.93,1.00}{\tt b\char32\char123font\char45family\char58\char32\char39Diavlo\char32Black\char39\char59\char125}} - how broken is that? Unless we caught all such default elements and re-styled them to use the bastardized names instead of the correct attributes, lots of basic HTML formatting would be broken. I myself may never use in-document formatting (separation of design and content!), but what about comments forms? Forum posts? Direct HTML-literal quotes? If we want to use Javascript to modify the display of the content, we can't simply adjust the mentioned textual control attributes - we have to know and change the entire {\colorbox[rgb]{1.00,0.93,1.00}{\tt font\char45family\char58}} array of strings. \item You make us very wet. And by wet, I mean `not DRY'. What if we decide to change one of the bastardized font names? Or use a different font entirely? We have to go through all of our CSS, all of our Javascript, and make sure we update every occurrence of the typeface's bastardized name. \item You remove our user's user choice, and waste bandwidth. Since the names refer to families that don't, in fact, exist, the browser can't override the declaration with a user's installed version of the typeface. This means that, regardless of whether the user already has the typeface installed on their own computer, the browser won't use that - it doesn't know to use `Diavlo', which the user has installed, because it was told to use `Diavlo Black', which no user in the entire world has installed on their computer. \end{itemize} This whole thing is rather worrying - I've heard Opera has {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} support, though I haven't had time to test this myself, so I don't know if it actually does - or, for that matter, if it does it `correctly', or has the same problems as WebKit. But either way, WebKit is one of the first two implementations to ever attempt to support {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} (Microsoft's unrelated {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char64font\char45face}} declaration notwithstanding) - I really don't want to see it's early mistakes carried on to FireFox in a few years, and then Internet Explorer a few decades after that. That will leave us stuck with this broken system forever, as it has been demonstrated time and time again that if nobody else supports an old standard correctly, a newcomer to the standard will not do it correctly either. I for one would really, really, hate that. In summary\ldots{} come on, WebKit team, this isn't like you - you're always the ones with the closest-to-standard implementation, and the cleanest code, and\ldots{} hell, overall? Webkit is the most secure/fastest browser available. But this is making me lose my faith in you, guys, please get it right. You're pioneering a leap into the future when it comes to the Web - this is as important, or \emph{more} important, than Mosiac's allowing of images was. To put it succinctly - don't fuck this up, y'all. *** Output of to_md *** WebKit (Safari 3.1) and the CSS @font-face declarationI m a big fan of typography in general. If you check out my homepageor my contact elliottcablepage, and you re using Safari/WebKit or Opera/Kestrel, you ll notice the typefaces (fonts, as colloquialized) are verynon-standard. (As of this writing, I m using Museoand Diavloheavily on both.) The internet has not be a friendly place for typohiles like myself, up to this point, at least. One might even say it was a frightful, mentally scarring environment for those akin to yours truly. We ve been restricted to reading page after page after page on day after day after day for year after year after year abominations of markup and design enslaved by the horrible overlords we know as Lucida, Verdana, Arial, Helvetica, Geneva, Georgia, Courier, and dare I invoke ye, thou my terrible overlord? Times New Roman. Wherefore art thou, my glorious Archer? And thee as well, my beautiful Garamond? The technical restrictions of that horrible monster we know as the Web Browser hath forced us all too long to use those most banal, those most common, and those most abused, out of all of the typefaces of the world. All hyperbole aside, I m extremely happy to see the advent of a standard declaration in CSS. Internet Explorer first implemented a crutched, basic version of this way back in version 4, but nothing ever really came of it - their decision to create the proprietary .EOT format to appease overly restrictive type foundries worries about intellectual property (aka. the cold, hard dominatrix that we know only as Ms. Profit) truly and completely killed that initial attempt at bringing astute typography and it s advocates to the web. This new run at by an established, trusted, and open group (the W3Citself, responsible for helping to make much of what we use as designers on the web standard and cross-system compatible) has a much better chance, in my humble opinion - and I am quite looking forward to the consequences if it succeeds. Now, onwards to the topic of my post as declared in the header (yes, I know, a slow start - but it s an interesting topic with an interesting history!). WebKit, the open source rendering engine behind the wonderfulness that is Safari, and how it handles the new declaration. No, it s not really new , but yes, it feels like it is. To put it simply, and to be very blunt, it s broken. The CSS spec sectionfor is very specific - typefaces are to be selected based on a wide array of criteria placed in the declaration block itself. Various textual CSS attributes may be defined within the declaration, and then they will be checked when the typeface is referred to later in the CSS. For instance, if I have two declarations for the Diavlo family - one for regular text, and one for a heavier weighted version of the typeface - then I later utilize Diavlo in a attribute, it should refer to the basic Diavlo font defined in the first . However, if I were to do the same, but also specify a heavy , then it should use the heavier version of Diavlo. To place this example in code: As you can see, my headings should use the typeface defined in , while my body content should use . However, in WebKit, this doesn t work - it completely ignores any attribute except and in a declaration! Completely ignores them! Not only that - not only that - it disregards all but the last for a given attribute string! The implication here is that, to make work as it is currently implemented in WebKit (and thus, Safari 3.1), I have to declare completely imaginary, non-existent type families to satisfy WebKit alone. Here s the method I have used in the places I current implement : Isn t it horrible? Seriously, my eyes, they bleed. There s lots of problems with this far beyond the lack of semanticity when it comes to the typeface names let me see how many ways this breaks the purpose of : -You remove a large element our control over the display of the page. As soon as we begin to use in our page, we can no longer make any use of any other textual control attribute - , , and are no longer available to us, because they no longer correctly map to technical typeface variant/features. Also, many default elements are destroyed, unusable, without fixing - for instance, would have no effect in a page styled for WebKit as above; We would have to specify something like - how broken is that? Unless we caught all such default elements and re-styled them to use the bastardized names instead of the correct attributes, lots of basic HTML formatting would be broken. I myself may never use in-document formatting (separation of design and content!), but what about comments forms? Forum posts? Direct HTML-literal quotes? If we want to use Javascript to modify the display of the content, we cant simply adjust the mentioned textual control attributes - we have to know and change the entire array of strings. -ou make us very wet. And by wet, I mean not DRY. What if we decide to change one of the bastardized font names? Or use a different font entirely? We have to go through all of our CSS, all of our Javascript, and make sure we update every occurrence of the typefaces bastardized name. -You remove our users user choice, and waste bandwidth. Since the names refer to families that dont, in fact, exist, the browser cant override the declaration with a users installed version of the typeface. This means that, regardless of whether the user already has the typeface installed on their own computer, the browser wont use that - it doesnt know to use Diavlo, which the user has installed, because it was told to use Diavlo Black, which no user in the entire world has installed on their computer. This whole thing is rather worrying - I ve heard Opera has support, though I haven t had time to test this myself, so I don t know if it actually does - or, for that matter, if it does it correctly , or has the same problems as WebKit. But either way, WebKit is one of the first two implementations to ever attempt to support (Microsoft s unrelated declaration notwithstanding) - I really don t want to see it s early mistakes carried on to FireFox in a few years, and then Internet Explorer a few decades after that. That will leave us stuck with this broken system forever, as it has been demonstrated time and time again that if nobody else supports an old standard correctly, a newcomer to the standard will not do it correctly either. I for one would really, really, hate that. In summary come on, WebKit team, this isn t like you - you re always the ones with the closest-to-standard implementation, and the cleanest code, and hell, overall? Webkit is the most secure/fastest browser available. But this is making me lose my faith in you, guys, please get it right. You re pioneering a leap into the future when it comes to the Web - this is as important, or moreimportant, than Mosiac s allowing of images was. To put it succinctly - don t fuck this up, y all. CSS: Cascading Style Sheets.EOT: Embedded OpenType : To give Microsoft a little credit, something I rarely do Yes, I m aware Microsoft submitted EOT to the W3C as a proposal - the problem isn t with their attempts to make it non-proprietary, but with the basic concept of making typefaces on the web DRMed. Look what such attempts have done to the music and video industry - simply decimated it. Do we really want to see the same thing happen to our beloved medium as typography moves into the 21st century? W3C: World Wide Web Consortium *** Output of to_s *** WebKit (Safari 3.1) and the CSS @font-face declarationIm a big fan of typography in general. If you check out my homepage or my contact elliottcable page, and youre using Safari/WebKit or Opera/Kestrel, youll notice the typefaces (fonts, as colloquialized) are very non-standard. (As of this writing, Im using Museo and Diavlo heavily on both.)The internet has not be a friendly place for typohiles like myself, up to this point, at least. One might even say it was a frightful, mentally scarring environment for those akin to yours truly. Weve been restricted to reading page after page after page on day after day after day for year after year after year abominations of markup and design enslaved by the horrible overlords we know as Lucida, Verdana, Arial, Helvetica, Geneva, Georgia, Courier, and dare I invoke ye, thou my terrible overlord? Times New Roman.Wherefore art thou, my glorious Archer? And thee as well, my beautiful Garamond? The technical restrictions of that horrible monster we know as the Web Browser hath forced us all too long to use those most banal, those most common, and those most abused, out of all of the typefaces of the world.All hyperbole aside, Im extremely happy to see the advent of a standard declaration in CSS. Internet Explorer first implemented a crutched, basic version of this way back in version 4, but nothing ever really came of it - their decision to create the proprietary .EOT format to appease overly restrictive type foundries worries about intellectual property (aka. the cold, hard dominatrix that we know only as Ms. Profit) truly and completely killed that initial attempt at bringing astute typography and its advocates to the web. This new run at by an established, trusted, and open group (the W3C itself, responsible for helping to make much of what we use as designers on the web standard and cross-system compatible) has a much better chance, in my humble opinion - and I am quite looking forward to the consequences if it succeeds.Now, onwards to the topic of my post as declared in the header (yes, I know, a slow start - but its an interesting topic with an interesting history!). WebKit, the open source rendering engine behind the wonderfulness that is Safari, and how it handles the new declaration. No, its not really new, but yes, it feels like it is.To put it simply, and to be very blunt, its broken.The CSS spec section for is very specific - typefaces are to be selected based on a wide array of criteria placed in the declaration block itself. Various textual CSS attributes may be defined within the declaration, and then they will be checked when the typeface is referred to later in the CSS. For instance, if I have two declarations for the Diavlo family - one for regular text, and one for a heavier weighted version of the typeface - then I later utilize Diavlo in a attribute, it should refer to the basic Diavlo font defined in the first . However, if I were to do the same, but also specify a heavy , then it should use the heavier version of Diavlo. To place this example in code:As you can see, my headings should use the typeface defined in , while my body content should use . However, in WebKit, this doesnt work - it completely ignores any attribute except and in a declaration! Completely ignores them! Not only that - not only that - it disregards all but the last for a given attribute string!The implication here is that, to make work as it is currently implemented in WebKit (and thus, Safari 3.1), I have to declare completely imaginary, non-existent type families to satisfy WebKit alone. Heres the method I have used in the places I current implement :Isnt it horrible? Seriously, my eyes, they bleed. Theres lots of problems with this far beyond the lack of semanticity when it comes to the typeface names let me see how many ways this breaks the purpose of :You remove a large element our control over the display of the page.As soon as we begin to use in our page, we can no longer make any use of any other textual control attribute - , , and are no longer available to us, because they no longer correctly map to technical typeface variant/features.Also, many default elements are destroyed, unusable, without fixing - for instance, would have no effect in a page styled for WebKit as above; We would have to specify something like - how broken is that? Unless we caught all such default elements and re-styled them to use the bastardized names instead of the correct attributes, lots of basic HTML formatting would be broken. I myself may never use in-document formatting (separation of design and content!), but what about comments forms? Forum posts? Direct HTML-literal quotes?If we want to use Javascript to modify the display of the content, we cant simply adjust the mentioned textual control attributes - we have to know and change the entire array of strings.You make us very wet.And by wet, I mean not DRY. What if we decide to change one of the bastardized font names? Or use a different font entirely? We have to go through all of our CSS, all of our Javascript, and make sure we update every occurrence of the typefaces bastardized name.You remove our users user choice, and waste bandwidth.Since the names refer to families that dont, in fact, exist, the browser cant override the declaration with a users installed version of the typeface. This means that, regardless of whether the user already has the typeface installed on their own computer, the browser wont use that - it doesnt know to use Diavlo, which the user has installed, because it was told to use Diavlo Black, which no user in the entire world has installed on their computer.This whole thing is rather worrying - Ive heard Opera has support, though I havent had time to test this myself, so I dont know if it actually does - or, for that matter, if it does it correctly, or has the same problems as WebKit. But either way, WebKit is one of the first two implementations to ever attempt to support (Microsofts unrelated declaration notwithstanding) - I really dont want to see its early mistakes carried on to FireFox in a few years, and then Internet Explorer a few decades after that. That will leave us stuck with this broken system forever, as it has been demonstrated time and time again that if nobody else supports an old standard correctly, a newcomer to the standard will not do it correctly either. I for one would really, really, hate that.In summary come on, WebKit team, this isnt like you - youre always the ones with the closest-to-standard implementation, and the cleanest code, and hell, overall? Webkit is the most secure/fastest browser available. But this is making me lose my faith in you, guys, please get it right. Youre pioneering a leap into the future when it comes to the Web - this is as important, or more important, than Mosiacs allowing of images was.To put it succinctly - dont fuck this up, yall.CSS: Cascading Style Sheets.EOT: Embedded OpenType : To give Microsoft a little credit, something I rarely do Yes, Im aware Microsoft submitted EOT to the W3C as a proposal - the problem isnt with their attempts to make it non-proprietary, but with the basic concept of making typefaces on the web DRMed. Look what such attempts have done to the music and video industry - simply decimated it. Do we really want to see the same thing happen to our beloved medium as typography moves into the 21st century? W3C: World Wide Web Consortium maruku-0.7.2/spec/block_docs/hrule.md0000644000004100000410000000124012347070213017545 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** * * * *** ***** - - - --------------------------------------- *** Output of inspect *** md_el(:document,[ md_el(:hrule,[],{},[]), md_el(:hrule,[],{},[]), md_el(:hrule,[],{},[]), md_el(:hrule,[],{},[]), md_el(:hrule,[],{},[]) ],{},[]) *** Output of to_html ***




*** Output of to_latex *** \vspace{.5em} \hrule \vspace{.5em} \vspace{.5em} \hrule \vspace{.5em} \vspace{.5em} \hrule \vspace{.5em} \vspace{.5em} \hrule \vspace{.5em} \vspace{.5em} \hrule \vspace{.5em} *** Output of to_md *** * * * * * * * * * * * * * * * *** Output of to_s *** maruku-0.7.2/spec/block_docs/paragraph.md0000644000004100000410000000047412347070213020403 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** Paragraph *** Output of inspect *** md_el(:document,[md_par(["Paragraph"])],{},[]) *** Output of to_html ***

Paragraph

*** Output of to_latex *** Paragraph *** Output of to_md *** Paragraph *** Output of to_s *** Paragraph maruku-0.7.2/spec/block_docs/code.md0000644000004100000410000000146112347070213017345 0ustar www-datawww-dataComment *** Parameters: *** {} *** Markdown input: *** Here is an example of AppleScript: tell application "Foo" beep end tell tab *** Output of inspect *** md_el(:document,[ md_par(["Here is an example of AppleScript:"]), md_el(:code,[],{:raw_code=>"tell application \"Foo\"\n beep\nend tell\n\ttab", :lang=>nil},[]) ],{},[]) *** Output of to_html ***

Here is an example of AppleScript:

tell application "Foo"
    beep
end tell
	tab
*** Output of to_latex *** Here is an example of AppleScript: \begin{verbatim}tell application "Foo" beep end tell tab\end{verbatim} *** Output of to_md *** Here is an example of AppleScript: tell application "Foo" beep end tell tab *** Output of to_s *** Here is an example of AppleScript: maruku-0.7.2/spec/block_docs/list_multipara.md0000644000004100000410000000150712347070213021465 0ustar www-datawww-dataLists with multiple paragraphs *** Parameters: *** {} *** Markdown input: *** * A list item with a couple paragraphs, each of which is indented. For example, this paragraph. * Another list item *** Output of inspect *** md_el(:document, md_el(:ul, [ md_li([ md_par("A list item with a couple paragraphs, each of which is indented."), md_par("For example, this paragraph.") ], true), md_li(md_par("Another list item"), false) ])) *** Output of to_html ***
  • A list item with a couple paragraphs, each of which is indented.

    For example, this paragraph.

  • Another list item

*** Output of to_latex *** \begin{itemize}% \item A list item with a couple paragraphs, each of which is indented. For example, this paragraph. \item Another list item \end{itemize} maruku-0.7.2/spec/block_docs/html3.md0000644000004100000410000000261712347070213017466 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** taking part in some arcane conspirations which involve coffee, robots, sushi, *** Output of inspect *** md_el(:document,[ md_par([ "taking part in ", md_html("some arcane conspirations"), " which involve ", md_html("coffee"), ", ", md_html("robots"), ", ", md_html("sushi"), "," ]) ],{},[]) *** Output of to_html ***

taking part in some arcane conspirations which involve coffee, robots, sushi,

*** Output of to_latex *** taking part in which involve , , , *** Output of to_md *** taking part in which involve , , , *** Output of to_s *** taking part in which involve , , , maruku-0.7.2/spec/block_docs/loss.md0000644000004100000410000000062312347070213017412 0ustar www-datawww-datamaruku treats all HTML as a block level element, but it should treat inline elements as part of a paragraph, even if they start the line. *** Parameters: *** {} # params *** Markdown input: ***
123 *** Output of inspect *** md_el(:document, md_par([md_html("
"), "123"])) *** Output of to_html ***


123

*** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/lists7b.md0000644000004100000410000000147612347070213020030 0ustar www-datawww-dataTest case given by Scott. http://rubyforge.org/tracker/index.php?func=detail&aid=8862&group_id=2795&atid=10735 a should not be indented. *** Parameters: *** {} # params *** Markdown input: *** * a * a1 * a2 * b *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[ "a", md_el(:ul,[ md_el(:li,["a1"],{:want_my_paragraph=>false},[]), md_el(:li,["a2"],{:want_my_paragraph=>false},[]) ],{},[]) ],{:want_my_paragraph=>false},[]), md_el(:li,["b"],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***
  • a
    • a1
    • a2
  • b
*** Output of to_latex *** \begin{itemize}% \item a\begin{itemize}% \item a1 \item a2 \end{itemize} \item b \end{itemize} *** Output of to_md *** -* a1 * a2 - *** Output of to_s *** aa1a2b maruku-0.7.2/spec/block_docs/issue70.md0000644000004100000410000000045612347070213017735 0ustar www-datawww-dataLines should be able to start with @. Note that a leading space doesn't trigger the old metadata syntax. https://github.com/bhollis/maruku/issues/70 *** Parameters: *** {} *** Markdown input: *** @ foo *** Output of inspect *** md_el(:document, md_par("@ foo")) *** Output of to_html ***

@ foo

maruku-0.7.2/spec/block_docs/issue89.md0000644000004100000410000000113412347070213017741 0ustar www-datawww-datahttps://github.com/bhollis/maruku/issues/89 - Markdown extra .class ALD parsing error *** Parameters: *** {} *** Markdown input: *** [![Alt text](/Understanding-Big-Data-Cover-201x300.jpg){.alignright}](http://testsite.com/big-data) *** Output of inspect *** md_el(:document, md_par(md_im_link(md_im_image("Alt text", "/Understanding-Big-Data-Cover-201x300.jpg", nil, [[:class, "alignright"]]), "http://testsite.com/big-data", nil))) *** Output of to_html ***

Alt text

maruku-0.7.2/spec/block_docs/ref_with_title.md0000644000004100000410000000066312347070213021446 0ustar www-datawww-dataComment *** Parameters: *** {} *** Markdown input: *** [bar][1]. [1]: /url/ "Title" *** Output of inspect *** md_el(:document,[ md_par([md_link(["bar"],"1"), "."]), md_ref_def("1", "/url/", {:title=>"Title"}) ],{},[]) *** Output of to_html ***

bar.

*** Output of to_latex *** \href{/url/}{bar}. *** Output of to_md *** [bar][1]. [1]: /url/ "Title" *** Output of to_s *** bar. maruku-0.7.2/spec/block_docs/abbreviations.md0000644000004100000410000000345412347070213021267 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** The HTML specification is maintained by the W3C. The W3C is headquartered in Geneva. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium Operation Tigra Genesis is going well. *[Tigra Genesis]: *** Output of inspect *** md_el(:document,[ md_par([ "The ", md_el(:abbr,["HTML"],{:title=>"Hyper Text Markup Language"},[]), " specification is maintained by the ", md_el(:abbr,["W3C"],{:title=>"World Wide Web Consortium"},[]), ". The ", md_el(:abbr,["W3C"],{:title=>"World Wide Web Consortium"},[]), " is headquartered in Geneva." ]), md_el(:abbr_def,[],{:abbr=>"HTML",:text=>"Hyper Text Markup Language"},[]), md_el(:abbr_def,[],{:abbr=>"W3C",:text=>"World Wide Web Consortium"},[]), md_par([ "Operation ", md_el(:abbr,["Tigra Genesis"],{:title=>nil},[]), " is going well." ]), md_el(:abbr_def,[],{:abbr=>"Tigra Genesis",:text=>nil},[]) ],{},[]) *** Output of to_html ***

The HTML specification is maintained by the W3C. The W3C is headquartered in Geneva.

Operation Tigra Genesis is going well.

*** Output of to_latex *** The HTML specification is maintained by the W3C. The W3C is headquartered in Geneva. Operation Tigra Genesis is going well. *** Output of to_md *** The HTML specification is maintained by the W3C. The W3C is headquartered in Geneva. *[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium Operation Tigra Genesis is going well. *[Tigra Genesis]: *** Output of to_s *** The HTML specification is maintained by the W3C. The W3C is headquartered in Geneva.Operation Tigra Genesis is going well. maruku-0.7.2/spec/block_docs/link.md0000644000004100000410000000424512347070213017373 0ustar www-datawww-data *** Parameters: *** {} # params *** Markdown input: *** *** Output of inspect *** md_el(:document,[ md_par([md_url("http://www.aa.com")]), md_par([md_url("http://www.bb.com")]), md_par([md_url("http://www.cc.com")]), md_par([md_url("http://www.dd.com")]), md_el(:code,[],{:raw_code=>"", :lang=>nil},[]), md_par([md_email("a@invalid.it")]), md_par([md_email("a@invalid.it")]), md_par([md_email("a@invalid.it")]), md_el(:code,[],{:raw_code=>"", :lang=>nil},[]) ],{},[]) *** Output of to_html ***

http://www.aa.com

http://www.bb.com

http://www.cc.com

http://www.dd.com

<http://www.dd.com>

a@invalid.it

a@invalid.it

a@invalid.it

<a@invalid.it>
*** Output of to_latex *** \href{http://www.aa.com}{http\char58\char47\char47www\char46aa\char46com} \href{http://www.bb.com}{http\char58\char47\char47www\char46bb\char46com} \href{http://www.cc.com}{http\char58\char47\char47www\char46cc\char46com} \href{http://www.dd.com}{http\char58\char47\char47www\char46dd\char46com} \begin{verbatim}\end{verbatim} \href{mailto:a@invalid.it}{a\char64invalid\char46it} \href{mailto:a@invalid.it}{a\char64invalid\char46it} \href{mailto:a@invalid.it}{a\char64invalid\char46it} \begin{verbatim}\end{verbatim} *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/images2.md0000644000004100000410000000127612347070213017766 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** This is an ![image][]. This is an ![image]. [image]: image.jpg *** Output of inspect *** md_el(:document,[ md_par(["This is an ", md_image(["image"], ""), "."]), md_par(["This is an ", md_image(["image"], "image"), "."]), md_ref_def("image", "image.jpg", {:title=>nil}) ],{},[]) *** Output of to_html ***

This is an image.

This is an image.

*** Output of to_latex *** This is an . This is an . *** Output of to_md *** This is an ![image][]. This is an ![image]. [image]: image.jpg *** Output of to_s *** This is an image.This is an image. maruku-0.7.2/spec/block_docs/auto_cdata.md0000644000004100000410000000161312347070213020536 0ustar www-datawww-dataAdds CDATA only when necessary. NOTE: CDATA is output because we use XHTML - for HTML mode it should be omitted. *** Parameters: *** {} *** Markdown input: *** *** Output of inspect *** *** Output of to_html *** maruku-0.7.2/spec/block_docs/lists_blockquote_code.md0000644000004100000410000000262612347070213023017 0ustar www-datawww-dataLists should be able to contain blockquotes and code. *** Parameters: *** {} *** Markdown input: *** * A list item with a blockquote: > This is a blockquote > inside a list item. * A list item with a code block: *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[ md_par(["A list item with a blockquote:"]), md_el(:quote,[md_par(["This is a blockquote inside a list item."])],{},[]) ],{:want_my_paragraph=>true},[]), md_el(:li,[ md_par(["A list item with a code block:"]), md_el(:code,[],{:raw_code=>"", :lang=>nil},[]) ],{:want_my_paragraph=>true},[]) ],{},[]) ],{},[]) *** Output of to_html ***
  • A list item with a blockquote:

    This is a blockquote inside a list item.

  • A list item with a code block:

    <code goes here>
*** Output of to_latex *** \begin{itemize}% \item A list item with a blockquote: \begin{quote}% This is a blockquote inside a list item. \end{quote} \item A list item with a code block: \begin{verbatim}\end{verbatim} \end{itemize} *** Output of to_md *** - list item with a blockquote: This is a blockquote inside a list item. - list item with a code block: *** Output of to_s *** A list item with a blockquote:This is a blockquote inside a list item.A list item with a code block: maruku-0.7.2/spec/block_docs/headers.md0000644000004100000410000000245112347070213020046 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:title=>"A title with emphasis"} *** Markdown input: *** A title with *emphasis* ======================= A title with *emphasis* ----------------------- #### A title with *emphasis* #### *** Output of inspect *** md_el(:document,[ md_el(:header,["A title with ", md_em(["emphasis"])],{:level=>1},[]), md_el(:header,["A title with ", md_em(["emphasis"])],{:level=>2},[]), md_el(:header,["A title with ", md_em(["emphasis"])],{:level=>4},[]) ],{},[]) *** Output of to_html ***

A title with emphasis

A title with emphasis

A title with emphasis

*** Output of to_latex *** \hypertarget{a_title_with_emphasis}{}\section*{{A title with \emph{emphasis}}}\label{a_title_with_emphasis} \hypertarget{a_title_with_emphasis_2}{}\subsection*{{A title with \emph{emphasis}}}\label{a_title_with_emphasis_2} \hypertarget{a_title_with_emphasis_3}{}\paragraph*{{A title with \emph{emphasis}}}\label{a_title_with_emphasis_3} *** Output of to_md *** # A title with *emphasis* # ## A title with *emphasis* ## #### A title with *emphasis* #### *** Output of to_s *** A title with emphasisA title with emphasisA title with emphasis maruku-0.7.2/spec/block_docs/code3.md0000644000004100000410000000253512347070213017433 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** This is code (4 spaces): Code This is not code Code This is code (1 tab): Code This is not code Code *** Output of inspect *** md_el(:document,[ md_par(["This is code (4 spaces):"]), md_el(:code,[],{:raw_code=>"Code", :lang=>nil},[]), md_par(["This is not code"]), md_el(:code,[],{:raw_code=>"Code", :lang=>nil},[]), md_par(["This is code (1 tab):"]), md_el(:code,[],{:raw_code=>"Code", :lang=>nil},[]), md_par(["This is not code"]), md_el(:code,[],{:raw_code=>"Code", :lang=>nil},[]) ],{},[]) *** Output of to_html ***

This is code (4 spaces):

Code

This is not code

Code

This is code (1 tab):

Code

This is not code

Code
*** Output of to_latex *** This is code (4 spaces): \begin{verbatim}Code\end{verbatim} This is not code \begin{verbatim}Code\end{verbatim} This is code (1 tab): \begin{verbatim}Code\end{verbatim} This is not code \begin{verbatim}Code\end{verbatim} *** Output of to_md *** This is code (4 spaces): Code This is not code Code This is code (1 tab): Code This is not code Code *** Output of to_s *** This is code (4 spaces):This is not codeThis is code (1 tab):This is not code maruku-0.7.2/spec/block_docs/lists_blank.md0000644000004100000410000000075112347070213020741 0ustar www-datawww-dataLists should allow newlines between items. *** Parameters: *** {} *** Markdown input: *** * A list item * Another list item *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_li(md_par("A list item"), true), md_li(md_par("Another list item"), false) ]) ]) *** Output of to_html ***
  • A list item

  • Another list item

*** Output of to_latex *** \begin{itemize}% \item A list item \item Another list item \end{itemize} maruku-0.7.2/spec/block_docs/alt.md0000644000004100000410000000054712347070213017217 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** ![bar](/foo.jpg) *** Output of inspect *** md_el(:document,[md_par([md_im_image(["bar"], "/foo.jpg", nil)])],{},[]) *** Output of to_html ***

bar

*** Output of to_latex *** *** Output of to_md *** ![bar](/foo.jpg) *** Output of to_s *** bar maruku-0.7.2/spec/block_docs/xml_comments.md0000644000004100000410000000125112347070213021135 0ustar www-datawww-dataXML Comments need to be handled properly. Note that output is kind of weird because we modify the comment in order to let REXML parse it due to https://bugs.ruby-lang.org/issues/9277. *** Parameters: *** {} *** Markdown input: *** *** Output of inspect *** md_el(:document,[md_html(""), md_html(""), md_html(""), md_html("")]) *** Output of to_html *** maruku-0.7.2/spec/block_docs/ticks.md0000644000004100000410000000103012347070213017540 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** ``There is a literal backtick (`) here.`` *** Output of inspect *** md_el(:document,[md_par([md_code("There is a literal backtick (`) here.")])],{},[]) *** Output of to_html ***

There is a literal backtick (`) here.

*** Output of to_latex *** {\colorbox[rgb]{1.00,0.93,1.00}{\tt There\char32is\char32a\char32literal\char32backtick\char32\char40\char96\char41\char32here\char46}} *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/header_after_par.md0000644000004100000410000000201712347070213021704 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:title=>"header"} *** Markdown input: *** Paragraph ### header 1 ### Paragraph header 2 -------- Paragraph header 3 ======== *** Output of inspect *** md_el(:document,[ md_par(["Paragraph"]), md_el(:header,["header 1"],{:level=>3},[]), md_par(["Paragraph"]), md_el(:header,["header 2"],{:level=>2},[]), md_par(["Paragraph"]), md_el(:header,["header 3"],{:level=>1},[]) ],{},[]) *** Output of to_html ***

Paragraph

header 1

Paragraph

header 2

Paragraph

header 3

*** Output of to_latex *** Paragraph \hypertarget{header_1}{}\subsubsection*{{header 1}}\label{header_1} Paragraph \hypertarget{header_2}{}\subsection*{{header 2}}\label{header_2} Paragraph \hypertarget{header_3}{}\section*{{header 3}}\label{header_3} *** Output of to_md *** Paragraph ### header Paragraph ## header Paragraph # header *** Output of to_s *** ParagraphheaderParagraphheaderParagraphheader maruku-0.7.2/spec/block_docs/iframe.md0000644000004100000410000000106212347070213017673 0ustar www-datawww-dataEmbed html iframe element *** Parameters: *** {} *** Markdown input: *** Paragraph1 Paragraph2 *** Output of inspect *** md_el(:document,[ md_par(["Paragraph1"]), md_html(''), md_par(["Paragraph2"]) ],{},[]) *** Output of to_html ***

Paragraph1

Paragraph2

*** Output of to_latex *** Paragraph1 Paragraph2 *** Output of to_md *** Paragraph1 Paragraph2 *** Output of to_s *** Paragraph1Paragraph2 maruku-0.7.2/spec/block_docs/wrapping.md0000644000004100000410000000747212347070213020272 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break: Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. * Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break: Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet * Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet *** Output of inspect *** md_el(:document,[ md_par([ "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break:", md_el(:linebreak,[],{},[]), "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet." ]), md_el(:ul,[ md_el(:li,[ "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break:", md_el(:linebreak,[],{},[]), "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet" ],{:want_my_paragraph=>false},[]), md_el(:li,[ "Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet" ],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***

Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break:
Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet.

  • Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break:
    Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet
  • Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet
*** Output of to_latex *** Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break:\newline Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. \begin{itemize}% \item Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break:\newline Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet \item Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet \end{itemize} *** Output of to_md *** Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break: Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. - Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break: Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet - Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet *** Output of to_s *** Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Break:Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet.Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet Lorem ipsum Break:Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor ametLorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet. Lorem ipsum dolor amet maruku-0.7.2/spec/block_docs/ie.md0000644000004100000410000000522012347070213017025 0ustar www-datawww-dataWe must make sure that `'` is always written as `'`. *** Parameters: *** {:html_use_syntax => true} # params *** Markdown input: *** `

here's an apostrophe & a quote "

`

here's an apostrophe & a quote "

{:}

here's an apostrophe & a quote "

{:lang=xml}

here's an apostrophe & a quote "

{:html_use_syntax=true lang=not_supported}

here's an apostrophe & a quote "

{:html_use_syntax=true lang=xml} *** Output of inspect *** md_el(:document,[ md_par([md_code("

here's an apostrophe & a quote \"

")]), md_el(:code,[],{:raw_code=>"

here's an apostrophe & a quote \"

", :lang=>nil},[]), md_el(:code,[],{:raw_code=>"

here's an apostrophe & a quote \"

", :lang=>nil},[["lang", "xml"]]), md_el(:code,[],{:raw_code=>"

here's an apostrophe & a quote \"

", :lang=>nil},[["html_use_syntax", "true"], ["lang", "not_supported"]]), md_el(:code,[],{:raw_code=>"

here's an apostrophe & a quote \"

", :lang=>nil},[["html_use_syntax", "true"], ["lang", "xml"]]) ],{},[]) *** Output of to_html ***

<p>here's an apostrophe & a quote "</p>

<p>here's an apostrophe & a quote "</p>
<p>here's an apostrophe & a quote "</p>
<p>here's an apostrophe & a quote "</p>
<p>here's an apostrophe & a quote "</p>
*** Output of to_latex *** {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char60p\char62here\char39s\char32an\char32apostrophe\char32\char38\char32a\char32quote\char32\char34\char60\char47p\char62}} \begin{verbatim}

here's an apostrophe & a quote "

\end{verbatim} \begin{verbatim}

here's an apostrophe & a quote "

\end{verbatim} \begin{verbatim}

here's an apostrophe & a quote "

\end{verbatim} \begin{verbatim}

here's an apostrophe & a quote "

\end{verbatim} *** Output of to_md *** `

here's an apostrophe & a quote "

`

here's an apostrophe & a quote "

{:}

here's an apostrophe & a quote "

{:lang=xml}

here's an apostrophe & a quote "

{:html_use_syntax=true lang=not_supported}

here's an apostrophe & a quote "

{:html_use_syntax=true lang=xml} *** Output of to_s *** maruku-0.7.2/spec/block_docs/recover/0000755000004100000410000000000012347070213017554 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/recover/recover_links.md0000644000004100000410000000102112347070213022735 0ustar www-datawww-dataMaruku should not mangle references that don't exist. *** Parameters: *** {:on_error=>:warning} *** Markdown input: *** Search on [Google images][ GoOgle search ] *** Output of inspect *** md_el(:document,[md_par(["Search on ", md_link(["Google images"]," \tGoOgle search ")])],{},[]) *** Output of to_html ***

Search on [Google images][ GoOgle search ]

*** Output of to_latex *** Search on Google images *** Output of to_md *** Search on [Google images][ GoOgle search ] *** Output of to_s *** Search on Google images maruku-0.7.2/spec/block_docs/xml.md0000644000004100000410000000240312347070213017230 0ustar www-datawww-dataJRUBY NOKOGIRI PENDING - Write a comment here (JRuby Nokogiri is broken for empty tags: https://github.com/sparklemotion/nokogiri/issues/971) *** Parameters: *** {:on_error=>:raise} *** Markdown input: *** *** Output of inspect *** md_el(:document,[ md_html(""), md_html("\n \n\t\n\t\n \n") ],{},[]) *** Output of to_html *** *** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/inline_html.md0000644000004100000410000000626612347070213020745 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:css=>"style.css"} *** Markdown input: *** CSS: style.css Input: Emphasis Result: Emphasis Input: Result on span: Result alone: Without closing:
This is *true* markdown text (paragraph)

This is *true* markdown text (no paragraph)

This is *true* markdown text (block paragraph)

This is a *true* markdown text. (no par) This is *true* markdown text. (par)
*** Output of inspect *** md_el(:document,[ md_par(["Input:"]), md_el(:code,[],{:raw_code=>"Emphasis", :lang=>nil},[]), md_par(["Result: ", md_html("Emphasis")]), md_par(["Input:"]), md_el(:code,[],{:raw_code=>"", :lang=>nil},[]), md_par([ "Result on span: ", md_html("") ]), md_par(["Result alone:"]), md_par(md_html("")), md_par(["Without closing:"]), md_par(md_html("")), md_html("
\n This is *true* markdown text (paragraph)\n\n

\n This is *true* markdown text (no paragraph)\n

\n

\n This is *true* markdown text (block paragraph)\n

\n
"), md_html("\n\n\n\n\n
This is a *true* markdown text. (no par)This is *true* markdown text. (par)
") ],{},[]) *** Output of to_html ***

Input:

<em>Emphasis</em>

Result: Emphasis

Input:

<img src="http://jigsaw.w3.org/css-validator/images/vcss"/>

Result on span:

Result alone:

Without closing:

This is true markdown text (paragraph)

This is true markdown text (no paragraph)

This is true markdown text (block paragraph)

This is a true markdown text. (no par)

This is true markdown text. (par)

*** Output of to_latex *** Input: \begin{verbatim}Emphasis\end{verbatim} Result: Input: \begin{verbatim}\end{verbatim} Result on span: Result alone: Without closing: *** Output of to_md *** Input: Result: Input: Result on span: Result alone: Without closing: *** Output of to_s *** Input:Result: Input:Result on span: Result alone:Without closing: maruku-0.7.2/spec/block_docs/lists_nested.md0000644000004100000410000000107612347070213021135 0ustar www-datawww-dataNesting lists. *** Parameters: *** {} # params *** Markdown input: *** * A list item * Foo * Bar * Bax * Bap * Another list item *** Output of inspect *** md_el(:document, md_el(:ul, [ md_li([ "A list item", md_el(:ul, [ md_li("Foo", false), md_li([ "Bar", md_el(:ul, [ md_li("Bax", false), md_li("Bap", false) ]) ], false) ]) ], false), md_li("Another list item", false) ])) *** Output of to_html ***
  • A list item
    • Foo
    • Bar
      • Bax
      • Bap
  • Another list item
maruku-0.7.2/spec/block_docs/fenced_code_blocks_highlighted.md0000644000004100000410000000175312347070213024552 0ustar www-datawww-dataFenced code blocks *** Parameters: *** { :fenced_code_blocks => true, :html_use_syntax => true } *** Markdown input: *** ```ruby john = Twitter::Client.new( :oauth_token => "John's access token", :oauth_token_secret => "John's access secret" ) ``` *** Output of inspect *** *** Output of to_html ***
john = Twitter::Client.new(
  :oauth_token => "John's access token",
  :oauth_token_secret => "John's access secret"
)
maruku-0.7.2/spec/block_docs/bug_table.md0000644000004100000410000000225312347070213020357 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** hello {: summary="Table summary" .class1 style="color:red"} h | h ----------|-- {:t} c1 | c2 {: summary="Table summary" .class1 style="color:red"} {:t: scope="row"} *** Output of inspect *** md_el(:document,[ md_par(["hello"], [["summary", "Table summary"], [:class, "class1"], ["style", "color:red"]]), md_el(:table,[ [md_el(:head_cell,["h"],{},[]), md_el(:head_cell,["h"],{},[])], [md_el(:cell,[" c1"],{},[[:ref, "t"]]), md_el(:cell,["c2"],{},[])] ],{:align=>[:left, :left]},[["summary", "Table summary"], [:class, "class1"], ["style", "color:red"]]), md_el(:ald,[],{:ald=>[["scope", "row"]],:ald_id=>"t"},[]) ],{},[]) *** Output of to_html ***

hello

hh
c1c2
*** Output of to_latex *** hello \begin{tabular}{l|l} h&h\\ \hline c1&c2\\ \end{tabular} *** Output of to_md *** hello hh c1c2 *** Output of to_s *** hellohh c1c2 maruku-0.7.2/spec/block_docs/xml3.md0000644000004100000410000000066612347070213017324 0ustar www-datawww-dataThe markdown="1" attribute does NOT get recursively applied *** Parameters: *** {} *** Markdown input: *** Blah
*em*
*** Output of inspect *** md_el(:document,[ md_html("\n\tBlah\n\t\n\t\t\n\t\n
*em*
") ],{},[]) *** Output of to_html *** Blah
*em*
maruku-0.7.2/spec/block_docs/olist.md0000644000004100000410000000125412347070213017565 0ustar www-datawww-data *** Parameters: *** {} *** Markdown input: *** This is a list: 2. one 2. two 3. three *** Output of inspect *** md_el(:document,[ md_par(["This is a list:"]), md_el(:ol,[ md_el(:li,["one"],{:want_my_paragraph=>false},[]), md_el(:li,["two"],{:want_my_paragraph=>false},[]), md_el(:li,["three"],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***

This is a list:

  1. one
  2. two
  3. three
*** Output of to_latex *** This is a list: \begin{enumerate}% \item one \item two \item three \end{enumerate} *** Output of to_md *** This is a list: 1. one 2. two 3. three *** Output of to_s *** This is a list:onetwothree maruku-0.7.2/spec/block_docs/ignore_bad_header.md0000644000004100000410000000057512347070213022041 0ustar www-datawww-dataPass weird messed up header through to output without blowing up. Secondary issue noticed via https://github.com/bhollis/maruku/issues/124 *** Parameters: *** {:on_error => :raise} *** Markdown input: *** = Markdown, with some ruby = *** Output of inspect *** md_el(:document, md_par(["= Markdown, with some ruby ="])) *** Output of to_html ***

= Markdown, with some ruby =

maruku-0.7.2/spec/block_docs/underscore_in_words.md0000644000004100000410000000071512347070213022511 0ustar www-datawww-dataNote that Markdown.pl gives incorrect result here. *** Parameters: *** {} # params *** Markdown input: *** Ok, this_was a_really_old bug *** Output of inspect *** md_el(:document,[md_par(["Ok, this_was a_really_old bug"])],{},[]) *** Output of to_html ***

Ok, this_was a_really_old bug

*** Output of to_latex *** Ok, this\_was a\_really\_old bug *** Output of to_md *** Ok, this_was a_really_old bug *** Output of to_s *** Ok, this_was a_really_old bug maruku-0.7.2/spec/block_docs/attributes/0000755000004100000410000000000012347070213020275 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/attributes/att3.md0000644000004100000410000000075312347070213021477 0ustar www-datawww-dataIALs can refer to element before or after. *** Parameters: *** {} *** Markdown input: *** Paragraph1 {:#par1} {:#par2} Paragraph2 *** Output of inspect *** md_el(:document,[ md_par(["Paragraph1"], [[:id, "par1"]]), md_par(["Paragraph2"], [[:id, "par2"]]) ],{},[]) *** Output of to_html ***

Paragraph1

Paragraph2

*** Output of to_latex *** Paragraph1 Paragraph2 *** Output of to_md *** Paragraph1 Paragraph2 *** Output of to_s *** Paragraph1Paragraph2 maruku-0.7.2/spec/block_docs/attributes/default.md0000644000004100000410000000074012347070213022244 0ustar www-datawww-dataThis shows the use of default attributes list. *** Parameters: *** {} *** Markdown input: *** Paragraph2 {#2} {paragraph}: .maruku-par *** Output of inspect *** md_el(:document,[ md_par(["Paragraph2"], [[:id, "2"]]), md_el(:ald,[],{:ald=>[[:class, "maruku-par"]],:ald_id=>"paragraph"},[]) ],{},[]) *** Output of to_html ***

Paragraph2

*** Output of to_latex *** Paragraph2 *** Output of to_md *** Paragraph2 *** Output of to_s *** Paragraph2 maruku-0.7.2/spec/block_docs/attributes/circular.md0000644000004100000410000000065712347070213022433 0ustar www-datawww-data *** Parameters: *** {} *** Markdown input: *** Paragraph {:a} {:a: b} {:b: a} *** Output of inspect *** md_el(:document,[ md_par(["Paragraph"], [[:ref, "a"]]), md_el(:ald,[],{:ald=>[[:ref, "b"]],:ald_id=>"a"},[]), md_el(:ald,[],{:ald=>[[:ref, "a"]],:ald_id=>"b"},[]) ],{},[]) *** Output of to_html ***

Paragraph

*** Output of to_latex *** Paragraph *** Output of to_md *** Paragraph *** Output of to_s *** Paragraph maruku-0.7.2/spec/block_docs/attributes/attributes.md0000644000004100000410000000327212347070213023011 0ustar www-datawww-dataThis is a simple test for attributes *** Parameters: *** {} *** Markdown input: *** Header with attributes {#header1} ---------------------- ### Header with attributes ### {#header2} ### Header no attributes ### {:warn2}Paragraph with a. {#par1} Paragraph with *emphasis*{:hello notfound} {#par2} {:hello: .chello} *** Output of inspect *** md_el(:document,[ md_el(:header,["Header with attributes"],{:level=>2},[[:id, "header1"]]), md_el(:header,["Header with attributes"],{:level=>3},[[:id, "header2"]]), md_el(:header,["Header no attributes"],{:level=>3},[]), md_par(["Paragraph with a."], [[:id, "par1"]]), md_par([ "Paragraph with ", md_em(["emphasis"], [[:ref, "hello"], [:ref, "notfound"]]) ], [[:id, "par2"]]), md_el(:ald,[],{:ald=>[[:class, "chello"]],:ald_id=>"hello"},[]) ],{},[]) *** Output of to_html ***

Header with attributes

Header with attributes

Header no attributes

Paragraph with a.

Paragraph with emphasis

*** Output of to_latex *** \hypertarget{header1}{}\subsection*{{Header with attributes}}\label{header1} \hypertarget{header2}{}\subsubsection*{{Header with attributes}}\label{header2} \hypertarget{header_no_attributes}{}\subsubsection*{{Header no attributes}}\label{header_no_attributes} Paragraph with a. Paragraph with \emph{emphasis} *** Output of to_md *** ## Header with attributes ## ### Header with attributes ### ### Header no attributes ### Paragraph with a. Paragraph with *emphasis* *** Output of to_s *** Header with attributesHeader with attributesHeader no attributesParagraph with a.Paragraph with emphasis maruku-0.7.2/spec/block_docs/attributes/att2.md0000644000004100000410000000051212347070213021467 0ustar www-datawww-data *** Parameters: *** {} *** Markdown input: *** {a}: a {:b: a} *** Output of inspect *** md_el(:document,[ md_el(:ald,[],{:ald=>[[:ref, "a"]],:ald_id=>"a"},[]), md_el(:ald,[],{:ald=>[[:ref, "a"]],:ald_id=>"b"},[]) ],{},[]) *** Output of to_html *** *** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/list1.md0000644000004100000410000000166112347070213017471 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** * A list item with a blockquote: > This is a blockquote > inside a list item. *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[ md_par(["A list item with a blockquote:"]), md_el(:quote,[md_par(["This is a blockquote inside a list item."])],{},[]) ],{:want_my_paragraph=>true},[]) ],{},[]) ],{},[]) *** Output of to_html ***
  • A list item with a blockquote:

    This is a blockquote inside a list item.

*** Output of to_latex *** \begin{itemize}% \item A list item with a blockquote: \begin{quote}% This is a blockquote inside a list item. \end{quote} \end{itemize} *** Output of to_md *** - list item with a blockquote: This is a blockquote inside a list item. *** Output of to_s *** A list item with a blockquote:This is a blockquote inside a list item. maruku-0.7.2/spec/block_docs/lists_paraindent.md0000644000004100000410000000105012347070213021770 0ustar www-datawww-dataIndentation is weird... *** Parameters: *** {} # params *** Markdown input: *** * A list item * Foo * Bar * Bax Bap * Another list item *** Output of inspect *** md_el(:document, md_el(:ul, [ md_li([ "A list item", md_el(:ul, [ md_li("Foo", false), md_li([ "Bar", md_el(:ul, [ md_li("Bax Bap", false) ]) ], false) ]) ], false), md_li("Another list item", false) ])) *** Output of to_html ***
  • A list item
    • Foo
    • Bar
      • Bax Bap
  • Another list item
maruku-0.7.2/spec/block_docs/encoding/0000755000004100000410000000000012347070213017675 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/encoding/utf-8.md0000644000004100000410000000073612347070213021170 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:italian=>"\303\240\303\250\303\254\303\262\303\271."} *** Markdown input: *** Italian: àèìòù. Japanese: マルク *** Output of inspect *** md_el(:document,[md_par(["Japanese: \343\203\236\343\203\253\343\202\257"])],{},[]) *** Output of to_html ***

Japanese: マルク

*** Output of to_latex *** Japanese: マルク *** Output of to_md *** Japanese: マルク *** Output of to_s *** Japanese: マルク maruku-0.7.2/spec/block_docs/encoding/iso-8859-1.md0000644000004100000410000000107312347070213021563 0ustar www-datawww-dataEncoding: iso-8859-1 *** Parameters: *** {} *** Markdown input: *** Encoding: iso-8859-1 This is iso-8859-1: àèìàù. *** Output of inspect *** md_el(:document,[ md_par([ "This is iso-8859-1: \303\203\302\240\303\203\302\250\303\203\302\254\303\203\302\240\303\203\302\271." ]) ],{},[]) *** Output of to_html ***

This is iso-8859-1: àèìàù.

*** Output of to_latex *** This is iso-8859-1: àèìàù. *** Output of to_md *** This is iso-8859-1: àèìàù. *** Output of to_s *** This is iso-8859-1: àèìàù. maruku-0.7.2/spec/block_docs/tables.md0000644000004100000410000000463712347070213017715 0ustar www-datawww-dataPHP Markdown Extra table syntax *** Parameters: *** {} # params *** Markdown input: *** Col1 | Very very long head | Very very long head| ------- |:-------------------:|-------------------:| cell | center-align | right-align | another | cell | here | | First Header | Second Header | | ------------- | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | First Header | Second Header ------------- | ------------- Content Cell | Content Cell Content Cell | Content Cell *** Output of inspect *** md_el(:document, [ md_el(:table, [ [md_el(:head_cell, "Col1"), md_el(:head_cell, "Very very long head"), md_el(:head_cell, "Very very long head")], [md_el(:cell, "cell"), md_el(:cell, "center-align"), md_el(:cell, "right-align")], [md_el(:cell, "another"), md_el(:cell, "cell"), md_el(:cell, "here")] ], {:align=>[:left, :center, :right]}), md_el(:table, [ [md_el(:head_cell, "First Header"), md_el(:head_cell, "Second Header")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")] ], {:align=>[:left, :left]}), md_el(:table, [ [md_el(:head_cell, "First Header"), md_el(:head_cell, "Second Header")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")] ], {:align=>[:left, :left]}) ]) *** Output of to_html ***
Col1Very very long headVery very long head
cellcenter-alignright-align
anothercellhere
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
maruku-0.7.2/spec/block_docs/test.md0000644000004100000410000000066612347070213017420 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** $ python *** Output of inspect *** md_el(:document,[md_el(:code,[],{:raw_code=>" $ python ", :lang=>nil},[])],{},[]) *** Output of to_html ***
       $ python       
*** Output of to_latex *** \begin{verbatim} $ python \end{verbatim} *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/links.md0000644000004100000410000001250312347070213017552 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:on_error=>:warning} *** Markdown input: *** Search on [Google][] Search on [Google] [] Search on [Google] [google] Search on [Google] [Google] Search on [Google images][] Inline: [Google images](http://google.com) Inline with title: [Google images](http://google.com "Title") Inline with title: [Google images]( http://google.com "Title" ) Search on or or ask or you might ask bill@google.com. If all else fails, ask [Google](http://www.google.com) And now [reference-style link ID with spaces] [Google Images] And now [reference-style link ID (without spaces)][Google Search] [google]: http://www.google.com [google2]: http://www.google.com 'Single quotes' [google3]: http://www.google.com "Double quotes" [google4]: http://www.google.com (Parenthesis) [Google Search]: http://www.google.com 'Google search' [Google Images]: http://images.google.com (Google images) *** Output of inspect *** md_el(:document,[ md_par(["Search on ", md_link(["Google"],"")]), md_par(["Search on ", md_link(["Google"],"")]), md_par(["Search on ", md_link(["Google"],"google")]), md_par(["Search on ", md_link(["Google"],"Google")]), md_par(["Search on ", md_link(["Google images"],"")]), md_par(["Inline: ", md_im_link(["Google images"], "http://google.com", nil)]), md_par([ "Inline with title: ", md_im_link(["Google images"], "http://google.com", "Title") ]), md_par([ "Inline with title: ", md_im_link(["Google images"], "http://google.com", "Title") ]), md_par([ "Search on ", md_url("http://www.gogole.com"), " or ", md_url("http://Here.com"), " or ask ", md_email("bill@google.com"), " or you might ask bill@google.com." ]), md_par([ "If all else fails, ask ", md_im_link(["Google"], "http://www.google.com", nil) ]), md_par([ "And now ", md_link(["reference-style link ID with spaces"],"Google Images") ]), md_par([ "And now ", md_link(["reference-style link ID (without spaces)"], "Google Search") ]), md_ref_def("google", "http://www.google.com", {:title=>nil}), md_ref_def("google2", "http://www.google.com", {:title=>"Single quotes"}), md_ref_def("google3", "http://www.google.com", {:title=>"Double quotes"}), md_ref_def("google4", "http://www.google.com", {:title=>"Parenthesis"}), md_ref_def("google search", "http://www.google.com", {:title=>"Google search"}), md_ref_def("google images", "http://images.google.com", {:title=>"Google images"}) ],{},[]) *** Output of to_html ***

Search on Google

Search on Google

Search on Google

Search on Google

Search on Google images

Inline: Google images

Inline with title: Google images

Inline with title: Google images

Search on http://www.gogole.com or http://Here.com or ask bill@google.com or you might ask bill@google.com.

If all else fails, ask Google

And now reference-style link ID with spaces

And now reference-style link ID (without spaces)

*** Output of to_latex *** Search on \href{http://www.google.com}{Google} Search on \href{http://www.google.com}{Google} Search on \href{http://www.google.com}{Google} Search on \href{http://www.google.com}{Google} Search on \href{http://images.google.com}{Google images} Inline: \href{http://google.com}{Google images} Inline with title: \href{http://google.com}{Google images} Inline with title: \href{http://google.com}{Google images} Search on \href{http://www.gogole.com}{http\char58\char47\char47www\char46gogole\char46com} or \href{http://Here.com}{http\char58\char47\char47Here\char46com} or ask \href{mailto:bill@google.com}{bill\char64google\char46com} or you might ask bill@google.com. If all else fails, ask \href{http://www.google.com}{Google} And now \href{http://images.google.com}{reference-style link ID with spaces} And now \href{http://www.google.com}{reference-style link ID (without spaces)} *** Output of to_md *** Search on Google Search on Google Search on Google Search on Google Search on Google images Inline: Google images Inline with title: Google images Inline with title: Google images Search on or or ask or you might ask bill@google.com. If all else fails, ask Google And now reference-style link ID with spaces And now reference-style link ID (without spaces) *** Output of to_s *** Search on GoogleSearch on GoogleSearch on GoogleSearch on GoogleSearch on Google imagesInline: Google imagesInline with title: Google imagesInline with title: Google imagesSearch on or or ask or you might ask bill@google.com.If all else fails, ask GoogleAnd now reference-style link ID with spacesAnd now reference-style link ID (without spaces) maruku-0.7.2/spec/block_docs/issue120.md0000644000004100000410000000211412347070213020002 0ustar www-datawww-dataStyle tags should be OK with unescaped angle brackets and ampersands. https://github.com/bhollis/maruku/issues/120 NOTE: Commented CDATA is output because we use XHTML - for HTML mode it should be omitted. *** Parameters: *** {} *** Markdown input: *** *** Output of inspect *** *** Output of to_html *** maruku-0.7.2/spec/block_docs/lists13.md0000644000004100000410000000163312347070213017736 0ustar www-datawww-dataList Items with non alphanumeric content *** Parameters: *** {} *** Markdown input: *** * {: #foo} A * {: #bar } ? * {#fubar} B * {#fubar2 } C * {Not an IAL} *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,["A"],{:want_my_paragraph=>false},[[:id, "foo"]]), md_el(:li,["?"],{:want_my_paragraph=>false},[[:id, "bar"]]), md_el(:li,["B"],{:want_my_paragraph=>false},[[:id, "fubar"]]), md_el(:li,["C"],{:want_my_paragraph=>false},[[:id, "fubar2"]]), md_el(:li,["{Not an IAL}"],{:want_my_paragraph=>false},[]) ],{},[]), ],{},[]) *** Output of to_html ***
  • A
  • ?
  • B
  • C
  • {Not an IAL}
*** Output of to_latex *** \begin{itemize}% \item A \item ? \item B \item C \item \{Not an IAL\} \end{itemize} *** Output of to_md *** - A - ? - B - C - {Not an IAL} *** Output of to_s *** A?BC{Not an IAL} maruku-0.7.2/spec/block_docs/fenced_code_blocks.md0000644000004100000410000000403112347070213022202 0ustar www-datawww-dataFenced code blocks *** Parameters: *** { :fenced_code_blocks => true, :html_use_syntax => false } *** Markdown input: *** ```ruby john = Twitter::Client.new( :oauth_token => "John's access token", :oauth_token_secret => "John's access secret" ) ``` ``` john = Twitter::Client.new( :oauth_token => "John's access token", :oauth_token_secret => "John's access secret" ) ``` ~~~~~ruby john = Twitter::Client.new( :oauth_token => "John's access token", :oauth_token_secret => "John's access secret" ) ~~~~~~~ ~~~~~ john = Twitter::Client.new( :oauth_token => "John's access token", :oauth_token_secret => "John's access secret" ) ~~~~~ *** Output of inspect *** md_el(:document, [ md_el(:code, [], {:raw_code=>"john = Twitter::Client.new(\n :oauth_token => \"John's access token\",\n :oauth_token_secret => \"John's access secret\"\n)", :lang=>"ruby"}), md_el(:code, [], {:raw_code=>"john = Twitter::Client.new(\n :oauth_token => \"John's access token\",\n :oauth_token_secret => \"John's access secret\"\n)", :lang=>nil}), md_el(:code, [], {:raw_code=>"john = Twitter::Client.new(\n :oauth_token => \"John's access token\",\n :oauth_token_secret => \"John's access secret\"\n)", :lang=>"ruby"}), md_el(:code, [], {:raw_code=>"john = Twitter::Client.new(\n :oauth_token => \"John's access token\",\n :oauth_token_secret => \"John's access secret\"\n)", :lang=>nil}) ]) *** Output of to_html ***
john = Twitter::Client.new(
  :oauth_token => "John's access token",
  :oauth_token_secret => "John's access secret"
)
john = Twitter::Client.new(
  :oauth_token => "John's access token",
  :oauth_token_secret => "John's access secret"
)
john = Twitter::Client.new(
  :oauth_token => "John's access token",
  :oauth_token_secret => "John's access secret"
)
john = Twitter::Client.new(
  :oauth_token => "John's access token",
  :oauth_token_secret => "John's access secret"
)
maruku-0.7.2/spec/block_docs/inline_html2.md0000644000004100000410000000106712347070213021021 0ustar www-datawww-dataMarkdown inside HTML according to Markdown Extra: http://michelf.ca/projects/php-markdown/extra/#markdown-attr *** Parameters: *** {} *** Markdown input: ***
Test **bold**

Test **bold**

*** Output of inspect *** md_el(:document,[ md_html("
Test **bold**
"), md_html("

Test **bold**

") ],{},[]) *** Output of to_html ***

Test bold

Test bold

*** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/paragraphs.md0000644000004100000410000000150212347070213020557 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** Paragraph 1 Paragraph 2 Paragraph 3 Paragraph 4 Paragraph Br-> Paragraph 5 *** Output of inspect *** md_el(:document,[ md_par(["Paragraph 1"]), md_par(["Paragraph 2"]), md_par([ "Paragraph 3 Paragraph 4 Paragraph Br->", md_el(:linebreak,[],{},[]), "Paragraph 5" ]) ],{},[]) *** Output of to_html ***

Paragraph 1

Paragraph 2

Paragraph 3 Paragraph 4 Paragraph Br->
Paragraph 5

*** Output of to_latex *** Paragraph 1 Paragraph 2 Paragraph 3 Paragraph 4 Paragraph Br-{\tt \symbol{62}}\newline Paragraph 5 *** Output of to_md *** Paragraph 1 Paragraph 2 Paragraph 3 Paragraph 4 Paragraph Br-> Paragraph 5 *** Output of to_s *** Paragraph 1Paragraph 2Paragraph 3 Paragraph 4 Paragraph Br->Paragraph 5 maruku-0.7.2/spec/block_docs/references/0000755000004100000410000000000012347070213020230 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/references/long_example.md0000644000004100000410000000724412347070213023233 0ustar www-datawww-dataTaken from the syntax document *** Parameters: *** {} *** Markdown input: *** filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], [Grutatext] [5], and [EtText] [6] -- the single biggest source of inspiration for Markdown's syntax is the format of plain text email. [1]: http://docutils.sourceforge.net/mirror/setext.html [2]: http://www.aaronsw.com/2002/atx/ [3]: http://textism.com/tools/textile/ [4]: http://docutils.sourceforge.net/rst.html [5]: http://www.triptico.com/software/grutatxt.html [6]: http://ettext.taint.org/doc/ To this end, Markdown's syntax is comprised entirely of punctuation *** Output of inspect *** md_el(:document,[ md_par([ "filters ", md_entity("ndash"), " including ", md_link(["Setext"],"1"), ", ", md_link(["atx"],"2"), ", ", md_link(["Textile"],"3"), ", ", md_link(["reStructuredText"],"4"), ", ", md_link(["Grutatext"],"5"), ", and ", md_link(["EtText"],"6"), " ", md_entity("ndash"), " the single biggest source of inspiration for Markdown", md_entity("rsquo"), "s syntax is the format of plain text email." ]), md_ref_def("1", "http://docutils.sourceforge.net/mirror/setext.html", {:title=>nil}), md_ref_def("2", "http://www.aaronsw.com/2002/atx/", {:title=>nil}), md_ref_def("3", "http://textism.com/tools/textile/", {:title=>nil}), md_ref_def("4", "http://docutils.sourceforge.net/rst.html", {:title=>nil}), md_ref_def("5", "http://www.triptico.com/software/grutatxt.html", {:title=>nil}), md_ref_def("6", "http://ettext.taint.org/doc/", {:title=>nil}), md_par([ "To this end, Markdown", md_entity("rsquo"), "s syntax is comprised entirely of punctuation" ]) ],{},[]) *** Output of to_html ***

filters – including Setext, atx, Textile, reStructuredText, Grutatext, and EtText – the single biggest source of inspiration for Markdown’s syntax is the format of plain text email.

To this end, Markdown’s syntax is comprised entirely of punctuation

*** Output of to_latex *** filters -- including \href{http://docutils.sourceforge.net/mirror/setext.html}{Setext}, \href{http://www.aaronsw.com/2002/atx/}{atx}, \href{http://textism.com/tools/textile/}{Textile}, \href{http://docutils.sourceforge.net/rst.html}{reStructuredText}, \href{http://www.triptico.com/software/grutatxt.html}{Grutatext}, and \href{http://ettext.taint.org/doc/}{EtText} -- the single biggest source of inspiration for Markdown's syntax is the format of plain text email. To this end, Markdown's syntax is comprised entirely of punctuation *** Output of to_md *** filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], [Grutatext] [5], and [EtText] [6] -- the single biggest source of inspiration for Markdown's syntax is the format of plain text email. [1]: http://docutils.sourceforge.net/mirror/setext.html [2]: http://www.aaronsw.com/2002/atx/ [3]: http://textism.com/tools/textile/ [4]: http://docutils.sourceforge.net/rst.html [5]: http://www.triptico.com/software/grutatxt.html [6]: http://ettext.taint.org/doc/ To this end, Markdown's syntax is comprised entirely of punctuation *** Output of to_s *** filters including Setext, atx, Textile, reStructuredText, Grutatext, and EtText the single biggest source of inspiration for Markdowns syntax is the format of plain text email.To this end, Markdowns syntax is comprised entirely of punctuation maruku-0.7.2/spec/block_docs/references/spaces_and_numbers.md0000644000004100000410000000053212347070213024405 0ustar www-datawww-dataSpaces can be put before. ID can be a number *** Parameters: *** {} *** Markdown input: *** [6]: http://ettext.taint.org/doc/ *** Output of inspect *** md_el(:document,[md_ref_def("6", "http://ettext.taint.org/doc/", {:title=>nil})],{},[]) *** Output of to_html *** *** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/footnotes2.md0000644000004100000410000000576212347070213020545 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** require 'maruku/ext/math';{:html_math_engine => 'itex2mml'} *** Markdown input: *** Ruby on Rails is a web-framework[^framework]. It uses the MVC[^MVC] architecture pattern. It has its good points[^points]. [^framework]: a reusable set of libraries [^MVC]: Model View Controller [^points]: Here are its good points 1. Ease of use 2. Rapid development That has nothing to do with putting equations in footnotes[^equations]. [^equations]: Like this: $$ x = r\cos\theta $$ *** Output of inspect *** md_el(:document,[ md_par([ "Ruby on Rails is a web-framework", md_foot_ref("^framework"), ". It uses the MVC", md_foot_ref("^MVC"), " architecture pattern. It has its good points", md_foot_ref("^points"), "." ]), md_el(:footnote, md_par("a reusable set of libraries"), {:footnote_id=>"^framework"}), md_el(:footnote, md_par("Model View Controller"), {:footnote_id=>"^MVC"}), md_el(:footnote, [ md_par("Here are its good points"), md_el(:ol, [md_li("Ease of use", false), md_li("Rapid development", false)]) ], {:footnote_id=>"^points"}), md_par([ "That has nothing to do with putting equations in footnotes", md_foot_ref("^equations"), "." ]), md_el(:footnote, [ md_par("Like this:"), md_el(:equation, [], {:math=>"\nx = r\\cos\\theta\n\n", :label=>nil, :num=>nil}) ], {:footnote_id=>"^equations"}) ],{},[]) *** Output of to_html ***

Ruby on Rails is a web-framework1. It uses the MVC2 architecture pattern. It has its good points3.

That has nothing to do with putting equations in footnotes4.


  1. a reusable set of libraries

  2. Model View Controller

  3. Here are its good points

    1. Ease of use
    2. Rapid development
  4. Like this:

    x=rcosθ x = r\cos\theta
*** Output of to_latex *** Ruby on Rails is a web-framework\footnote{a reusable set of libraries} . It uses the MVC\footnote{Model View Controller} architecture pattern. It has its good points\footnote{Here are its good points \begin{enumerate}% \item Ease of use \item Rapid development \end{enumerate}} . That has nothing to do with putting equations in footnotes\footnote{Like this: \begin{displaymath} x = r\cos\theta \end{displaymath}} .maruku-0.7.2/spec/block_docs/tables2.md0000644000004100000410000000762412347070213017776 0ustar www-datawww-dataTrailing blanks in table rows *** Parameters: *** {} # params *** Markdown input: *** Col1 | Very very long head | Very very long head| ------- |:-------------------:|-------------------:| cell | center-align | right-align | another | cell | here | | First Header | Second Header | | ------------- | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | | First Header | Second Header | | ------------- | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | First Header | Second Header| ------------- | -------------| Content Cell | Content Cell| Content Cell | Content Cell| First Header | Second Header ------------- | ------------- Content Cell | Content Cell Content Cell | Content Cell | Content Cell *** Output of inspect *** md_el(:document, [ md_el(:table, [ [md_el(:head_cell, "Col1"), md_el(:head_cell, "Very very long head"), md_el(:head_cell, "Very very long head")], [md_el(:cell, "cell"), md_el(:cell, "center-align"), md_el(:cell, "right-align")], [md_el(:cell, "another"), md_el(:cell, "cell"), md_el(:cell, "here")] ], {:align=>[:left, :center, :right]}), md_el(:table, [ [md_el(:head_cell, "First Header"), md_el(:head_cell, "Second Header")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")] ], {:align=>[:left, :left]}), md_el(:table, [ [md_el(:head_cell, "First Header"), md_el(:head_cell, "Second Header")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")] ], {:align=>[:left, :left]}), md_el(:table, [ [md_el(:head_cell, "First Header"), md_el(:head_cell, "Second Header")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")] ], {:align=>[:left, :left]}), md_el(:table, [ [md_el(:head_cell, "First Header"), md_el(:head_cell, "Second Header")], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")], [md_el(:cell, "Content Cell"), md_el(:cell, [])], [md_el(:cell, "Content Cell"), md_el(:cell, "Content Cell")] ], {:align=>[:left, :left]}) ]) *** Output of to_html ***
Col1Very very long headVery very long head
cellcenter-alignright-align
anothercellhere
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
First HeaderSecond Header
Content CellContent Cell
Content Cell
Content CellContent Cell
maruku-0.7.2/spec/block_docs/html5.md0000644000004100000410000000171112347070213017462 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: ***
Aperitif
*** Output of inspect *** md_el(:document,[ md_html("
\n \"Aperitif\"\n
") ],{},[]) *** Output of to_html ***
Aperitif
*** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/lists14.md0000644000004100000410000000171612347070213017741 0ustar www-datawww-dataNested Lists with IALs *** Parameters: *** {} *** Markdown input: *** 1. First * {: #bar} A * B 2. {: .foo} Second * C * D 3. {:fubar style="color:red"} Third *** Output of inspect *** md_el(:document, [ md_el(:ol, [ md_li(["First", md_el(:ul, [ md_li("A", false, [[:id, "bar"]]), md_li("B", false) ], {}, []) ], false), md_li([ "Second", md_el(:ul, [md_li("C", false), md_li("D", false)],{},[]) ], false, [[:class, "foo"]]), md_li("Third", false, [[:ref, "fubar"],["style", "color:red"]]) ],{},[]) ],{},[]) *** Output of to_html ***
  1. First
    • A
    • B
  2. Second
    • C
    • D
  3. Third
*** Output of to_latex *** \begin{enumerate}% \item First\begin{itemize}% \item A \item B \end{itemize} \item Second\begin{itemize}% \item C \item D \end{itemize} \item Third \end{enumerate} maruku-0.7.2/spec/block_docs/paragraph_rules/0000755000004100000410000000000012347070213021266 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/paragraph_rules/tab_is_blank.md0000644000004100000410000000066312347070213024225 0ustar www-datawww-dataParagraphs eat blank lines. The following are two paragraphs: *** Parameters: *** {} *** Markdown input: *** Paragraph1 Paragraph2 *** Output of inspect *** md_el(:document,[md_par(["Paragraph1"]), md_par(["Paragraph2"])],{},[]) *** Output of to_html ***

Paragraph1

Paragraph2

*** Output of to_latex *** Paragraph1 Paragraph2 *** Output of to_md *** Paragraph1 Paragraph2 *** Output of to_s *** Paragraph1Paragraph2 maruku-0.7.2/spec/block_docs/paragraph_rules/dont_merge_ref.md0000644000004100000410000000132012347070213024563 0ustar www-datawww-dataParagraphs eats everything, but not link definitions. *** Parameters: *** {} *** Markdown input: *** Paragraph [google1]: # Paragraph [google2]: # Paragraph [google3]: # *** Output of inspect *** md_el(:document,[ md_par(["Paragraph"]), md_ref_def("google1", "#", {:title=>nil}), md_par(["Paragraph"]), md_ref_def("google2", "#", {:title=>nil}), md_par(["Paragraph"]), md_ref_def("google3", "#", {:title=>nil}) ],{},[]) *** Output of to_html ***

Paragraph

Paragraph

Paragraph

*** Output of to_latex *** Paragraph Paragraph Paragraph *** Output of to_md *** Paragraph [google1]: # Paragraph [google2]: # Paragraph [google3]: # *** Output of to_s *** ParagraphParagraphParagraph maruku-0.7.2/spec/block_docs/bug_def.md0000644000004100000410000000047412347070213020031 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** [test][]: *** Output of inspect *** md_el(:document,[md_par([md_link(["test"], ""), ":"])],{},[]) *** Output of to_html ***

[test][]:

*** Output of to_latex *** test: *** Output of to_md *** [test][]: *** Output of to_s *** test: maruku-0.7.2/spec/block_docs/easy.md0000644000004100000410000000070312347070213017372 0ustar www-datawww-dataSimple test for emphasis. *** Parameters: *** {} *** Markdown input: *** *Hello!* how are **you**? *** Output of inspect *** md_el(:document,[md_par([md_em(["Hello!"]), " how are ", md_strong(["you"]), "?"])],{},[]) *** Output of to_html ***

Hello! how are you?

*** Output of to_latex *** \emph{Hello!} how are \textbf{you}? *** Output of to_md *** *Hello!* how are **you**? *** Output of to_s *** Hello! how are you? maruku-0.7.2/spec/block_docs/extra_header_id.md0000644000004100000410000000416112347070213021542 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:title=>"Header 1"} *** Markdown input: *** Header 1 {#header1} ======== Header 2 {#header2} -------- ### Header 3 ### {#header3} Then you can create links to different parts of the same document like this: [Link back to header 1](#header1), [Link back to header 2](#header2), [Link back to header 3](#header3) *** Output of inspect *** md_el(:document,[ md_el(:header,["Header 1"],{:level=>1},[[:id, "header1"]]), md_el(:header,["Header 2"],{:level=>2},[[:id, "header2"]]), md_el(:header,["Header 3"],{:level=>3},[[:id, "header3"]]), md_par([ "Then you can create links to different parts of the same document like this:" ]), md_par([ md_im_link(["Link back to header 1"], "#header1", nil), ", ", md_im_link(["Link back to header 2"], "#header2", nil), ", ", md_im_link(["Link back to header 3"], "#header3", nil) ]) ],{},[]) *** Output of to_html ***

Header 1

Header 2

Header 3

Then you can create links to different parts of the same document like this:

Link back to header 1, Link back to header 2, Link back to header 3

*** Output of to_latex *** \hypertarget{header1}{}\section*{{Header 1}}\label{header1} \hypertarget{header2}{}\subsection*{{Header 2}}\label{header2} \hypertarget{header3}{}\subsubsection*{{Header 3}}\label{header3} Then you can create links to different parts of the same document like this: \hyperlink{header1}{Link back to header 1}, \hyperlink{header2}{Link back to header 2}, \hyperlink{header3}{Link back to header 3} *** Output of to_md *** # Header 1 # ## Header 2 ## ### Header 3 ### Then you can create links to different parts of the same document like this: [Link back to header 1](#header1), [Link back to header 2](#header2), [Link back to header 3](#header3) *** Output of to_s *** Header 1Header 2Header 3Then you can create links to different parts of the same document like this:Link back to header 1, Link back to header 2, Link back to header 3 maruku-0.7.2/spec/block_docs/lists_nested_blankline.md0000644000004100000410000000072212347070213023151 0ustar www-datawww-dataNesting lists should handle newlines inbetween list items. *** Parameters: *** {} # params *** Markdown input: *** * Bar * Bax * boo *** Output of inspect *** md_el(:document, md_el(:ul, [ md_li([ md_par("Bar"), md_el(:ul, [ md_li(md_par("Bax"), true), md_li(md_par("boo"), false) ], {}, []) ],true) ],{},[])) *** Output of to_html ***
  • Bar

    • Bax

    • boo

maruku-0.7.2/spec/block_docs/lists11.md0000644000004100000410000000062212347070213017731 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** - ένα *** Output of inspect *** md_el(:document,[ md_el(:ul,[md_el(:li,["ένα"],{:want_my_paragraph=>false},[])],{},[]) ],{},[]) *** Output of to_html ***
  • ένα
*** Output of to_latex *** \begin{itemize}% \item ένα \end{itemize} *** Output of to_md *** - ένα *** Output of to_s *** ένα maruku-0.7.2/spec/block_docs/code2.md0000644000004100000410000000100312347070213017417 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** > Code > > Ciao *** Output of inspect *** md_el(:document,[ md_el(:quote,[md_par(["Code"]), md_el(:code,[],{:raw_code=>"Ciao", :lang=>nil},[])],{},[]) ],{},[]) *** Output of to_html ***

Code

Ciao
*** Output of to_latex *** \begin{quote}% Code \begin{verbatim}Ciao\end{verbatim} \end{quote} *** Output of to_md *** > Code > > Ciao *** Output of to_s *** Code maruku-0.7.2/spec/block_docs/images.md0000644000004100000410000000731712347070213017706 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** This page does not utilize ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss) Please mouseover to see the title: ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss "Title ok!") Please mouseover to see the title: ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss 'Title ok!') I'll say it one more time: this page does not use ![Cascading Style Sheets] [css] This is double size: ![Cascading Style Sheets] [css2] [css]: http://jigsaw.w3.org/css-validator/images/vcss "Optional title attribute" [css2]: http://jigsaw.w3.org/css-validator/images/vcss "Optional title attribute" class=external style="border:0;width:188px;height:131px" *** Output of inspect *** md_el(:document,[ md_par([ "This page does not utilize ", md_im_image(["Cascading Style Sheets"], "http://jigsaw.w3.org/css-validator/images/vcss", nil) ]), md_par([ "Please mouseover to see the title: ", md_im_image(["Cascading Style Sheets"], "http://jigsaw.w3.org/css-validator/images/vcss", "Title ok!") ]), md_par([ "Please mouseover to see the title: ", md_im_image(["Cascading Style Sheets"], "http://jigsaw.w3.org/css-validator/images/vcss", "Title ok!") ]), md_par([ "I", md_entity("rsquo"), "ll say it one more time: this page does not use ", md_image(["Cascading Style Sheets"], "css") ]), md_par([ "This is double size: ", md_image(["Cascading Style Sheets"], "css2") ]), md_ref_def("css", "http://jigsaw.w3.org/css-validator/images/vcss", {:title=>"Optional title attribute"}), md_ref_def("css2", "http://jigsaw.w3.org/css-validator/images/vcss", {:title=>"Optional title attribute"}) ],{},[]) *** Output of to_html ***

This page does not utilize Cascading Style Sheets

Please mouseover to see the title: Cascading Style Sheets

Please mouseover to see the title: Cascading Style Sheets

I’ll say it one more time: this page does not use Cascading Style Sheets

This is double size: Cascading Style Sheets

*** Output of to_latex *** This page does not utilize Please mouseover to see the title: Please mouseover to see the title: I'll say it one more time: this page does not use This is double size: *** Output of to_md *** This page does not utilize ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss) Please mouseover to see the title: ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss "Title ok!") Please mouseover to see the title: ![Cascading Style Sheets](http://jigsaw.w3.org/css-validator/images/vcss "Title ok!") I'll say it one more time: this page does not use ![Cascading Style Sheets][css] This is double size: ![Cascading Style Sheets][css2] [css]: http://jigsaw.w3.org/css-validator/images/vcss "Optional title attribute" [css2]: http://jigsaw.w3.org/css-validator/images/vcss "Optional title attribute" class=external style="border:0;width:188px;height:131px" *** Output of to_s *** This page does not utilize Cascading Style SheetsPlease mouseover to see the title: Cascading Style SheetsPlease mouseover to see the title: Cascading Style SheetsIll say it one more time: this page does not use Cascading Style SheetsThis is double size: Cascading Style Sheets maruku-0.7.2/spec/block_docs/html_block_in_para.md0000644000004100000410000000061012347070213022235 0ustar www-datawww-dataMaruku should not nest block-level HTML inside a paragraph *** Parameters: *** {} # params *** Markdown input: *** One
a
123
a
123 *** Output of inspect *** md_el(:document,[ md_par("One"), md_html("
a
"), md_par("123"), md_html("
a
"), md_par("123") ],{},[]) *** Output of to_html ***

One

a

123

a

123

maruku-0.7.2/spec/block_docs/issue124.md0000644000004100000410000000102312347070213020004 0ustar www-datawww-dataHandle blocks of inline HTML without a newline without complaining. https://github.com/bhollis/maruku/issues/124 *** Parameters: *** {:on_error => :raise} *** Markdown input: *** What follows uses ruby (トウ) (キョウ) . *** Output of inspect *** *** Output of to_html ***

What follows uses ruby (トウ) (キョウ) .

maruku-0.7.2/spec/block_docs/issue130.md0000644000004100000410000000063112347070213020005 0ustar www-datawww-dataHandle ellipsis at the end of a line. https://github.com/bhollis/maruku/issues/130 *** Parameters: *** { } *** Markdown input: *** A paragraph... continued... *** Output of inspect *** md_el(:document, md_par(["A paragraph", md_entity("hellip"), " continued", md_entity("hellip")])) *** Output of to_html ***

A paragraph… continued…

*** Output of to_latex *** A paragraph\ldots{} continued\ldots{} maruku-0.7.2/spec/block_docs/issue26.md0000644000004100000410000000072112347070213017731 0ustar www-datawww-dataNested lists shouldn't get

tags wrapped around elements. https://github.com/bhollis/maruku/issues/26 *** Parameters: *** {} *** Markdown input: *** - Root + Node + Node - Root *** Output of inspect *** md_el(:document, md_el(:ul, [ md_li(["Root", md_el(:ul, [md_li("Node", false), md_li("Node", false)])], false), md_li("Root", false) ])) *** Output of to_html ***

  • Root
    • Node
    • Node
  • Root
maruku-0.7.2/spec/block_docs/lists_tab.md0000644000004100000410000000145012347070213020415 0ustar www-datawww-dataSub-lists should be indentable with a single tab. *** Parameters: *** {} # params *** Markdown input: *** Ciao * Tab * Tab * Tab *** Output of inspect *** md_el(:document,[ md_par(["Ciao"]), md_el(:ul,[md_el(:li,["Tab", md_el(:ul,[md_el(:li,["Tab", md_el(:ul,[md_el(:li,["Tab"],{:want_my_paragraph=>false})])], {:want_my_paragraph=>false})])], {:want_my_paragraph=>false})]) ]) *** Output of to_html ***

Ciao

  • Tab
    • Tab
      • Tab
*** Output of to_latex *** Ciao \begin{itemize}% \item Tab\begin{itemize}% \item Tab\begin{itemize}% \item Tab \end{itemize} \end{itemize} \end{itemize} *** Output of to_md *** Ciao -ab * Tab * Tab *** Output of to_s *** CiaoTab * Tab * Tab maruku-0.7.2/spec/block_docs/attribute_sanitize.md0000644000004100000410000000124712347070213022346 0ustar www-datawww-dataMake sure extended attributes get escaped when generating HTML: https://github.com/bhollis/maruku/issues/114 *** Parameters: *** {} # params *** Markdown input: *** *foo*{: style='ball & chain'} *foo*{: style='ball\008 chain'} *foo*{: style='ball\" badAttribute=\"chain'} *** Output of inspect *** md_el(:document, [ md_par(md_em("foo", [["style", "ball & chain"]])), md_par(md_em("foo", [["style", "ball\\008 chain"]])), md_par(md_em("foo", [["style", "ball\" badAttribute=\"chain"]])) ]) *** Output of to_html ***

foo

foo

foo

maruku-0.7.2/spec/block_docs/table_colspan.md0000644000004100000410000000354412347070213021245 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** | h1 | h2 | h3 | |:----------|:---:|-----:| |c1 | c2 | c3 | |c1 | c2 || |c1 || c2 | |c1 ||| {: summary="Table summary" .class1 style="color:blue" border=1 width="50%" cellspacing=2em cellpadding=4px} {:t: scope="row"} *** Output of inspect *** md_el(:document,[ md_el(:table, [ [md_el(:head_cell, "h1"), md_el(:head_cell, "h2"), md_el(:head_cell, "h3")], [md_el(:cell, "c1"), md_el(:cell, "c2"), md_el(:cell, "c3")], [md_el(:cell, "c1"), md_el(:cell, "c2", {}, [["colspan", "2"]])], [md_el(:cell, "c1", {}, [["colspan", "2"]]), md_el(:cell, "c2")], [md_el(:cell, "c1", {}, [["colspan", "3"]])] ],{:align=>[:left, :center, :right]},[["summary", "Table summary"], [:class, "class1"], ["style", "color:blue"], ["border", ""], ["width", "50%"], ["frame", "lhs"], ["rules", "cols"], ["cellspacing", "2em"], ["cellpadding", "4px"]]), md_el(:ald,[],{:ald=>[["scope", "row"]],:ald_id=>"t"},[]) ],{},[]) *** Output of to_html ***
h1h2h3
c1c2c3
c1c2
c1c2
c1
*** Output of to_latex *** \begin{tabular}{l|c|r} h1&h2&h3\\ \hline c1&c2&c3\\ c1&\multicolumn {2}{|l|}{c2}\\ \multicolumn {2}{|l|}{c1}&c2\\ \multicolumn {3}{|l|}{c1}\\ \end{tabular} maruku-0.7.2/spec/block_docs/one.md0000644000004100000410000000046512347070213017217 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** One line *** Output of inspect *** md_el(:document,[md_par(["One line"])],{},[]) *** Output of to_html ***

One line

*** Output of to_latex *** One line *** Output of to_md *** One line *** Output of to_s *** One line maruku-0.7.2/spec/block_docs/xml_instruction.md0000644000004100000410000000230112347070213021666 0ustar www-datawww-dataDirectives should be preserved. *** Parameters: *** {} *** Markdown input: *** Targets ! Inside: last *** Output of inspect *** md_el(:document,[ md_el(:xml_instr,[],{:code=>" noTarget",:target=>""},[]), md_el(:xml_instr,[],{:code=>"",:target=>"php"},[]), md_el(:xml_instr,[],{:code=>"",:target=>"xml"},[]), md_el(:xml_instr,[],{:code=>"",:target=>"mrk"},[]), md_par([ "Targets ", md_el(:xml_instr,[],{:code=>"noTarget",:target=>""},[]), " ", md_el(:xml_instr,[],{:code=>"",:target=>"php"},[]), " ", md_el(:xml_instr,[],{:code=>"",:target=>"xml"},[]), " ", md_el(:xml_instr,[],{:code=>"",:target=>"mrk"},[]), " !" ]), md_par([ "Inside: ", md_el(:xml_instr,[],{:code=>"puts \"Inside: Hello\"",:target=>"mrk"},[]), " last" ]) ],{},[]) *** Output of to_html *** <? noTarget?>

Targets <?noTarget?> !

Inside: last

*** Output of to_latex *** Targets ! Inside: last *** Output of to_md *** Targets Inside: last *** Output of to_s *** Targets Inside: last maruku-0.7.2/spec/block_docs/table_attributes.md0000644000004100000410000000233512347070213021771 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** h | h ----------|--- {:t} c1 | c2 {: summary="Table summary" .class1 style="color:red" border=3 width="50%" frame=lhs rules=cols cellspacing=2em cellpadding=4px} {:t: scope="row"} *** Output of inspect *** md_el(:document,[ md_el(:table,[ [md_el(:head_cell,["h"],{},[]),md_el(:head_cell,["h"],{},[])], [md_el(:cell,[" c1"],{},[[:ref, "t"]]),md_el(:cell,["c2"],{},[])] ],{:align=>[:left, :left]},[["summary", "Table summary"], [:class, "class1"], ["style", "color:red"], ["border", "3"], ["width", "50%"], ["frame", "lhs"], ["rules", "cols"], ["cellspacing", "2em"], ["cellpadding", "4px"]]), md_el(:ald,[],{:ald=>[["scope", "row"]],:ald_id=>"t"},[]) ],{},[]) *** Output of to_html ***
hh
c1c2
*** Output of to_latex *** \begin{tabular}{l|l} h&h\\ \hline c1&c2\\ \end{tabular} *** Output of to_md *** hh c1c2 *** Output of to_s *** hh c1c2 maruku-0.7.2/spec/block_docs/divs/0000755000004100000410000000000012347070213017054 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/divs/div2.md0000644000004100000410000000057412347070213020250 0ustar www-datawww-dataWrite a comment here *** Parameters: *** require 'maruku/ext/div'; {} # params *** Markdown input: *** +-- ciao =-- *** Output of inspect *** md_el(:document,[ md_el(:div,[md_par(["ciao"])],{:label=>nil,:num=>nil,:type=>nil},[]) ],{},[]) *** Output of to_html ***

ciao

*** Output of to_latex *** ciao *** Output of to_md *** ciao *** Output of to_s *** ciao maruku-0.7.2/spec/block_docs/divs/div3_nest.md0000644000004100000410000000240412347070213021274 0ustar www-datawww-dataJRUBY PENDING - This is just crazy, and crashes JRuby with its crazy regexes *** Parameters: *** require 'maruku/ext/div'; {} # params *** Markdown input: *** +-----------------------------------{.warning}------ | this is the last warning! | | please, go away! | | +------------------------------------- {.menace} -- | | or else terrible things will happen | +-------------------------------------------------- +--------------------------------------------------- *** Output of inspect *** md_el(:document,[ md_el(:div,[ md_par(["this is the last warning!"]), md_par(["please, go away!"]), md_el(:div,[md_par(["or else terrible things will happen"])],{:label=>nil,:num=>nil,:type=>nil},[[:class, "menace"]]) ],{:label=>nil,:num=>nil,:type=>nil},[[:class, "warning"]]) ],{},[]) *** Output of to_html ***

this is the last warning!

please, go away!

or else terrible things will happen

*** Output of to_latex *** this is the last warning! please, go away! or else terrible things will happen *** Output of to_md *** this is the last warning! please, go away! or else terrible things will happen *** Output of to_s *** this is the last warning!please, go away!or else terrible things will happen maruku-0.7.2/spec/block_docs/divs/div1.md0000644000004100000410000000357612347070213020254 0ustar www-datawww-dataWrite a comment here *** Parameters: *** require 'maruku/ext/div'; {} # params *** Markdown input: *** +--------- | text +---------- +--------- |text +-- text =-- +--------- | text +---------- +--------- |text +-- text =-- +--------- | text +---------- +--------- |text +-- text =-- +--------- | text +---------- +--------- |text +-- text =-- *** Output of inspect *** md_el(:document,[ md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]), md_el(:div,[md_par(["text"])],{:label=>nil,:num=>nil,:type=>nil},[]) ],{},[]) *** Output of to_html ***

text

text

text

text

text

text

text

text

text

text

text

text

*** Output of to_latex *** text text text text text text text text text text text text *** Output of to_md *** text text text text text text text text text text text text *** Output of to_s *** texttexttexttexttexttexttexttexttexttexttexttext maruku-0.7.2/spec/block_docs/math/0000755000004100000410000000000012347070213017040 5ustar www-datawww-datamaruku-0.7.2/spec/block_docs/math/notmath.md0000644000004100000410000000075612347070213021044 0ustar www-datawww-data *** Parameters: *** require 'maruku/ext/math'; {:math_enabled => false} *** Markdown input: *** This is not $math$. \[ \alpha \] *** Output of inspect *** md_el(:document,[md_par(["This is not $math$."]), md_par(["[ \\alpha ]"])],{},[]) *** Output of to_html ***

This is not $math$.

[ \alpha ]

*** Output of to_latex *** This is not \$math\$. [ $\backslash$alpha ] *** Output of to_md *** This is not $math$. [ \alpha ] *** Output of to_s *** This is not $math$.[ \alpha ] maruku-0.7.2/spec/block_docs/math/spaces_after_inline_math.md0000644000004100000410000000124212347070213024367 0ustar www-datawww-data *** Parameters: *** require 'maruku/ext/math'; {:html_math_engine => 'itex2mml'} *** Markdown input: *** This *is* $a * b * c$ ahem. *** Output of inspect *** md_el(:document, md_par([ "This ", md_em("is"), " ", md_el(:inline_math, [], {:math=>"a * b * c"}), " ahem." ])) *** Output of to_html ***

This is a*b*ca * b * c ahem.

*** Output of to_latex *** This \emph{is} $a * b * c$ ahem. maruku-0.7.2/spec/block_docs/math/inline.md0000644000004100000410000000311112347070213020634 0ustar www-datawww-data *** Parameters: *** require 'maruku/ext/math'; {:html_math_engine => 'itex2mml'} *** Markdown input: *** Here are some formulas: * $\alpha$ * $x^{n}+y^{n} \neq z^{n}$ That's it, nothing else is supported. *** Output of inspect *** md_el(:document,[ md_par(["Here are some formulas:"]), md_el(:ul,[ md_el(:li,[md_el(:inline_math,[],{:math=>"\\alpha"},[])],{:want_my_paragraph=>false},[]), md_el(:li,[md_el(:inline_math,[],{:math=>"x^{n}+y^{n} \\neq z^{n}"},[])],{:want_my_paragraph=>false},[]) ],{},[]), md_par(["That", md_entity("rsquo"), "s it, nothing else is supported."]) ],{},[]) *** Output of to_html ***

Here are some formulas:

  • α\alpha
  • x n+y nz nx^{n}+y^{n} \neq z^{n}

That’s it, nothing else is supported.

*** Output of to_latex *** Here are some formulas: \begin{itemize}% \item $\alpha$ \item $x^{n}+y^{n} \neq z^{n}$ \end{itemize} That's it, nothing else is supported. *** Output of to_md *** Here are some formulas: -- That s it, nothing else is supported. *** Output of to_s *** Here are some formulas:Thats it, nothing else is supported. maruku-0.7.2/spec/block_docs/math/table2.md0000644000004100000410000000276412347070213020544 0ustar www-datawww-data *** Parameters: *** {} *** Markdown input: *** Symbol | Meaning | comments ------------|---------|--------- {:r} α | The first | I like it. {:r} ℵ | The first | I like it. {:r: scope='row'} *** Output of inspect *** md_el(:document,[ md_el(:table,[ [md_el(:head_cell,["Symbol"],{},[]), md_el(:head_cell,["Meaning"],{},[]), md_el(:head_cell,["comments"],{},[])], [md_el(:cell,[" ", md_entity("alpha")],{},[[:ref, "r"]]), md_el(:cell,["The first"],{},[]), md_el(:cell,["I like it."],{},[])], [md_el(:cell,[" ", md_entity("aleph")],{},[[:ref, "r"]]), md_el(:cell,["The first"],{},[]), md_el(:cell,["I like it."],{},[])] ],{:align=>[:left, :left, :left]},[]), md_el(:ald,[],{:ald=>[["scope", "row"]],:ald_id=>"r"},[]) ],{},[]) *** Output of to_html ***
SymbolMeaningcomments
αThe firstI like it.
The firstI like it.
*** Output of to_latex *** \begin{tabular}{l|l|l} Symbol&Meaning&comments\\ \hline $\alpha$&The first&I like it.\\ &The first&I like it.\\ \end{tabular} *** Output of to_md *** SymbolMeaningcomments The firstI like it. The firstI like it. *** Output of to_s *** SymbolMeaningcomments The firstI like it. The firstI like it. maruku-0.7.2/spec/block_docs/math/raw_mathml.md0000644000004100000410000001436612347070213021527 0ustar www-datawww-dataJRUBY NOKOGIRI PENDING - MathML inline with HTML (JRuby Nokogiri is broken for empty tags: https://github.com/sparklemotion/nokogiri/issues/971) *** Parameters: *** {} *** Markdown input: *** In SU(3), Rank-2 Symmetric Tensor Representation = Rank-2 Symmetric Tensor Representation . Rank-2 Symmetric Tensor Representation = Rank-2 Symmetric Tensor Representation *** Output of inspect *** md_el(:document,[ md_par(["In ", md_html("SU(3)"), ", ", md_html("\n\n Rank-2 Symmetric Tensor Representation\n \n \n \n \n\n=\n\n Rank-2 Symmetric Tensor Representation\n \n \n \n \n\n"), "." ]), md_html("\n\n Rank-2 Symmetric Tensor Representation\n \n \n \n \n\n=\n\n Rank-2 Symmetric Tensor Representation\n \n \n \n \n\n") ],{},[]) *** Output of to_html ***

In SU(3), Rank-2 Symmetric Tensor Representation = Rank-2 Symmetric Tensor Representation .

Rank-2 Symmetric Tensor Representation = Rank-2 Symmetric Tensor Representation maruku-0.7.2/spec/block_docs/math/equations.md0000644000004100000410000000343312347070213021375 0ustar www-datawww-dataWrite a comment here *** Parameters: *** require 'maruku/ext/math';{:html_math_engine => 'itex2mml'} *** Markdown input: *** $$ x = y $$ $$ x = y $$ $$ x = y $$ $$ x = y $$ *** Output of inspect *** md_el(:document,[ md_el(:equation,[],{:label=>nil,:math=>" x = y ",:num=>nil},[]), md_el(:equation,[],{:label=>nil,:math=>" x \n= y \n",:num=>nil},[]), md_el(:equation,[],{:label=>nil,:math=>" \nx = y \n",:num=>nil},[]), md_el(:equation,[],{:label=>nil,:math=>" x = y \n\n",:num=>nil},[]) ],{},[]) *** Output of to_html ***
x=y x = y
x=y x = y
x=y x = y
x=y x = y
*** Output of to_latex *** \begin{displaymath} x = y \end{displaymath} \begin{displaymath} x = y \end{displaymath} \begin{displaymath} x = y \end{displaymath} \begin{displaymath} x = y \end{displaymath} *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/math/embedded_svg.md0000644000004100000410000001654012347070213022000 0ustar www-datawww-dataSupport embedded SVG in LaTeX expressions. TODO: The LaTeX output does not look correct here! *** Parameters: *** require 'maruku/ext/math'; {:html_math_engine => 'itex2mml'} *** Markdown input: *** In $SU(3)$, $\begin{svg} Rank-2 Symmetric Tensor Representation \end{svg}\includegraphics[width=2em]{young1} \otimes \begin{svg} Fundamental Representation \end{svg}\includegraphics[width=1em]{young2} = \begin{svg} Adjoint Representation \end{svg}\includegraphics[width=2em]{young3} \oplus \begin{svg} Rank-3 Symmetric Tensor Representation \end{svg}\includegraphics[width=3em]{young4}$. *** Output of inspect *** md_el(:document,[ md_par(["In ", md_el(:inline_math, [], {:math=>"SU(3)"}), ", ", md_el(:inline_math, [], {:math=>"\\begin{svg}\n\n Rank-2 Symmetric Tensor Representation\n \n \n \n \n\n\\end{svg}\\includegraphics[width=2em]{young1}\n \\otimes\n\\begin{svg}\n\n Fundamental Representation\n \n \n \n\n\\end{svg}\\includegraphics[width=1em]{young2}\n =\n\\begin{svg}\n\n Adjoint Representation\n \n \n \n \n \n\n\\end{svg}\\includegraphics[width=2em]{young3}\n \\oplus\n\\begin{svg}\n\n Rank-3 Symmetric Tensor Representation\n \n \n \n \n \n\n\\end{svg}\\includegraphics[width=3em]{young4}"}), "." ]) ],{},[]) *** Output of to_html ***

In SU(3)SU(3), Rank-2 Symmetric Tensor Representation Fundamental Representation = Adjoint Representation Rank-3 Symmetric Tensor Representation \begin{svg} <svg xmlns="http://www.w3.org/2000/svg" width="30" height="16" viewBox="0 0 30 16"> <desc>Rank-2 Symmetric Tensor Representation</desc> <g transform="translate(5,5)" fill="#FCC" stroke="#000" stroke-width="2"> <rect width="10" height="10"/> <rect width="10" height="10" x="10"/> </g> </svg> \end{svg}\includegraphics[width=2em]{young1} \otimes \begin{svg} <svg xmlns="http://www.w3.org/2000/svg" width="20" height="16" viewBox="0 0 20 16"> <desc>Fundamental Representation</desc> <g transform="translate(5,5)" fill="#FCC" stroke="#000" stroke-width="2"> <rect width="10" height="10"/> </g> </svg> \end{svg}\includegraphics[width=1em]{young2} = \begin{svg} <svg xmlns="http://www.w3.org/2000/svg" width="30" height="26" viewBox="0 0 30 26"> <desc>Adjoint Representation</desc> <g transform="translate(5,5)" fill="#FCC" stroke="#000" stroke-width="2"> <rect width="10" height="10"/> <rect width="10" height="10" x="10"/> <rect width="10" height="10" y="10"/> </g> </svg> \end{svg}\includegraphics[width=2em]{young3} \oplus \begin{svg} <svg xmlns="http://www.w3.org/2000/svg" width="40" height="16" viewBox="0 0 40 16"> <desc>Rank-3 Symmetric Tensor Representation</desc> <g transform="translate(5,5)" fill="#FCC" stroke="#000" stroke-width="2"> <rect width="10" height="10"/> <rect width="10" height="10" x="10"/> <rect width="10" height="10" x="20"/> </g> </svg> \end{svg}\includegraphics[width=3em]{young4}.

*** Output of to_latex *** In $SU(3)$, $ \includegraphics[width=2em]{young1} \otimes \includegraphics[width=1em]{young2} = \includegraphics[width=2em]{young3} \oplus \includegraphics[width=3em]{young4}$. maruku-0.7.2/spec/block_docs/math/embedded_invalid_svg.md0000644000004100000410000001216312347070213023503 0ustar www-datawww-dataREXML PENDING - This tests that invalid SVG within LaTeX gets corrected and still output. I'm not sure why it should do that. Pending because Nokogiri will handle the tagsoup but REXML won't. TODO: The LaTeX output does not look correct here! *** Parameters: *** require 'maruku/ext/math'; {:html_math_engine => 'itex2mml'} *** Markdown input: *** In $SU(3)$, $\begin{svg} \end{svg}\includegraphics[width=2em]{young1} \otimes \begin{svg} Fundamental Representation \end{svg}\includegraphics[width=1em]{young2} = \begin{svg} Adjoint Representation \end{svg}\includegraphics[width=2em]{young3} \oplus \begin{svg} Rank-3 Symmetric Tensor Representation \end{svg}\includegraphics[width=3em]{young4}$. *** Output of inspect *** md_el(:document,[ md_par(["In ", md_el(:inline_math, [], {:math=>"SU(3)"}), ", ", md_el(:inline_math, [], {:math=>"\\begin{svg}\n\n \n\n\\end{svg}\\includegraphics[width=2em]{young1}\n \\otimes\n\\begin{svg}\n\n Fundamental Representation\n \n\n\\end{svg}\\includegraphics[width=1em]{young2}\n =\n\\begin{svg}\n\n Adjoint Representation\n \n\n\\end{svg}\\includegraphics[width=2em]{young3}\n \\oplus\n\\begin{svg}\n\n Rank-3 Symmetric Tensor Representation\n \n \n \n \n \n\n\\end{svg}\\includegraphics[width=3em]{young4}"}), "." ]) ],{},[]) *** Output of to_html ***

In SU(3)SU(3), Fundamental Representation = Adjoint Representation Rank-3 Symmetric Tensor Representation \begin{svg} svg xmlns=http://www.w3.org/2000/svg width=30 height=16 viewBox=0 0 30 16 g/rect /svg \end{svg}\includegraphics[width=2em]{young1} \otimes \begin{svg} svg xmlns=http://www.w3.org/2000/svg width=20 height=16 viewBox=0 0 20 16 descFundamental Representation/desc g /svg \end{svg}\includegraphics[width=1em]{young2} = \begin{svg} svg xmlns=http://www.w3.org/2000/svg width=30 height=26 viewBox=0 0 30 26 descAdjoint Representation/desc /g /svg \end{svg}\includegraphics[width=2em]{young3} \oplus \begin{svg} svg xmlns=http://www.w3.org/2000/svg width=40 height=16 viewBox=0 0 40 16 descRank-3 Symmetric Tensor Representation/desc g transform=translate(5,5) fill=#FCC stroke=#000 stroke-width=2 rect width=10 height=10/ rect width=10 height=10 x=10/ rect width=10 height=10 x=20/ /g /svg \end{svg}\includegraphics[width=3em]{young4}.

*** Output of to_latex *** In $SU(3)$, $ \includegraphics[width=2em]{young1} \otimes \includegraphics[width=1em]{young2} = \includegraphics[width=2em]{young3} \oplus \includegraphics[width=3em]{young4}$. maruku-0.7.2/spec/block_docs/math/math2.md0000644000004100000410000000355712347070213020407 0ustar www-datawww-data *** Parameters: *** require 'maruku/ext/math' {:math_numbered => ['\\['], :html_math_engine => 'itex2mml' } *** Markdown input: *** \[ \alpha \] \begin{equation} \alpha \end{equation} \begin{equation} \beta \end{equation} \begin{equation} \gamma \end{equation} *** Output of inspect *** md_el(:document,[ md_el(:equation,[],{:label=>"eq1",:math=>"\n\t\\alpha\n\n",:num=>1},[]), md_el(:equation,[],{:label=>nil,:math=>"\n\t\\alpha\n\n",:num=>nil},[]), md_el(:equation,[],{:label=>nil,:math=>" \\beta\n\n",:num=>nil},[]), md_el(:equation,[],{:label=>nil,:math=>" \\gamma ",:num=>nil},[]) ],{},[]) *** Output of to_html ***
(1)α \alpha
α \alpha
β \beta
γ \gamma
*** Output of to_latex *** \begin{equation} \alpha \label{eq1}\end{equation} \begin{displaymath} \alpha \end{displaymath} \begin{displaymath} \beta \end{displaymath} \begin{displaymath} \gamma \end{displaymath} *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/math/table.md0000644000004100000410000000165112347070213020454 0ustar www-datawww-dataWrite a comment here *** Parameters: *** require 'maruku/ext/math';{:html_math_engine => 'itex2mml' } *** Markdown input: *** $\alpha$
$\beta$
*** Output of inspect *** md_el(:document,[ md_html("\n\t$\\alpha$\n\t\n\t\t\n\t\n
$\\beta$
") ],{},[]) *** Output of to_html *** α\alpha
β\beta
*** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.2/spec/block_docs/issue90.md0000644000004100000410000000227212347070213017735 0ustar www-datawww-datahttps://github.com/bhollis/maruku/issues/90 - TOC not working without an H1 on the page. *** Parameters: *** {:use_numbered_headers => true} *** Markdown input: *** * Table of contents {:toc} ## First Heading Foo ## Second Heading ### Subheading Foobar *** Output of inspect *** md_el(:document,[ md_el(:ul, md_li("Table of contents", false), {}, [[:ref, "toc"]]), md_el(:header, "First Heading", {:level=>2}), md_par("Foo"), md_el(:header, "Second Heading", {:level=>2}), md_el(:header, "Subheading", {:level=>3}), md_par("Foobar") ],{},[]) *** Output of to_html ***

1. First Heading

Foo

2. Second Heading

2.1. Subheading

Foobar

maruku-0.7.2/spec/block_docs/html_inline.md0000644000004100000410000000121712347070213020734 0ustar www-datawww-dataJRUBY NOKOGIRI PENDING - Maruku should nest inline-level HTML inside a paragraph (JRuby Nokogiri is broken for empty tags: https://github.com/sparklemotion/nokogiri/issues/971) *** Parameters: *** {} # params *** Markdown input: *** One 123 123 123 *** Output of inspect *** md_el(:document,[ md_par(["One ", md_html(""), "123"]), md_par([md_html(""), "123"]), md_par([md_html(""), "123"]), md_html(""), ],{},[]) *** Output of to_html ***

One 123

123

123

maruku-0.7.2/spec/block_docs/issue67.md0000644000004100000410000000076512347070213017746 0ustar www-datawww-dataA span at the beginning of a list item shouldn't cause the other list elements to be wrapped in paragraphs or remove the inline element. https://github.com/bhollis/maruku/issues/67 *** Parameters: *** {} *** Markdown input: *** - One - Two - Three *** Output of inspect *** md_el(:document, md_el(:ul, [ md_li("One", false), md_li(md_html("Two"), false), md_li("Three", false) ])) *** Output of to_html ***
  • One
  • Two
  • Three
maruku-0.7.2/spec/block_docs/email.md0000644000004100000410000000205012347070213017515 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** This is an email address: Address: *** Output of inspect *** md_el(:document,[ md_par(["This is an email address: ", md_email("andrea@invalid.it")]), md_par(["Address: ", md_email("andrea@invalid.it")]) ],{},[]) *** Output of to_html ***

This is an email address: andrea@invalid.it

Address: andrea@invalid.it

*** Output of to_latex *** This is an email address: \href{mailto:andrea@invalid.it}{andrea\char64invalid\char46it} Address: \href{mailto:andrea@invalid.it}{andrea\char64invalid\char46it} *** Output of to_md *** This is an email address: Address: *** Output of to_s *** This is an email address: Address: maruku-0.7.2/spec/block_docs/issue31.md0000644000004100000410000000133112347070213017723 0ustar www-datawww-dataMarkdown should be processed inside span-level tags. https://github.com/bhollis/maruku/issues/31 *** Parameters: *** {} *** Markdown input: *** *hello*

*hello*

hello *there* hello *there* *** Output of inspect *** md_el(:document, [ md_par(md_html("*hello*")), md_html("

*hello*

"), md_par(md_html("hello *there*")), md_par(md_html("hello\n*there*")) ]) *** Output of to_html ***

hello

*hello*

hello there

hello there

maruku-0.7.2/spec/block_docs/html_trailing.md0000644000004100000410000000102212347070213021261 0ustar www-datawww-dataMarkdown should be processed trailing text after HTML *** Parameters: *** {} *** Markdown input: *** before ------ after

hello

*foo* done *** Output of inspect *** md_el(:document, [ md_par("before"), md_html(""), md_el(:hrule, []), md_par("after"), md_html("

hello

"), md_par(md_em("foo")), md_par("done") ]) *** Output of to_html ***

before


after

hello

foo

done

maruku-0.7.2/spec/block_docs/empty_cells.md0000644000004100000410000000174512347070213020760 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** | | 1 | 2 | |----|----|----| | A | X | | | B | | X | *** Output of inspect *** md_el(:document,[ md_el(:table,[ [md_el(:head_cell,[],{},[]),md_el(:head_cell,["1"],{},[]),md_el(:head_cell,["2"],{},[])], [md_el(:cell,["A"],{},[]),md_el(:cell,["X"],{},[]),md_el(:cell,[],{},[])], [md_el(:cell,["B"],{},[]),md_el(:cell,[],{},[]),md_el(:cell,["X"],{},[])] ],{:align=>[:left, :left, :left]},[]) ],{},[]) *** Output of to_html ***
12
AX
BX
*** Output of to_latex *** \begin{tabular}{l|l|l} &1&2\\ \hline A&X&\\ B&&X\\ \end{tabular} *** Output of to_md *** 12AXBX *** Output of to_s *** 12AXBX maruku-0.7.2/spec/block_docs/extra_dl.md0000644000004100000410000000354412347070213020241 0ustar www-datawww-dataDefinition lists - only Maruku and Kramdown support this syntax (and only Kramdown gets it right. *** Parameters: *** {:css=>"style.css"} *** Markdown input: *** CSS: style.css Apple : Pomaceous fruit of plants of the genus Malus in the family Rosaceae. Orange : The fruit of an evergreen tree of the genus Citrus. *** Output of inspect *** md_el(:document,[ md_el(:definition_list,[ md_el(:definition,[ md_el(:definition_term,["Apple"],{},[]), md_el(:definition_data,[ "Pomaceous fruit of plants of the genus Malus in the family Rosaceae." ],{},[]) ],{:definitions=>[md_el(:definition_data,[ "Pomaceous fruit of plants of the genus Malus in the family Rosaceae." ],{},[])],:terms=>[md_el(:definition_term,["Apple"],{},[])],:want_my_paragraph=>false},[]), md_el(:definition,[ md_el(:definition_term,["Orange"],{},[]), md_el(:definition_data,["The fruit of an evergreen tree of the genus Citrus."],{},[]) ],{:definitions=>[md_el(:definition_data,["The fruit of an evergreen tree of the genus Citrus."],{},[])],:terms=>[md_el(:definition_term,["Orange"],{},[])],:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***
Apple
Pomaceous fruit of plants of the genus Malus in the family Rosaceae.
Orange
The fruit of an evergreen tree of the genus Citrus.
*** Output of to_latex *** \begin{description} \item[Apple] Pomaceous fruit of plants of the genus Malus in the family Rosaceae. \item[Orange] The fruit of an evergreen tree of the genus Citrus. \end{description} *** Output of to_md *** ApplePomaceous fruit of plants of the genus Malus in the family Rosaceae.OrangeThe fruit of an evergreen tree of the genus Citrus. *** Output of to_s *** ApplePomaceous fruit of plants of the genus Malus in the family Rosaceae.OrangeThe fruit of an evergreen tree of the genus Citrus. maruku-0.7.2/spec/block_docs/lists.md0000644000004100000410000001723212347070213017574 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. Ancora * This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. ATTENZIONE! * Suspendisse id sem consectetuer libero luctus adipiscing. Ancora * This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list. *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[ "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus." ],{:want_my_paragraph=>false},[]), md_el(:li,[ "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing." ],{:want_my_paragraph=>false},[]), md_el(:li,[ "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing." ],{:want_my_paragraph=>false},[]), md_el(:li,[ "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing." ],{:want_my_paragraph=>false},[]), md_el(:li,[ "Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing." ],{:want_my_paragraph=>false},[]) ],{},[]), md_par(["Ancora"]), md_el(:ul,[ md_el(:li,[ md_par([ "This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus." ]), md_par(["ATTENZIONE!"]) ],{:want_my_paragraph=>true},[]), md_el(:li,[ md_par(["Suspendisse id sem consectetuer libero luctus adipiscing."]) ],{:want_my_paragraph=>false},[]) ],{},[]), md_par(["Ancora"]), md_el(:ul,[ md_el(:li,[ md_par(["This is a list item with two paragraphs."]), md_par([ "This is the second paragraph in the list item. You", md_entity("rsquo"), "re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit." ]) ],{:want_my_paragraph=>true},[]), md_el(:li,[md_par(["Another item in the same list."])],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***
  • Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
  • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
  • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
  • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.
  • Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.

Ancora

  • This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.

    ATTENZIONE!

  • Suspendisse id sem consectetuer libero luctus adipiscing.

Ancora

  • This is a list item with two paragraphs.

    This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

  • Another item in the same list.

*** Output of to_latex *** \begin{itemize}% \item Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. \item Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. \item Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. \item Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. \item Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. \end{itemize} Ancora \begin{itemize}% \item This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. ATTENZIONE! \item Suspendisse id sem consectetuer libero luctus adipiscing. \end{itemize} Ancora \begin{itemize}% \item This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \item Another item in the same list. \end{itemize} *** Output of to_md *** - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. - Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. - Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. - Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. - Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. Ancora - This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. ATTENZIONE! - Suspendisse id sem consectetuer libero luctus adipiscing. Ancora - This is a list item with two paragraphs. This is the second paragraph in the list item. You re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. - Another item in the same list. *** Output of to_s *** Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing.AncoraThis is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.ATTENZIONE!Suspendisse id sem consectetuer libero luctus adipiscing.AncoraThis is a list item with two paragraphs.This is the second paragraph in the list item. Youre only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Another item in the same list. maruku-0.7.2/spec/block_docs/issue85.md0000644000004100000410000000162012347070213017735 0ustar www-datawww-dataEscaped content in raw HTML. See https://github.com/bhollis/maruku/issues/85 *** Parameters: *** {} *** Markdown input: ***
#include <foo> “
Foo #include <foo> “ bar Foo #include <foo> “ bar *** Output of inspect *** md_el(:document, [md_html("
#include <foo> “
"), md_par([ "Foo ", md_html("#include <foo> “"), " bar"]), md_par([ "Foo ", md_html("#include <foo> “"), " bar"]) ]) *** Output of to_html ***
#include <foo> “

Foo #include <foo> “ bar

Foo #include <foo> “ bar

maruku-0.7.2/spec/block_docs/issue88.md0000644000004100000410000000065712347070213017751 0ustar www-datawww-dataHTML tags get chomped in list. See https://github.com/bhollis/maruku/issues/88 *** Parameters: *** {} *** Markdown input: *** hello 1. world *** Output of inspect *** md_el(:document, [md_par(md_html(" hello ")), md_el(:ol, md_li(md_html(" world "), false)) ]) *** Output of to_html ***

hello

  1. world
maruku-0.7.2/spec/block_docs/issue20.md0000644000004100000410000000045412347070213017726 0ustar www-datawww-dataJust an attribute list on its own in a header is probably really content. https://github.com/bhollis/maruku/issues/20 *** Parameters: *** {} *** Markdown input: *** # {hi} *** Output of inspect *** md_el(:document, md_el(:header, "{hi}", {:level=>1})) *** Output of to_html ***

{hi}

maruku-0.7.2/spec/block_docs/issue30.md0000644000004100000410000000113112347070213017720 0ustar www-datawww-dataList markers typically start at the left margin, but may be indented by up to three spaces. https://github.com/bhollis/maruku/issues/30 *** Parameters: *** {} *** Markdown input: *** This is a list: * a list And this: * still a list *** Output of inspect *** md_el(:document, [ md_par("This is a list:"), md_el(:ul, md_el(:li, "a list", {:want_my_paragraph=>false})), md_par("And this:"), md_el(:ul, md_el(:li, "still a list", {:want_my_paragraph=>false})) ]) *** Output of to_html ***

This is a list:

  • a list

And this:

  • still a list
maruku-0.7.2/spec/block_docs/list2.md0000644000004100000410000000333112347070213017466 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** * This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * other *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[ md_par(["This is a list item with two paragraphs."]), md_par([ "This is the second paragraph in the list item. You", md_entity("rsquo"), "re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit." ]) ],{:want_my_paragraph=>true},[]), md_el(:li,[md_par(["other"])],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***
  • This is a list item with two paragraphs.

    This is the second paragraph in the list item. You’re only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

  • other

*** Output of to_latex *** \begin{itemize}% \item This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \item other \end{itemize} *** Output of to_md *** -This is a list item with two paragraphs. This is the second paragraph in the list item. Youre only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. -ther *** Output of to_s *** This is a list item with two paragraphs.This is the second paragraph in the list item. Youre only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.other maruku-0.7.2/spec/block_docs/links2.md0000644000004100000410000000102612347070213017632 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** See [foo' bar][foo_bar] [foo_bar]: http://agorf.gr/ *** Output of inspect *** md_el(:document,[ md_par([ "See ", md_link(["foo", md_entity("rsquo"), " bar"],"foo_bar")]), md_ref_def("foo_bar", "http://agorf.gr/", {:title=>nil}) ],{},[]) *** Output of to_html ***

See foo’ bar

*** Output of to_latex *** See \href{http://agorf.gr/}{foo' bar} *** Output of to_md *** See foo bar *** Output of to_s *** See foo bar maruku-0.7.2/spec/block_docs/lists_nested_deep.md0000644000004100000410000000105412347070213022126 0ustar www-datawww-dataLists should be nestable to arbitrary depth. *** Parameters: *** {} *** Markdown input: *** * Space * Space * Space * Space * Space *** Output of inspect *** md_el(:document, [ md_el(:ul, md_li([ "Space", md_el(:ul, md_li([ "Space", md_el(:ul, md_li([ "Space", md_el(:ul, md_li(["Space", md_el(:ul, md_li("Space", false))], false)) ], false)) ], false)) ], false)) ]) *** Output of to_html ***
  • Space
    • Space
      • Space
        • Space
          • Space
maruku-0.7.2/spec/block_docs/lists12.md0000644000004100000410000000113512347070213017732 0ustar www-datawww-dataList Items with non alphanumeric content. https://github.com/bhollis/maruku/issues/1 *** Parameters: *** {} *** Markdown input: *** * A * ? * B *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,["A"],{:want_my_paragraph=>false},[]), md_el(:li,["?"],{:want_my_paragraph=>false},[]), md_el(:li,["B"],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***
  • A
  • ?
  • B
*** Output of to_latex *** \begin{itemize}% \item A \item ? \item B \end{itemize} *** Output of to_md *** - A - ? - B *** Output of to_s *** A?B maruku-0.7.2/spec/block_docs/triggering.md0000644000004100000410000000724412347070213020601 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** Paragraph, list with no space: * ciao Paragraph, list with 1 space: * ciao Paragraph, list with 3 space: * ciao Paragraph, list with 4 spaces: * ciao Paragraph, list with 1 tab: * ciao Paragraph (1 space after), list with no space: * ciao Paragraph (2 spaces after), list with no space: * ciao Paragraph (3 spaces after), list with no space: * ciao Paragraph with block quote: > Quoted Paragraph with header: ### header 1 ### Paragraph with header on two lines: header 2 -------- *** Output of inspect *** md_el(:document,[ md_par(["Paragraph, list with no space: * ciao"]), md_par(["Paragraph, list with 1 space: * ciao"]), md_par(["Paragraph, list with 3 space: * ciao"]), md_par(["Paragraph, list with 4 spaces: * ciao"]), md_par(["Paragraph, list with 1 tab: * ciao"]), md_par(["Paragraph (1 space after), list with no space: * ciao"]), md_par([ "Paragraph (2 spaces after), list with no space:", md_el(:linebreak,[],{},[]), "* ciao" ]), md_par([ "Paragraph (3 spaces after), list with no space: ", md_el(:linebreak,[],{},[]), "* ciao" ]), md_par(["Paragraph with block quote:"]), md_el(:quote,[md_par(["Quoted"])],{},[]), md_par(["Paragraph with header:"]), md_el(:header,["header 1"],{:level=>3},[]), md_par(["Paragraph with header on two lines:"]), md_el(:header,["header 2"],{:level=>2},[]) ],{},[]) *** Output of to_html ***

Paragraph, list with no space: * ciao

Paragraph, list with 1 space: * ciao

Paragraph, list with 3 space: * ciao

Paragraph, list with 4 spaces: * ciao

Paragraph, list with 1 tab: * ciao

Paragraph (1 space after), list with no space: * ciao

Paragraph (2 spaces after), list with no space:
* ciao

Paragraph (3 spaces after), list with no space:
* ciao

Paragraph with block quote:

Quoted

Paragraph with header:

header 1

Paragraph with header on two lines:

header 2

*** Output of to_latex *** Paragraph, list with no space: * ciao Paragraph, list with 1 space: * ciao Paragraph, list with 3 space: * ciao Paragraph, list with 4 spaces: * ciao Paragraph, list with 1 tab: * ciao Paragraph (1 space after), list with no space: * ciao Paragraph (2 spaces after), list with no space:\newline * ciao Paragraph (3 spaces after), list with no space: \newline * ciao Paragraph with block quote: \begin{quote}% Quoted \end{quote} Paragraph with header: \hypertarget{header_1}{}\subsubsection*{{header 1}}\label{header_1} Paragraph with header on two lines: \hypertarget{header_2}{}\subsection*{{header 2}}\label{header_2} *** Output of to_md *** Paragraph, list with no space: * ciao Paragraph, list with 1 space: * ciao Paragraph, list with 3 space: * ciao Paragraph, list with 4 spaces: * ciao Paragraph, list with 1 tab: * ciao Paragraph (1 space after), list with no space: * ciao Paragraph (2 spaces after), list with no space: * ciao Paragraph (3 spaces after), list with no space: * ciao Paragraph with block quote: > Quoted Paragraph with header: ### header Paragraph with header on two lines: ## header *** Output of to_s *** Paragraph, list with no space: * ciaoParagraph, list with 1 space: * ciaoParagraph, list with 3 space: * ciaoParagraph, list with 4 spaces: * ciaoParagraph, list with 1 tab: * ciaoParagraph (1 space after), list with no space: * ciaoParagraph (2 spaces after), list with no space:* ciaoParagraph (3 spaces after), list with no space: * ciaoParagraph with block quote:QuotedParagraph with header:headerParagraph with header on two lines:header maruku-0.7.2/lib/0000755000004100000410000000000012347070213013621 5ustar www-datawww-datamaruku-0.7.2/lib/maruku/0000755000004100000410000000000012347070213015125 5ustar www-datawww-datamaruku-0.7.2/lib/maruku/errors.rb0000644000004100000410000000445012347070213016771 0ustar www-datawww-datamodule MaRuKu class Exception < RuntimeError; end module Errors FRAME_WIDTH = 75 # Properly handles a formatting error. # All such errors go through this method. # # The behavior depends on {MaRuKu::Globals `MaRuKu::Globals[:on_error]`}. # If this is `:warning`, this prints the error to stderr # (or `@error_stream` if it's defined) and tries to continue. # If `:on_error` is `:ignore`, this doesn't print anything # and tries to continue. If it's `:raise`, this raises a {MaRuKu::Exception}. # # By default, `:on_error` is set to `:warning`. # # @overload def maruku_error(s, src = nil, con = nil) # @param s [String] The text of the error # @param src [#describe, nil] The source of the error # @param con [#describe, nil] The context of the error # @param recover [String, nil] Recovery text # @raise [MaRuKu::Exception] If `:on_error` is set to `:raise` def maruku_error(s, src=nil, con=nil, recover=nil) policy = get_setting(:on_error) case policy when :ignore when :raise raise_error create_frame(describe_error(s, src, con, recover)) when :warning tell_user create_frame(describe_error(s, src, con, recover)) else raise "Unknown on_error policy: #{policy.inspect}" end end # This is like {#maruku_error} but will never raise. def maruku_recover(s, src=nil, con=nil, recover=nil) policy = get_setting(:on_error) case policy when :ignore when :raise, :warning tell_user create_frame(describe_error(s, src, con, recover)) else raise "Unknown on_error policy: #{policy.inspect}" end end def raise_error(s) raise MaRuKu::Exception, s, caller end def tell_user(s) (self.attributes[:error_stream] || $stderr) << s << "\n" end private def create_frame(s) "\n" + <] attr_accessor :section_number # The `:header` node for this section. # The value of `meta[:section]` for the header will be this node. # # @return [MDElement] attr_accessor :header_element # The immediate child nodes of this section. # # @todo Why does this never contain Strings? # # @return [Array] attr_accessor :immediate_children # The subsections of this section. # # @return [Array
] attr_accessor :section_children def initialize @immediate_children = [] @section_children = [] end def inspect(indent = 1) if @header_element s = "\_" * indent << "(#{@section_level})>\t #{@section_number.join('.')} : " << @header_element.children_to_s << " (id: '#{@header_element.attributes[:id]}')\n" else s = "Master\n" end @section_children.each {|c| s << c.inspect(indent + 1) } s end # Assign \{#section\_number section numbers} # to this section and its children. # This also assigns the section number attribute # to the sections' headers. # # This should only be called on the root section. # # @overload def numerate def numerate(a = []) self.section_number = a self.section_children.each_with_index {|c, i| c.numerate(a + [i + 1])} if h = self.header_element h.attributes[:section_number] = self.section_number end end # Returns an HTML representation of the table of contents. # # This should only be called on the root section. def to_html MaRuKu::Out::HTML::HTMLElement.new('div', { 'class' => 'maruku_toc' }, _to_html) end # Returns a LaTeX representation of the table of contents. # # This should only be called on the root section. def to_latex _to_latex + "\n\n" end protected def _to_html ul = MaRuKu::Out::HTML::HTMLElement.new('ul') @section_children.each do |c| li = MaRuKu::Out::HTML::HTMLElement.new('li') if span = c.header_element.render_section_number li << span end a = c.header_element.wrap_as_element('a') a.attributes.delete('id') a['href'] = "##{c.header_element.attributes[:id]}" li << a li << c._to_html if c.section_children.size > 0 ul << li end ul end def _to_latex s = "" @section_children.each do |c| s << "\\noindent" if number = c.header_element.section_number s << number end id = c.header_element.attributes[:id] text = c.header_element.children_to_latex s << "\\hyperlink{#{id}}{#{text}}" s << "\\dotfill \\pageref*{#{id}} \\linebreak\n" s << c._to_latex if c.section_children.size > 0 end s end end class MDDocument # The table of contents for the document. # # @return [Section] attr_accessor :toc # A map of header IDs to a count of how many times they've occurred in the document. # # @return [Hash] attr_accessor :header_ids def create_toc self.header_ids = Hash.new(0) each_element(:header) {|h| h.attributes[:id] ||= h.generate_id } # The root section s = Section.new s.section_level = 0 stack = [s] i = 0 while i < @children.size if children[i].node_type == :header header = @children[i] level = header.level s2 = Section.new s2.section_level = level s2.header_element = header header.instance_variable_set :@section, s2 while level <= stack.last.section_level stack.pop end stack.last.section_children.push s2 stack.push s2 else stack.last.immediate_children.push @children[i] end i += 1 end # If there is only one big header, then assume # it is the master if s.section_children.size == 1 s = s.section_children.first end # Assign section numbers s.numerate s end end class MDElement # Generate an id for headers. Assumes @children is set. def generate_id raise "generate_id only makes sense for headers" unless node_type == :header generated_id = children_to_s.tr(' ', '_').downcase.gsub(/\W/, '').strip num_occurs = (@doc.header_ids[generated_id] += 1) generated_id += "_#{num_occurs}" if num_occurs > 1 generated_id end end end maruku-0.7.2/lib/maruku/textile2.rb0000644000004100000410000000005112347070213017206 0ustar www-datawww-datarequire 'maruku/input_textile2/t2_parser'maruku-0.7.2/lib/maruku/document.rb0000644000004100000410000000175712347070213017302 0ustar www-datawww-datamodule MaRuKu # This represents the whole document and holds global data. class MDDocument # < MDElement # @return [{String => {:url => String, :title => String}}] attr_accessor :refs # @return [{String => MDElement}] attr_accessor :footnotes # @return [{String => String}] attr_accessor :abbreviations # Attribute definition lists. # # @return [{String => AttributeList}] attr_accessor :ald # The order in which footnotes are used. Contains the id. # # @return [Array] attr_accessor :footnotes_order # @return [{String => {String => MDElement}}] attr_accessor :refid2ref # A counter for generating unique IDs [Integer] attr_accessor :id_counter def initialize(s=nil) super(:document) self.doc = self self.refs = {} self.footnotes = {} self.footnotes_order = [] self.abbreviations = {} self.ald = {} self.id_counter = 0 parse_doc(s) if s end end end maruku-0.7.2/lib/maruku/string_utils.rb0000644000004100000410000000717012347070213020205 0ustar www-datawww-datarequire 'strscan' module MaRuKu # Utility functions for dealing with strings. module Strings TAB_SIZE = 4 # Split a string into multiple lines, # on line feeds and/or carriage returns. # # @param s [String] # @return [String] def split_lines(s) s.split(/\r\n|\r|\n/) end # Parses email headers, returning a hash. # `hash[:data]` is the message; # that is, anything past the headers. # # Keys are downcased and converted to symbols; # spaces become underscores. For example: # # !!!plain # My key: true # # becomes: # # {:my_key => true} # # @param s [String] The email # @return [Symbol => String] The header values def parse_email_headers(s) headers = {} scanner = StringScanner.new(s) while scanner.scan(/(\w[\w\s\-]+): +(.*)\n/) k, v = normalize_key_and_value(scanner[1], scanner[2]) headers[k.to_sym] = v end headers[:data] = scanner.rest headers end # This returns the position of the first non-list character # in a list item. # # @example # spaces_before_first_char('*Hello') #=> 1 # spaces_before_first_char('* Hello') #=> 2 # spaces_before_first_char(' * Hello') #=> 3 # spaces_before_first_char(' * Hello') #=> 5 # spaces_before_first_char('1.Hello') #=> 2 # spaces_before_first_char(' 1. Hello') #=> 5 # # @param s [String] # @return [Fixnum] def spaces_before_first_char(s) s = MaRuKu::MDLine.new(s.gsub(/([^\t]*)(\t)/) { $1 + " " * (TAB_SIZE - $1.length % TAB_SIZE) }) match = case s.md_type when :ulist # whitespace, followed by ('*'|'+'|'-') followed by # more whitespace, followed by an optional IAL, followed # by yet more whitespace s[/^\s*(\*|\+|\-)\s*(\{[:#\.].*?\})?\s*/] when :olist # whitespace, followed by a number, followed by a period, # more whitespace, an optional IAL, and more whitespace s[/^\s*\d+\.\s*(\{[:#\.].*?\})?\s*/] else tell_user "BUG (my bad): '#{s}' is not a list" '' end f = /\{(.*?)\}/.match(match) ial = f[1] if f [match.length, ial] end # Normalize a link reference. # # @param s [String] # @return [String] def sanitize_ref_id(s) s.downcase.gsub(/\s+/, ' ') end # Remove line-initial `>` characters for a quotation. # # @param s [String] # @return [String] def unquote(s) s.gsub(/^>\s?/, '') end # Removes indentation from the beginning of `s`, # up to at most `n` spaces. # Tabs are counted as {TAB_SIZE} spaces. # # @param s [String] # @param n [Fixnum] # @return [String] def strip_indent(s, n) while n > 0 case s[0, 1] when ' ' n -= 1 when "\t" n -= TAB_SIZE else break end s = s[1..-1] end MDLine.new(s) end private # Normalize the key/value pairs for email headers. # Keys are downcased and converted to symbols; # spaces become underscores. # # Values of `"yes"`, `"true"`, `"no"`, and `"false"` # are converted to appropriate booleans. # # @param k [String] # @param v [String] # @return [Array(String, String or Boolean)] def normalize_key_and_value(k, v) k = k.strip.downcase.gsub(/\s+/, '_').to_sym v = v.strip # check synonyms return k, true if %w[yes true].include?(v.downcase) return k, false if %w[no false].include?(v.downcase) return k, v end end end maruku-0.7.2/lib/maruku/defaults.rb0000644000004100000410000000216212347070213017262 0ustar www-datawww-datamodule MaRuKu Globals = { :unsafe_features => false, :on_error => :warning, :use_numbered_headers => false, :maruku_signature => false, :code_background_color => '#fef', :code_show_spaces => false, :filter_html => false, :html_parser => 'rexml', # or 'nokogiri' :html_math_output_mathml => true, # also set :html_math_engine :html_math_engine => 'none', # none, ritex, itex2mml, blahtex :html_math_output_png => false, :html_png_engine => 'none', :html_png_dir => 'pngs', :html_png_url => 'pngs/', :html_png_resolution => 200, :fenced_code_blocks => false, :html_use_syntax => false, :latex_use_listings => false, :latex_cjk => false, :debug_keep_ials => false, :doc_prefix => '', :ignore_wikilinks => true } class MDElement def get_setting(sym) return attributes[sym] if attributes.has_key?(sym) return doc.attributes[sym] if doc && doc.attributes.has_key?(sym) return MaRuKu::Globals[sym] if MaRuKu::Globals.has_key?(sym) $stderr.puts "Bug: no default for #{sym.inspect}" nil end end end maruku-0.7.2/lib/maruku/helpers.rb0000644000004100000410000001054112347070213017115 0ustar www-datawww-datarequire 'maruku/html' module MaRuKu # A collection of helper functions for creating Markdown elements. # They hide the particular internal representations. # # Always use these rather than creating an {MDElement} directly. module Helpers # @param children [MDElement, String, Array] # The child nodes. # If the first child is a \{#md\_ial}, it's merged with `al` def md_el(node_type, children=[], meta={}, al=nil) children = Array(children) first = children.first if first && first.is_a?(MDElement) && first.node_type == :ial if al al += first.ial else al = first.ial end children.shift end e = MDElement.new(node_type, children, meta, al) e.doc = @doc e end def md_header(level, children, al=nil) md_el(:header, children, { :level => level }, al) end # Inline code def md_code(code, al=nil) md_el(:inline_code, [], { :raw_code => code }, al) end # Code block def md_codeblock(source, lang=nil, al=nil) md_el(:code, [], { :raw_code => source, :lang => lang }, al) end def md_quote(children, al=nil) md_el(:quote, children, {}, al) end def md_li(children, want_my_par=false, al=nil) md_el(:li, children, { :want_my_paragraph => want_my_par }, al) end def md_footnote(footnote_id, children, al=nil) md_el(:footnote, children, { :footnote_id => footnote_id }, al) end def md_abbr_def(abbr, text, al=nil) md_el(:abbr_def, [], { :abbr => abbr, :text => text }, al) end def md_abbr(abbr, title) md_el(:abbr, abbr, :title => title) end def md_html(raw_html, al=nil) e = MDHTMLElement.new(:raw_html, [], :raw_html => raw_html) e.doc = @doc begin # Set this as an attribute so it doesn't get included # in metadata comparisons e.parsed_html = MaRuKu::HTMLFragment.new(raw_html) rescue => ex maruku_recover "Maruku cannot parse this block of HTML/XML:\n" + raw_html.gsub(/^/, '|').rstrip + "\n" + ex.to_s end e end def md_link(children, ref_id, al=nil) md_el(:link, children, { :ref_id => ref_id }, al) end def md_im_link(children, url, title = nil, al=nil) md_el(:im_link, children, { :url => url, :title => title }, al) end def md_image(children, ref_id, al=nil) md_el(:image, children, { :ref_id => ref_id }, al) end def md_im_image(children, url, title=nil, al=nil) md_el(:im_image, children, { :url => url, :title => title }, al) end def md_em(children, al=nil) md_el(:emphasis, children, {}, al) end def md_br md_el(:linebreak, [], {}, nil) end def md_hrule md_el(:hrule, [], {}, nil) end def md_strong(children, al=nil) md_el(:strong, children, {}, al) end def md_emstrong(children, al=nil) md_strong(md_em(children), al) end # A URL to be linkified (e.g. ``). def md_url(url, al=nil) md_el(:immediate_link, [], { :url => url }, al) end # An email to be linkified # (e.g. `` or ``). def md_email(email, al=nil) md_el(:email_address, [], { :email => email }, al) end def md_entity(entity_name, al=nil) md_el(:entity, [], { :entity_name => entity_name }, al) end # Markdown extra def md_foot_ref(ref_id, al=nil) md_el(:footnote_reference, [], { :footnote_id => ref_id }, al) end def md_par(children, al=nil) md_el(:paragraph, children, {}, al) end # A definition of a reference (e.g. `[1]: http://url [properties]`). def md_ref_def(ref_id, url, title=nil, meta={}, al=nil) all_meta = meta.merge({ :url => url, :ref_id => ref_id }) all_meta[:title] ||= title md_el(:ref_definition, [], all_meta, al) end # inline attribute list def md_ial(al) al = Maruku::AttributeList.new(al) unless al.is_a?(Maruku::AttributeList) md_el(:ial, [], :ial => al) end # Attribute list definition def md_ald(id, al) md_el(:ald, [], :ald_id => id, :ald => al) end # A server directive (e.g. ``) def md_xml_instr(target, code) md_el(:xml_instr, [], :target => target, :code => code) end end end maruku-0.7.2/lib/maruku/version.rb0000644000004100000410000000145112347070213017140 0ustar www-datawww-datamodule MaRuKu # The Maruku version. VERSION = '0.7.2' # @deprecated Exists for backwards compatibility. Use {VERSION} # @private Version = VERSION # The URL of the Maruku website. MARUKU_URL = 'http://github.com/bhollis/maruku/' # @deprecated Exists for backwards compatibility. Use {MARUKU_URL} # @private MarukuURL = MARUKU_URL # Whether Markdown implements the PHP Markdown extra syntax. # # Note: it is not guaranteed that if this is false, # then no special features will be used. # # @return [Boolean] def markdown_extra? true end # Whether Markdown implements the new meta-data proposal. # # Note: it is not guaranteed that if this is false, # then no special features will be used. # # @return [Boolean] def new_meta_data? true end end maruku-0.7.2/lib/maruku/input/0000755000004100000410000000000012347070213016264 5ustar www-datawww-datamaruku-0.7.2/lib/maruku/input/mdline.rb0000644000004100000410000001054612347070213020067 0ustar www-datawww-data# This code does the classification of lines for block-level parsing. module MaRuKu # Represents a single line in a Markdown source file, as produced by # LineSource. class MDLine < String def md_type @md_type ||= line_md_type end # Returns the number of leading spaces on this string, # considering that a tab counts as {MaRuKu::Strings::TAB_SIZE} spaces. # # @param s [String] # @return [Fixnum] def number_of_leading_spaces if self =~ /\A\s+/ spaces = $& spaces.count(" ") + spaces.count("\t") * MaRuKu::Strings::TAB_SIZE else 0 end end def gsub!(*args) # Any in-place-modification method should reset the md_type @md_type = nil super end private def line_md_type # The order of evaluation is important (:text is a catch-all) return :text if self =~ /\A[a-zA-Z]/ return :empty if self =~ /\A\s*\z/ return :footnote_text if self =~ FootnoteText return :ref_definition if self =~ LinkRegex || self =~ IncompleteLink return :abbreviation if self =~ Abbreviation return :definition if self =~ Definition # I had a bug with emails and urls at the beginning of the # line that were mistaken for raw_html return :text if self =~ /\A[ ]{0,3}#{EMailAddress}/ return :text if self =~ /\A[ ]{0,3}<\w+:\/\// # raw html is like PHP Markdown Extra: at most three spaces before return :xml_instr if self =~ /\A\s*<\?/ return :raw_html if self =~ %r{\A[ ]{0,3}= 4 return :quote if self =~ /\A>/ return :ald if self =~ AttributeDefinitionList return :ial if self =~ InlineAttributeList return :text # else, it's just text end end # MacRuby has trouble with commented regexes, so just put the expanded form # in a comment. # $1 = id $2 = attribute list AttributeDefinitionList = /\A\s{0,3}\{([\w\s]+)\}:\s*(.*?)\s*\z/ # InlineAttributeList = /\A\s{0,3}\{([:#\.].*?)\}\s*\z/ # Example: # ^:blah blah # ^: blah blah # ^ : blah blah Definition = /\A[ ]{0,3}:\s*(\S.*)\z/ # %r{ # ^ # begin of line # [ ]{0,3} # up to 3 spaces # : # colon # \s* # whitespace # (\S.*) # the text = $1 # $ # end of line # }x # Example: # *[HTML]: Hyper Text Markup Language Abbreviation = /\A[ ]{0,3}\*\[([^\]]+)\]:\s*(\S.*\S)*\s*\z/ # %r{ # ^ # begin of line # [ ]{0,3} # up to 3 spaces # \* # one asterisk # \[ # opening bracket # ([^\]]+) # any non-closing bracket: id = $1 # \] # closing bracket # : # colon # \s* # whitespace # (\S.*\S)* # definition=$2 # \s* # strip this whitespace # $ # end of line # }x FootnoteText = /\A[ ]{0,3}\[(\^.+)\]:\s*(\S.*)?\z/ # %r{ # ^ # begin of line # [ ]{0,3} # up to 3 spaces # \[(\^.+)\]: # id = $1 (including '^') # \s*(\S.*)?$ # text = $2 (not obb.) # }x # This regex is taken from BlueCloth sources # Link defs are in the form: ^[id]: \n? url "optional title" LinkRegex = /\A[ ]{0,3}\[([^\[\]]+)\]:[ ]*\s]+)>?[ ]*(?:(?:(?:"([^"]+)")|(?:'([^']+)')|(?:\(([^\(\)]+)\)))\s*(.+)?)?/ #%r{ # ^[ ]{0,3}\[([^\[\]]+)\]: # id = $1 # [ ]* # \s]+)>? # url = $2 # [ ]* # (?: # Titles are delimited by "quotes" or (parens). # (?:(?:"([^"]+)")|(?:'([^']+)')|(?:\(([^\(\)]+)\))) # title = $3, $4, or $5 # \s*(.+)? # stuff = $6 # )? # title is optional #}x IncompleteLink = /\A[ ]{0,3}\[([^\[\]]+?)\]:\s*\z/ # Table syntax: http://michelf.ca/projects/php-markdown/extra/#table # | -------------:| ------------------------------ | TableSeparator = /\A(?>\|?\s*\:?\-+\:?\s*\|?)+?\z/ EMailAddress = /<([^:@>]+?@[^:@>]+?)>/ end maruku-0.7.2/lib/maruku/input/charsource.rb0000644000004100000410000001465412347070213020761 0ustar www-datawww-datarequire 'strscan' module MaRuKu::In::Markdown::SpanLevelParser # a string scanner coded by me class CharSourceManual; end # a wrapper around StringScanner class CharSourceStrscan; end # A debug scanner that checks the correctness of both # by comparing their output class CharSourceDebug; end # Choose! CharSource = CharSourceManual # faster! 58ms vs. 65ms #CharSource = CharSourceStrscan # Faster on LONG documents. But StringScanner is buggy in Rubinius #CharSource = CharSourceDebug class CharSourceManual def initialize(s, parent=nil) raise "Passed #{s.class}" if not s.kind_of? String @buffer = s @buffer_index = 0 @parent = parent end # Return current char as a String (or nil). def cur_char cur_chars(1) end # Return the next n chars as a String. def cur_chars(n) return nil if @buffer_index >= @buffer.size @buffer[@buffer_index, n] end # Return the char after current char as a String (or nil). def next_char return nil if @buffer_index + 1 >= @buffer.size @buffer[@buffer_index + 1, 1] end def shift_char c = cur_char @buffer_index += 1 c end def ignore_char @buffer_index += 1 end def ignore_chars(n) @buffer_index += n end def current_remaining_buffer @buffer[@buffer_index, @buffer.size - @buffer_index] end def cur_chars_are(string) cur_chars(string.size) == string end def next_matches(r) r2 = /^.{#{@buffer_index}}#{r}/m r2.match @buffer end def read_regexp(r) r2 = /^#{r}/ rest = current_remaining_buffer m = r2.match(rest) if m @buffer_index += m.to_s.size end m end def consume_whitespace while c = cur_char break unless (c == ' ' || c == "\t") ignore_char end end def describe s = describe_pos(@buffer, @buffer_index) if @parent s += "\n\n" + @parent.describe end s end def describe_pos(buffer, buffer_index) len = 75 num_before = [len/2, buffer_index].min num_after = [len/2, buffer.size - buffer_index].min num_before_max = buffer_index num_after_max = buffer.size - buffer_index num_before = [num_before_max, len - num_after].min num_after = [num_after_max, len - num_before].min index_start = [buffer_index - num_before, 0].max index_end = [buffer_index + num_after, buffer.size].min size = index_end - index_start str = buffer[index_start, size] str.gsub!("\n", 'N') str.gsub!("\t", 'T') if index_end == buffer.size str += "EOF" end pre_s = buffer_index - index_start pre_s = [pre_s, 0].max pre_s2 = [len - pre_s, 0].max pre = " " * pre_s "-" * len + "\n" + str + "\n" + "-" * pre_s + "|" + "-" * pre_s2 + "\n" + pre + "+--- Byte #{buffer_index}\n"+ "Shown bytes [#{index_start} to #{size}] of #{buffer.size}:\n"+ buffer.gsub(/^/, ">") end end class CharSourceStrscan def initialize(s, parent=nil) @scanner = StringScanner.new(s) @size = s.size end # Return current char as a String (or nil). def cur_char @scanner.peek(1)[0] end # Return the next n chars as a String. def cur_chars(n) @scanner.peek(n) end # Return the char after current char as a String (or nil). def next_char @scanner.peek(2)[1] end # Return a character as a String, advancing the pointer. def shift_char @scanner.getch[0] end # Advance the pointer def ignore_char @scanner.getch end # Advance the pointer by n def ignore_chars(n) n.times { @scanner.getch } end # Return the rest of the string def current_remaining_buffer @scanner.rest end # Returns true if string matches what we're pointing to def cur_chars_are(string) @scanner.peek(string.size) == string end # Returns true if Regexp r matches what we're pointing to def next_matches(r) @scanner.check(r) end def read_regexp(r) r.match(@scanner.scan(r)) end def consume_whitespace @scanner.skip(/\s+/) end def describe len = 75 num_before = [len/2, @scanner.pos].min num_after = [len/2, @scanner.rest_size].min num_before_max = @scanner.pos num_after_max = @scanner.rest_size num_before = [num_before_max, len - num_after].min num_after = [num_after_max, len - num_before].min index_start = [@scanner.pos - num_before, 0].max index_end = [@scanner.pos + num_after, @size].min size = index_end - index_start str = @scanner.string[index_start, size] str.gsub!("\n", 'N') str.gsub!("\t", 'T') if index_end == @size str += "EOF" end pre_s = @scanner.pos - index_start pre_s = [pre_s, 0].max pre_s2 = [len-pre_s, 0].max pre = " " * pre_s "-" * len + "\n" + str + "\n" + "-" * pre_s + "|" + "-" * pre_s2 + "\n" + pre + "+--- Byte #{@scanner.pos}\n" + "Shown bytes [#{index_start} to #{size}] of #{@size}:\n" + @scanner.string.gsub(/^/, ">") end end class CharSourceDebug def initialize(s, parent) @a = CharSourceManual.new(s, parent) @b = CharSourceStrscan.new(s, parent) end def method_missing(methodname, *args) a_bef = @a.describe b_bef = @b.describe a = @a.send(methodname, *args) b = @b.send(methodname, *args) if a.kind_of? MatchData if a.to_a != b.to_a puts "called: #{methodname}(#{args})" puts "Matchdata:\na = #{a.to_a.inspect}\nb = #{b.to_a.inspect}" puts "AFTER: " + @a.describe puts "AFTER: " + @b.describe puts "BEFORE: " + a_bef puts "BEFORE: " + b_bef puts caller.join("\n") exit end else if a != b puts "called: #{methodname}(#{args})" puts "Attenzione!\na = #{a.inspect}\nb = #{b.inspect}" puts "" + @a.describe puts "" + @b.describe puts caller.join("\n") exit end end if @a.cur_char != @b.cur_char puts "Fuori sincronia dopo #{methodname}(#{args})" puts "" + @a.describe puts "" + @b.describe exit end return a end end end maruku-0.7.2/lib/maruku/input/linesource.rb0000644000004100000410000000365012347070213020765 0ustar www-datawww-datamodule MaRuKu::In::Markdown::BlockLevelParser # This represents a source of lines that can be consumed. # # It is the twin of CharSource. # class LineSource attr_reader :parent def initialize(lines, parent=nil, parent_offset=nil) raise "NIL lines? " unless lines @lines = lines.map {|l| l.kind_of?(MaRuKu::MDLine) ? l : MaRuKu::MDLine.new(l) } @lines_index = 0 @parent = parent @parent_offset = parent_offset end def cur_line @lines[@lines_index] end def next_line @lines[@lines_index + 1] end def shift_line raise "Over the rainbow" if @lines_index >= @lines.size l = @lines[@lines_index] @lines_index += 1 l end def ignore_line raise "Over the rainbow" if @lines_index >= @lines.size @lines_index += 1 end def describe s = "At line #{original_line_number(@lines_index)}\n" context = 3 # lines from = [@lines_index - context, 0].max to = [@lines_index + context, @lines.size - 1].min from.upto(to) do |i| prefix = (i == @lines_index) ? '--> ' : ' '; l = @lines[i] s += "%10s %4s|%s" % [@lines[i].md_type.to_s, prefix, l] s += "|\n" end s end def original_line_number(index) if @parent index + @parent.original_line_number(@parent_offset) else 1 + index end end def cur_index @lines_index end # Returns the type of next line as a string # breaks at first :definition def tell_me_the_future s = "" num_e = 0 @lines_index.upto(@lines.size - 1) do |i| c = case @lines[i].md_type when :text; "t" when :empty; num_e += 1; "e" when :definition; "d" else "o" end s << c break if c == "d" or num_e > 1 end s end end # linesource end maruku-0.7.2/lib/maruku/input/parse_span.rb0000644000004100000410000005150612347070213020753 0ustar www-datawww-datamodule MaRuKu::In::Markdown::SpanLevelParser include MaRuKu::Helpers EscapedCharInText = '\\`*_{}[]()#.!|:+->'.split(//) EscapedCharInQuotes = EscapedCharInText + ["'", '"'] EscapedCharInInlineCode = ['\\', '`'] IgnoreWikiLinks = MaRuKu::Globals[:ignore_wikilinks] def parse_span(string, parent=nil) string = Array(string).join("\n") unless string.kind_of? String src = MaRuKu::In::Markdown::SpanLevelParser::CharSource.new(string, parent) read_span(src, EscapedCharInText, [nil]) end # This is the main loop for reading span elements # # It's long, but not *complex* or difficult to understand. # # def read_span(src, escaped, exit_on_chars=nil, exit_on_strings=nil) escaped = Array(escaped) con = SpanContext.new dquote_state = squote_state = :closed c = d = prev_char = nil while true c = src.cur_char # This is only an optimization which cuts 50% of the time used. # (but you can't use a-zA-z in exit_on_chars) if c && c =~ /[[:alnum:]]/ con.push_char src.shift_char prev_char = c next end break if Array(exit_on_chars).include?(c) if Array(exit_on_strings).any? {|x| src.cur_chars_are x } # Special case: bold nested in italic break unless !(['*', '_'] & Array(exit_on_strings)).empty? && ['**', '__'].include?(src.cur_chars(2)) && !['***', '___'].include?(src.cur_chars(3)) end # check if there are extensions next if check_span_extensions(src, con) case c = src.cur_char when ' ' if src.cur_chars_are " \n" src.ignore_chars(3) con.push_element md_br prev_char = ' ' next elsif src.cur_chars_are ' >>' # closing guillemettes src.ignore_chars(3) con.push_element md_entity('nbsp') con.push_element md_entity('raquo') elsif src.cur_chars(5) =~ / '\d\ds/ # special case: '80s src.ignore_chars(2) con.push_space con.push_element md_entity('rsquo') elsif src.cur_chars_are " '" # opening single-quote src.ignore_chars(2) con.push_space con.push_element md_entity('lsquo') squote_state = :open else src.ignore_char con.push_space end when "\n", "\t" src.ignore_char con.push_space when '`' read_inline_code(src, con) when '<' # It could be: # 1) HTML "
> case d = src.next_char when '<' # guillemettes if src.cur_chars_are '<< ' src.ignore_chars(3) con.push_element md_entity('laquo') con.push_element md_entity('nbsp') else src.ignore_chars(2) con.push_element md_entity('laquo') end when '!' if src.cur_chars_are '} TO_SANITIZE = ['img', 'hr', 'br'] attr_reader :rest, :first_tag def initialize @rest = "" @tag_stack = [] @m = nil @already = "" self.state = :inside_element end attr_accessor :state # = :inside_element, :inside_tag, :inside_comment, :inside_cdata def eat_this(line) @rest = line + @rest things_read = 0 until @rest.empty? case self.state when :inside_comment if @m = CommentEnd.match(@rest) debug_state 'Comment End' # Workaround for https://bugs.ruby-lang.org/issues/9277 and another bug in 1.9.2 where even a # single dash in a comment will cause REXML to error. @already << @m.pre_match.gsub(/-(?![^\-])/, '- ') << @m.to_s @rest = @m.post_match self.state = :inside_element else @already << @rest.gsub(/-(?![^\-])/, '- ') # Workaround for https://bugs.ruby-lang.org/issues/9277 @rest = "" self.state = :inside_comment end when :inside_element if @m = CommentStart.match(@rest) debug_state 'Comment' things_read += 1 @already << @m.pre_match << @m.to_s @rest = @m.post_match self.state = :inside_comment elsif @m = Tag.match(@rest) debug_state 'Tag' things_read += 1 self.state = :inside_element handle_tag elsif @m = CData.match(@rest) debug_state 'CDATA' @already << @m.pre_match close_script_style if script_style? @already << @m.to_s @rest = @m.post_match self.state = :inside_cdata elsif @m = PartialTag.match(@rest) debug_state 'PartialTag' @already << @m.pre_match @rest = @m.post_match @partial_tag = @m.to_s self.state = :inside_tag elsif @m = EverythingElse.match(@rest) debug_state 'EverythingElse' @already << @m.pre_match << @m.to_s @rest = @m.post_match self.state = :inside_element else error "Malformed HTML: not complete: #{@rest.inspect}" end when :inside_tag if @m = /^[^>]*>/.match(@rest) @partial_tag << @m.to_s @rest = @partial_tag + @m.post_match @partial_tag = nil self.state = :inside_element if @m = Tag.match(@rest) things_read += 1 handle_tag end else @partial_tag << @rest @rest = "" self.state = :inside_tag end when :inside_cdata if @m = CDataEnd.match(@rest) self.state = :inside_element @already << @m.pre_match << @m.to_s @rest = @m.post_match start_script_style if script_style? else @already << @rest @rest = "" self.state = :inside_cdata end else raise "Bug bug: state = #{self.state.inspect}" end break if is_finished? && things_read > 0 end end def handle_tag @already << @m.pre_match @rest = @m.post_match is_closing = !!@m[1] tag = @m[2] @first_tag ||= tag attributes = @m[3].to_s is_single = false if attributes[-1, 1] == '/' attributes = attributes[0, attributes.size - 1] is_single = true end if TO_SANITIZE.include? tag attributes.strip! if attributes.size > 0 @already << '<%s %s />' % [tag, attributes] else @already << '<%s />' % [tag] end elsif is_closing if @tag_stack.empty? error "Malformed: closing tag #{tag.inspect} in empty list" elsif @tag_stack.last != tag error "Malformed: tag <#{tag}> closes <#{@tag_stack.last}>" end close_script_style if script_style? @already << @m.to_s @tag_stack.pop else @already << @m.to_s @tag_stack.push(tag) unless is_single start_script_style if script_style? end end def stuff_you_read @already end def is_finished? self.state == :inside_element && @tag_stack.empty? end private def debug_state(note) my_debug "#{@state}: #{note}: #{@m.to_s.inspect}" end def my_debug(s) # puts "---" * 10 + "\n" + inspect + "\t>>>\t" + s end def error(s) raise "Error: #{s} \n" + inspect, caller end def inspect "HTML READER\n state=#{self.state} " + "match=#{@m.to_s.inspect}\n" + "Tag stack = #{@tag_stack.inspect} \n" + "Before:\n" + @already.gsub(/^/, '|') + "\n" + "After:\n" + @rest.gsub(/^/, '|') + "\n" end # Script and style tag handling # ----------------------------- # # XHTML, and XML parsers like REXML, require that certain characters be # escaped within script or style tags. However, there are conflicts between # documents served as XHTML vs HTML. So we need to be extra careful about # how we escape these tags so they will even parse correctly. However, we # also try to avoid adding that escaping unnecessarily. # # See http://dorward.me.uk/www/comments-cdata/ for a good explanation. # Are we within a script or style tag? def script_style? %w(script style).include?(@tag_stack.last) end # Save our @already buffer elsewhere, and switch to using @already for the # contents of this script or style tag. def start_script_style @before_already, @already = @already, "" end # Finish script or style tag content, wrapping it in CDATA if necessary, # and add it to our original @already buffer. def close_script_style tag = @tag_stack.last # See http://www.w3.org/TR/xhtml1/#C_4 for character sequences not allowed within an element body. if @already =~ /<|&|\]\]>|--/ new_already = script_style_cdata_start(tag) new_already << "\n" unless @already.start_with?("\n") new_already << @already new_already << "\n" unless @already.end_with?("\n") new_already << script_style_cdata_end(tag) @already = new_already end @before_already << @already @already = @before_already end def script_style_cdata_start(tag) (tag == 'script') ? "//" : "/*]]>*/" end end end maruku-0.7.2/lib/maruku/input/extensions.rb0000644000004100000410000000272712347070213021020 0ustar www-datawww-datamodule MaRuKu::In::Markdown # Hash Fixnum -> name SpanExtensionsTrigger = {} class SpanExtension # trigging chars attr_accessor :chars # trigging regexp attr_accessor :regexp # lambda attr_accessor :block end # Hash String -> Extension SpanExtensions = {} def check_span_extensions(src, con) c = src.cur_char if extensions = SpanExtensionsTrigger[c] extensions.each do |e| if e.regexp && src.next_matches(e.regexp) return true if e.block.call(doc, src, con) end end end false # not special end def self.register_span_extension(args) e = SpanExtension.new e.chars = [*args[:chars]] e.regexp = args[:regexp] e.block = args[:handler] || raise("No blocks passed") e.chars.each do |c| (SpanExtensionsTrigger[c] ||= []).push e end end def self.register_block_extension(args) regexp = args[:regexp] BlockExtensions[regexp] = (args[:handler] || raise("No blocks passed")) end # Hash Regexp -> Block BlockExtensions = {} def check_block_extensions(src, con, line) BlockExtensions.each do |reg, block| if reg.match(line) block = BlockExtensions[reg] accepted = block.call(doc, src, con) return true if accepted end end false # not special end def any_matching_block_extension?(line) BlockExtensions.each_key do |reg| m = reg.match(line) return m if m end false end end maruku-0.7.2/lib/maruku/input/parse_doc.rb0000644000004100000410000001025612347070213020554 0ustar www-datawww-datarequire 'strscan' require 'cgi' module MaRuKu::In::Markdown::BlockLevelParser def parse_doc(s) # Remove BOM if it is present s = s.sub(/^\xEF\xBB\xBF/u, '') meta2 = parse_email_headers(s) data = meta2.delete :data self.attributes.merge! meta2 =begin maruku_doc Attribute: encoding Scope: document Summary: Encoding for the document. If the `encoding` attribute is specified, then the content will be converted from the specified encoding to UTF-8. =end enc = self.attributes.delete(:encoding) || 'utf-8' if enc.downcase != 'utf-8' # Switch to ruby 1.9 String#encode # with backward 1.8 compatibility if data.respond_to?(:encode!) data.encode!('UTF-8', enc) else require 'iconv' data = Iconv.new('utf-8', enc).iconv(data) end end @children = parse_text_as_markdown(data) if markdown_extra? self.search_abbreviations self.substitute_markdown_inside_raw_html end self.toc = create_toc # use title if not set self.attributes[:title] ||= toc.header_element.children.join if toc.header_element # Now do the attributes magic each_element do |e| # default attribute list if default = self.ald[e.node_type.to_s] expand_attribute_list(default, e.attributes) end expand_attribute_list(e.al, e.attributes) # puts "#{e.node_type}: #{e.attributes.inspect}" end =begin maruku_doc Attribute: unsafe_features Scope: global Summary: Enables execution of XML instructions. Disabled by default because of security concerns. =end if Maruku::Globals[:unsafe_features] self.execute_code_blocks # TODO: remove executed code blocks end end # Expands an attribute list in an Hash def expand_attribute_list(al, result) al.each do |k, v| case k when :class if result[:class] result[:class] << " " << v else result[:class] = v end when :id result[:id] = v when :ref if self.ald[v] already = (result[:expanded_references] ||= []) if !already.include?(v) already << v expand_attribute_list(self.ald[v], result) else already << v maruku_error "Circular reference between labels.\n\n" + "Label #{v.inspect} calls itself via recursion.\nThe recursion is " + already.map(&:inspect).join(' => ') end else if result[:unresolved_references] result[:unresolved_references] << " " << v else result[:unresolved_references] = v end # $stderr.puts "Unresolved reference #{v.inspect} (avail: #{self.ald.keys.inspect})" result[v.to_sym] = true end else result[k.to_sym] = v end end end def safe_execute_code(object, code) begin object.instance_eval(code) rescue StandardError, ScriptError => e maruku_error "Exception while executing this:\n" + code.gsub(/^/, ">") + "\nThe error was:\n" + (e.inspect + "\n" + e.caller.join("\n")).gsub(/^/, "|") nil end end def execute_code_blocks each_element(:xml_instr) do |e| if e.target == 'maruku' result = safe_execute_code(e, e.code) if result.kind_of?(String) puts "Result is : #{result.inspect}" end end end end def search_abbreviations abbreviations.each do |abbrev, title| reg = Regexp.new(Regexp.escape(abbrev)) replace_each_string do |s| # bug if many abbreviations are present (agorf) p = StringScanner.new(s) a = [] until p.eos? o = '' o << p.getch until p.scan(reg) or p.eos? a << o unless o.empty? a << md_abbr(abbrev.dup, title ? title.dup : nil) if p.matched == abbrev end a end end end # (PHP Markdown extra) Search for elements that have # markdown=1 or markdown=block defined def substitute_markdown_inside_raw_html each_element(:raw_html) do |e| html = e.parsed_html next unless html html.process_markdown_inside_elements(self) end end end maruku-0.7.2/lib/maruku/input/parse_block.rb0000644000004100000410000004771412347070213021112 0ustar www-datawww-datamodule MaRuKu; module In; module Markdown; module BlockLevelParser include Helpers include MaRuKu::Strings include MaRuKu::In::Markdown::SpanLevelParser class BlockContext < Array def describe n = 5 desc = size > n ? self[-n, n] : self "Last #{n} elements: " + desc.map {|x| "\n -" + x.inspect }.join end end # Splits the string and calls parse_lines_as_markdown def parse_text_as_markdown(text) lines = split_lines(text) src = LineSource.new(lines) parse_blocks(src) end # Input is a LineSource def parse_blocks(src) output = BlockContext.new # run state machine while src.cur_line next if check_block_extensions(src, output, src.cur_line) md_type = src.cur_line.md_type # Prints detected type (useful for debugging) #puts "parse_blocks #{md_type}|#{src.cur_line}" case md_type when :empty output << :empty src.ignore_line when :ial m = InlineAttributeList.match src.shift_line content = m[1] || "" src2 = CharSource.new(content, src) interpret_extension(src2, output) when :ald output << read_ald(src) when :text # paragraph, or table, or definition list read_text_material(src, output) when :header2, :hrule # hrule src.shift_line output << md_hrule when :header3 output << read_header3(src) when :ulist, :olist list_type = (md_type == :ulist) ? :ul : :ol li = read_list_item(src) # append to current list if we have one if output.last.kind_of?(MDElement) && output.last.node_type == list_type then output.last.children << li else output << md_el(list_type, li) end when :quote output << read_quote(src) when :code e = read_code(src) output << e if e when :raw_html # More extra hacky stuff - if there's more than just HTML, we either wrap it # in a paragraph or break it up depending on whether it's an inline element or not e = read_raw_html(src) unless e.empty? if e.first.parsed_html && (first_node_name = e.first.parsed_html.first_node_name) && HTML_INLINE_ELEMS.include?(first_node_name) && !%w(svg math).include?(first_node_name) content = [e.first] if e.size > 1 content.concat(e[1].children) end output << md_par(content) else output.concat(e) end end when :footnote_text output << read_footnote_text(src) when :ref_definition if src.parent && src.cur_index == 0 read_text_material(src, output) else read_ref_definition(src, output) end when :abbreviation output << read_abbreviation(src) when :xml_instr read_xml_instruction(src, output) else # unhandled line type at this level # Just treat it as raw text read_text_material(src, output) end end merge_ial(output, src, output) output.delete_if do |x| # Strip out IAL (x.kind_of?(MDElement) && x.node_type == :ial) || # get rid of empty line markers x == :empty end # See for each list if we can omit the paragraphs # TODO: do this after output.each do |c| # Remove paragraphs that we can get rid of if [:ul, :ol].include?(c.node_type) && c.children.none?(&:want_my_paragraph) c.children.each do |d| if d.children.first && d.children.first.node_type == :paragraph d.children = d.children.first.children + d.children[1..-1] end end elsif c.node_type == :definition_list && c.children.none?(&:want_my_paragraph) c.children.each do |definition| definition.definitions.each do |dd| if dd.children.first.node_type == :paragraph dd.children = dd.children.first.children + dd.children[1..-1] end end end end end output end def read_text_material(src, output) if src.cur_line.include?('|') && # if contains a pipe, it could be a table header src.next_line && src.next_line.rstrip =~ TableSeparator output << read_table(src) elsif src.next_line && [:header1, :header2].include?(src.next_line.md_type) output << read_header12(src) elsif eventually_comes_a_def_list(src) definition = read_definition(src) if output.last.kind_of?(MDElement) && output.last.node_type == :definition_list then output.last.children << definition else output << md_el(:definition_list, definition) end else # Start of a paragraph output.concat read_paragraph(src) end end def read_ald(src) if (l = src.shift_line) =~ AttributeDefinitionList id = $1 al = read_attribute_list(CharSource.new($2, src)) self.ald[id] = al; md_ald(id, al) else maruku_error "Bug Bug:\n#{l.inspect}" nil end end # reads a header (with ----- or ========) def read_header12(src) line = src.shift_line.strip al = nil # Check if there is an IAL if new_meta_data? and line =~ /^(.*?)\{(.*?)\}\s*$/ line = $1.strip ial = $2 al = read_attribute_list(CharSource.new(ial, src)) end text = parse_span line if text.empty? text = "{#{ial}}" al = nil end level = src.cur_line.md_type == :header2 ? 2 : 1; src.shift_line md_header(level, text, al) end # reads a header like '#### header ####' def read_header3(src) line = src.shift_line.strip al = nil # Check if there is an IAL if new_meta_data? and line =~ /^(.*?)\{(.*?)\}\s*$/ line = $1.strip ial = $2 al = read_attribute_list(CharSource.new(ial, src)) end level = line[/^#+/].size text = parse_span line.gsub(/\A#+|#+\z/, '') if text.empty? text = "{#{ial}}" al = nil end md_header(level, text, al) end def read_xml_instruction(src, output) m = /^\s*<\?((\w+)\s*)?(.*)$/.match src.shift_line raise "BugBug" unless m target = m[2] || '' code = m[3] until code.include?('?>') code << "\n" << src.shift_line end unless code =~ /\?>\s*$/ garbage = (/\?>(.*)$/.match(code))[1] maruku_error "Trailing garbage on last line: #{garbage.inspect}:\n" + code.gsub(/^/, '|'), src end code.gsub!(/\?>\s*$/, '') if target == 'mrk' && MaRuKu::Globals[:unsafe_features] result = safe_execute_code(self, code) if result if result.kind_of? String raise "Not expected" else output.push(*result) end end else output << md_xml_instr(target, code) end end def read_raw_html(src) extra_line = nil h = HTMLHelper.new begin l = src.shift_line h.eat_this(l) # puts "\nBLOCK:\nhtml -> #{l.inspect}" while src.cur_line && !h.is_finished? l = src.shift_line # puts "html -> #{l.inspect}" h.eat_this "\n" + l end rescue => e maruku_error "Bad block-level HTML:\n#{e.inspect.gsub(/^/, '|')}\n", src end unless h.rest =~ /^\s*$/ extra_line = h.rest end raw_html = h.stuff_you_read is_inline = HTML_INLINE_ELEMS.include?(h.first_tag) if extra_line remainder = is_inline ? parse_span(extra_line) : parse_text_as_markdown(extra_line) if extra_line.start_with?(' ') remainder[0] = ' ' + remainder[0] if remainder[0].is_a?(String) end is_inline ? [md_html(raw_html), md_par(remainder)] : [md_html(raw_html)] + remainder else [md_html(raw_html)] end end def read_paragraph(src) lines = [src.shift_line] while src.cur_line # :olist does not break case t = src.cur_line.md_type when :quote, :header3, :empty, :ref_definition, :ial, :xml_instr break when :olist, :ulist break if !src.next_line || src.next_line.md_type == t end break if src.cur_line.strip.empty? break if src.next_line && [:header1, :header2].include?(src.next_line.md_type) break if any_matching_block_extension?(src.cur_line) lines << src.shift_line end children = parse_span(lines, src) pick_apart_non_inline_html(children) end # If there are non-inline HTML tags in the paragraph, break them out into # their own elements and make paragraphs out of everything else. def pick_apart_non_inline_html(children) output = [] para_children = [] children.each do |child| if element_is_non_inline_html?(child) unless para_children.empty? # Fix up paragraphs before non-inline elements having an extra space last_child = para_children.last if last_child.is_a?(String) && !last_child.empty? last_child.replace last_child[0..-2] end output << md_par(para_children) para_children = [] end output << child else para_children << child end end unless para_children.empty? output << md_par(para_children) end output end # Is the given element an HTML element whose root is not an inline element? def element_is_non_inline_html?(elem) if elem.is_a?(MDElement) && elem.node_type == :raw_html && elem.parsed_html first_node_name = elem.parsed_html.first_node_name first_node_name && !HTML_INLINE_ELEMS.include?(elem.parsed_html.first_node_name) else false end end # Reads one list item, either ordered or unordered. def read_list_item(src) parent_offset = src.cur_index item_type = src.cur_line.md_type first = src.shift_line indentation, ial = spaces_before_first_char(first) al = read_attribute_list(CharSource.new(ial, src)) if ial ial_offset = ial ? ial.length + 3 : 0 lines, want_my_paragraph = read_indented_content(src, indentation, [], item_type, ial_offset) # in case there is a second line and this line starts a new list, format it. if !lines.empty? && [:ulist, :olist].include?(MaRuKu::MDLine.new(lines.first).md_type) lines.unshift "" end # add first line # Strip first '*', '-', '+' from first line first_changed = first.gsub(/([^\t]*)(\t)/) { $1 + " " * (TAB_SIZE - $1.length % TAB_SIZE) } stripped = first_changed[indentation, first_changed.size - 1] lines.unshift stripped src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) md_li(children, want_my_paragraph, al) end def read_abbreviation(src) unless (l = src.shift_line) =~ Abbreviation maruku_error "Bug: it's Andrea's fault. Tell him.\n#{l.inspect}" end abbr = $1 desc = $2 if !abbr || abbr.empty? maruku_error "Bad abbrev. abbr=#{abbr.inspect} desc=#{desc.inspect}" end self.abbreviations[abbr] = desc md_abbr_def(abbr, desc) end def read_footnote_text(src) parent_offset = src.cur_index first = src.shift_line unless first =~ FootnoteText maruku_error "Bug (it's Andrea's fault)" end id = $1 text = $2 || '' indentation = 4 #first.size-text.size # puts "id =_#{id}_; text=_#{text}_ indent=#{indentation}" break_list = [:footnote_text, :ref_definition, :definition, :abbreviation] item_type = :footnote_text lines, _ = read_indented_content(src, indentation, break_list, item_type) # add first line lines.unshift text unless text.strip.empty? src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) e = md_footnote(id, children) self.footnotes[id] = e e end # This is the only ugly function in the code base. # It is used to read list items, descriptions, footnote text def read_indented_content(src, indentation, break_list, item_type, ial_offset=0) lines = [] # collect all indented lines saw_empty = false saw_anything_after = false break_list = Array(break_list) len = indentation - ial_offset while src.cur_line num_leading_spaces = src.cur_line.number_of_leading_spaces break if num_leading_spaces < len && ![:text, :empty].include?(src.cur_line.md_type) line = strip_indent(src.cur_line, indentation) md_type = line.md_type if md_type == :empty saw_empty = true lines << line src.shift_line next end # Unquestioningly grab anything that's deeper-indented if md_type != :code && num_leading_spaces > len lines << line src.shift_line next end # after a white line if saw_empty # we expect things to be properly aligned break if num_leading_spaces < len saw_anything_after = true else break if break_list.include?(md_type) end lines << line src.shift_line # You are only required to indent the first line of # a child paragraph. if md_type == :text while src.cur_line && src.cur_line.md_type == :text lines << strip_indent(src.shift_line, indentation) end end end # TODO fix this want_my_paragraph = saw_anything_after || (saw_empty && src.cur_line && src.cur_line.md_type == item_type) # create a new context while lines.last && lines.last.md_type == :empty lines.pop end return lines, want_my_paragraph end def read_quote(src) parent_offset = src.cur_index lines = [] # collect all indented lines while src.cur_line && src.cur_line.md_type == :quote lines << unquote(src.shift_line) end src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) md_quote(children) end def read_code(src) # collect all indented lines lines = [] while src.cur_line && [:code, :empty].include?(src.cur_line.md_type) lines << strip_indent(src.shift_line, 4) end #while lines.last && (lines.last.md_type == :empty ) while lines.last && lines.last.strip.size == 0 lines.pop end while lines.first && lines.first.strip.size == 0 lines.shift end return nil if lines.empty? source = lines.join("\n") md_codeblock(source) end def read_ref_definition(src, out) line = src.shift_line # if link is incomplete, shift next line if src.cur_line && ![:footnote_text, :ref_definition, :definition, :abbreviation].include?(src.cur_line.md_type) && (1..3).include?(src.cur_line.number_of_leading_spaces) line << " " << src.shift_line end match = LinkRegex.match(line) unless match maruku_error "Link does not respect format: '#{line}'" and return end id = match[1] url = match[2] title = match[3] || match[4] || match[5] id = sanitize_ref_id(id) hash = self.refs[id] = { :url => url, :title => title } stuff = (match[6] || '') stuff.split.each do |couple| k, v = couple.split('=') v ||= "" v = v[1..-2] if v.start_with?('"') # strip quotes hash[k.to_sym] = v end out << md_ref_def(id, url, :title => title) end def split_cells(s, allowBlank = false) if allowBlank if /^[|].*[|]$/ =~ s # handle the simple and decorated table cases s.split('|', -1)[1..-2] # allow blank cells, but only keep the inner elements of the cells elsif /^.*[|]$/ =~ s s.split('|', -1)[0..-2] # allow blank cells, but only keep the inner elements of the cells else s.split('|', -1) end else s.split('|').reject(&:empty?).map(&:strip) end end def read_table(src) head = split_cells(src.shift_line).map do |s| md_el(:head_cell, parse_span(s)) end separator = split_cells(src.shift_line) align = separator.map do |s| # ex: :-------------------: # If the separator starts and ends with a colon, # center the cell. If it's on the right, right-align, # otherwise left-align. starts = s.start_with? ':' ends = s.end_with? ':' if s.empty? # blank nil elsif starts && ends :center elsif ends :right else :left end end align.pop if align[-1].nil? # trailing blank num_columns = align.size head.pop if head.size == num_columns + 1 && head[-1].al.size == 0 # trailing blank if head.size != num_columns maruku_error "Table head does not have #{num_columns} columns: \n#{head.inspect}" tell_user "I will ignore this table." # XXX try to recover return md_br end rows = [] while src.cur_line && src.cur_line.include?('|') row = [] colCount = 0 colspan = 1 currElem = nil currIdx = 0 split_cells(src.shift_line, true).map do |s| if s.empty? # empty cells increase the colspan of the previous cell found = false colspan += 1 al = (currElem &&currElem.al) || AttributeList.new if al.size > 0 elem = find_colspan(al) if elem != nil elem[1] = colspan.to_s found = true end end al.push(["colspan", colspan.to_s]) unless found # also handles the case of and empty attribute list else colspan = 1 row[currIdx] = md_el(:cell, parse_span(s)) currElem = row[currIdx] currIdx += 1 end end # # sanity check - make sure the current row has the right number of columns (including spans) # If not, dump the table and return a break # num_columns = count_columns(row) if num_columns == head.size + 1 && row[-1].al.size == 0 #trailing blank cell row.pop num_columns -= 1 end if head.size != num_columns maruku_error "Row does not have #{head.size} columns: \n#{row.inspect} - #{num_columns}" tell_user "I will ignore this table." # XXX need to recover return md_br end rows << row end rows.unshift(head) # put the header row on the processed table md_el(:table, rows, { :align => align }) end # # count the actual number of elements in a row taking into account colspans # def count_columns(row) colCount = 0 row.each do |cell| if cell.al && cell.al.size > 0 al = find_colspan(cell.al) if al != nil colCount += al[1].to_i else colCount += 1 end else colCount += 1 end end colCount end # # Search an attribute list looking for a colspan # def find_colspan(al) al.find {|alElem| alElem[0] == "colspan" } end # If current line is text, a definition list is coming # if 1) text,empty,[text,empty]*,definition def eventually_comes_a_def_list(src) src.tell_me_the_future =~ %r{^t+e?d}x end def read_definition(src) # Read one or more terms terms = [] while src.cur_line && src.cur_line.md_type == :text terms << md_el(:definition_term, parse_span(src.shift_line)) end want_my_paragraph = false raise "Chunky Bacon!" unless src.cur_line # one optional empty if src.cur_line.md_type == :empty want_my_paragraph = true src.shift_line end raise "Chunky Bacon!" unless src.cur_line.md_type == :definition # Read one or more definitions definitions = [] while src.cur_line && src.cur_line.md_type == :definition parent_offset = src.cur_index first = src.shift_line first =~ Definition first = $1 lines, w_m_p = read_indented_content(src, 4, :definition, :definition) want_my_paragraph ||= w_m_p lines.unshift first src2 = LineSource.new(lines, src, parent_offset) children = parse_blocks(src2) definitions << md_el(:definition_data, children) end md_el(:definition, terms + definitions, { :terms => terms, :definitions => definitions, :want_my_paragraph => want_my_paragraph }) end end end end end maruku-0.7.2/lib/maruku/attributes.rb0000644000004100000410000000675712347070213017657 0ustar www-datawww-datamodule MaRuKu # This represents a list of attributes specified in the Markdown document # that apply to a Markdown-generated tag. # What was `{#id .class key="val" ref}` in the Markdown # is parsed into `[[:id, 'id'], [:class, 'class'], ['key', 'val'], [:ref, 'ref']]`. class AttributeList < Array def to_s map do |k, v| value = quote_if_needed(v) case k when :id; "#" + value when :class; "." + value when :ref; value else quote_if_needed(k) + "=" + value end end.join(' ') end alias to_md to_s private def quote_if_needed(str) (str =~ /[\s'"]/) ? str.inspect : str end end module In::Markdown::SpanLevelParser def md_al(s = []) AttributeList.new(s) end # @return [AttributeList, nil] def read_attribute_list(src, con=nil, break_on_chars=nil) break_on_chars = Array(break_on_chars) separators = break_on_chars + ['=', ' ', "\t"] escaped = Maruku::EscapedCharInQuotes al = AttributeList.new loop do src.consume_whitespace break if break_on_chars.include? src.cur_char case src.cur_char when ':' src.ignore_char when nil break # we're done here. when '=' # error src.ignore_char maruku_error "In attribute lists, cannot start identifier with `=`." tell_user "Ignoring and continuing." when '#' # id definition src.ignore_char if id = read_quoted_or_unquoted(src, con, escaped, separators) al << [:id, id] else maruku_error 'Could not read `id` attribute.', src, con tell_user 'Ignoring bad `id` attribute.' end when '.' # class definition src.ignore_char if klass = read_quoted_or_unquoted(src, con, escaped, separators) al << [:class, klass] else maruku_error 'Could not read `class` attribute.', src, con tell_user 'Ignoring bad `class` attribute.' end else unless key = read_quoted_or_unquoted(src, con, escaped, separators) maruku_error 'Could not read key or reference.' next end if src.cur_char != '=' && key.length > 0 al << [:ref, key] next end src.ignore_char # skip the = if val = read_quoted_or_unquoted(src, con, escaped, separators) al << [key, val] else maruku_error "Could not read value for key #{key.inspect}.", src, con tell_user "Ignoring key #{key.inspect}" end end end al end def merge_ial(elements, src, con) # Apply each IAL to the element before (elements + [nil]).each_cons(3) do |before, e, after| next unless ial?(e) if before.kind_of? MDElement before.al = e.ial elsif after.kind_of? MDElement after.al = e.ial else maruku_error <|\<\>|\=)? # padding (\(+)? # left is 9 (\)+)? # right is 10 # filters is 11 (\| (?:(?:\w+)\|)+ )? # optional final dot is 12 (\.)? $ }x def initialize(s) if m = Reg.match(s) self.block_name = m[1] self.style = m[3] self.lang = m[4] self.css_class = m[6] self.css_id = m[7] self.text_align = {nil=>nil,'>'=>'right','<'=>'left', '<>'=>'center','='=>'justified'}[m[8]] self.num_left_pad = m[9] && m[9].size self.num_right_pad = m[10] && m[10].size self.filters = m[11] && m[11].split('|') self.double_dot = m[12] && true end end attr_accessor :block_name # or nil attr_accessor :style # or nil attr_accessor :lang # or nil attr_accessor :css_class # or nil attr_accessor :css_id # or nil attr_accessor :text_align # {nil, 'left', 'right', 'center', 'justified'} attr_accessor :num_left_pad # nil or 1.. attr_accessor :num_right_pad # nil or 1.. attr_accessor :filters # nil [], array of strings attr_accessor :double_dot # nil or true end module MaRuKu def self.textile2(source, params) m = Maruku.new m.t2_parse(source, params) end class MDDocument def t2_parse(source, params) src = LineSource.new(source) output = BlockContext.new t2_parse_blocks(src, output) self.children = output.elements end Handling = Struct.new(:method, :parse_lines) T2_Handling = { nil => Handling.new(:t2_block_paragraph, true), 'p' => Handling.new(:t2_block_paragraph, true) } # Input is a LineSource def t2_parse_blocks(src, output) while src.cur_line l = src.shift_line # ignore empty line if l.t2_empty? then src.shift_line next end # TODO: lists # TODO: xml # TODO: `==` signature, l = if l.t2_contains_signature? l.t2_get_signature else [Textile2Signature.new, l] end if handling = T2_Handling.has_key?(signature.block_name) if self.responds_to? handling.method # read as many non-empty lines that you can lines = [l] if handling.parse_lines while not src.cur_line.t2_empty? lines.push src.shift_line end end self.send(handling.method, src, output, signature, lines) else maruku_error("We don't know about method #{handling.method.inspect}") next end end end end def t2_block_paragraph(src, output, signature, lines) paragraph = lines.join("\n") src2 = CharSource.new(paragraph, src) # output = end def t2_parse_span(src, output) end end # MDDocument endmaruku-0.7.2/lib/maruku/output/0000755000004100000410000000000012347070213016465 5ustar www-datawww-datamaruku-0.7.2/lib/maruku/output/s5/0000755000004100000410000000000012347070213017014 5ustar www-datawww-datamaruku-0.7.2/lib/maruku/output/s5/to_s5.rb0000644000004100000410000000662112347070213020377 0ustar www-datawww-datarequire 'maruku/output/to_html' module MaRuKu class MDDocument def s5_theme xtext(self.attributes[:slide_theme] || "default") end # Render as an HTML fragment (no head, just the content of BODY). (returns a string) def to_s5(context={}) content_only = context[:content_only] != false print_slides = context[:print_slides] if content_only body = xelem('div', doc) else html = xelem('html') html['xmlns'] = 'http://www.w3.org/1999/xhtml' html['xmlns:svg'] = "http://www.w3.org/2000/svg" html['xml:lang'] = self.attributes[:lang] || 'en' head = xelem('head') html << head me = xelem('meta') me['http-equiv'] = 'Content-type' me['content'] = 'text/html;charset=utf-8' head << me # Create title element doc_title = self.attributes[:title] || self.attributes[:subject] || "" begin title_content = MaRuKu::HTMLFragment.new(doc_title).to_html rescue title_content = xtext(doc_title) end title = xelem('title') << title_content head << title body = xelem('body') html << body end slide_header = self.attributes[:slide_header] slide_footer = self.attributes[:slide_footer] slide_subfooter = self.attributes[:slide_subfooter] slide_topleft = self.attributes[:slide_topleft] slide_topright = self.attributes[:slide_topright] slide_bottomleft = self.attributes[:slide_bottomleft] slide_bottomright = self.attributes[:slide_bottomright] dummy_layout_slide = "
#{slide_topleft}
#{slide_topright}
#{slide_bottomleft}
#{slide_bottomright}
" body << dummy_layout_slide presentation = xelem('div') presentation['class'] = 'presentation' body << presentation first_slide = "

#{self.attributes[:title] ||context[:title]}

#{self.attributes[:subtitle] ||context[:subtitle]}

#{self.attributes[:author] ||context[:author]}

#{self.attributes[:company] ||context[:company]}

" presentation << first_slide slide_num = 0 self.toc.section_children.each do |slide| slide_num += 1 @doc.attributes[:doc_prefix] = "s#{slide_num}" div = xelem('div') presentation << div div['class'] = 'slide' h1 = xelem('h1') puts "Slide #{slide_num}: #{slide.header_element.children_to_html.join}" if print_slides slide.header_element.children_to_html.inject(h1, &:<<) div << h1 array_to_html(slide.immediate_children).inject(div, &:<<) # render footnotes unless @doc.footnotes_order.empty? div << render_footnotes @doc.footnotes_order = [] end end if content_only xml = body.to_html else head << S5_external add_css_to(head) xml = html.to_html Xhtml11_mathml2_svg11 + xml end end end end maruku-0.7.2/lib/maruku/output/s5/fancy.rb0000644000004100000410000005776712347070213020467 0ustar www-datawww-datamodule MaRuKu S5_external =< EOF S5_Fancy =< EOF end maruku-0.7.2/lib/maruku/output/to_latex.rb0000644000004100000410000003257212347070213020642 0ustar www-datawww-datarequire 'set' module MaRuKu::Out::Latex module MDDocumentExtensions # @return [Set] attr_accessor :latex_required_packages def latex_require_package(p) self.latex_required_packages << p end def initialize(*args) self.latex_required_packages = Set.new super end end Latex_preamble_enc_cjk = "\\usepackage[C40]{fontenc} \\usepackage[cjkjis]{ucs} \\usepackage[utf8x]{inputenc}" Latex_preamble_enc_utf8 = "\\usepackage{ucs} \\usepackage[utf8x]{inputenc}" # Render as a LaTeX fragment def to_latex children_to_latex end #=begin maruku_doc # Attribute: maruku_signature # Scope: document # Output: html, latex # Summary: Enables Maruku's signature. # Default: true # # If false, Maruku does not append a signature to the # generated file. #=end # Render as a complete LaTeX document def to_latex_document body = to_latex if get_setting(:maruku_signature) body << render_latex_signature end required = self.latex_required_packages.map do |p| "\\usepackage{#{p}}\n" end.join #=begin maruku_doc # Attribute: latex_cjk # Scope: document # Output: latex # Summary: Support for CJK characters. # # If the `latex_cjk` attribute is specified, then appropriate headers # are added to the LaTeX preamble to support Japanese fonts. # You have to have these fonts installed -- and this can be a pain. # # If `latex_cjk` is specified, this is added to the preamble: # # # # # # # while the default is to add this: # # # #=end encoding = get_setting(:latex_cjk) ? Latex_preamble_enc_cjk : Latex_preamble_enc_utf8 #=begin maruku_doc # Attribute: latex_preamble # Scope: document # Output: latex # Summary: User-defined preamble. # # If the `latex_preamble` attribute is specified, then its value # will be used as a custom preamble. # # For example: # # Title: My document # Latex preamble: preamble.tex # # will produce: # # ... # \input{preamble.tex} # ... # #=end user_preamble = (file = @doc.attributes[:latex_preamble]) ? "\\input{#{file}}\n" : "" "\\documentclass{article} % Packages required to support encoding #{encoding} % Packages required by code #{required} % Packages always used \\usepackage{hyperref} \\usepackage{xspace} \\usepackage[usenames,dvipsnames]{color} \\hypersetup{colorlinks=true,urlcolor=blue} #{user_preamble} \\begin{document} #{body} \\end{document} " end def render_latex_signature "\\vfill \\hrule \\vspace{1.2mm} \\begin{tiny} Created by \\href{#{MaRuKu::MARUKU_URL}}{Maruku} #{self.nice_date}. \\end{tiny}" end def to_latex_hrule "\n\\vspace{.5em} \\hrule \\vspace{.5em}\n" end def to_latex_linebreak "\\newline " end def to_latex_paragraph children_to_latex + "\n\n" end #=begin maruku_doc # Title: Input format for colors # Output: latex, html # Related: code_background_color # # Admissible formats: # # green # #abc # #aabbcc #=end # \color{name} # \color[rgb]{1,0.2,0.3} def latex_color(s, command='color') if s =~ /\A\#([1-9A-F]{1,2})([1-9A-F]{1,2})([1-9A-F]{1,2})\z/i # convert from 0-255 or 0-15 to 0.0-1.0 r, g, b = [$1, $2, $3].map {|c| c.hex / (c.length == 1 ? 15.0 : 255.0) } "\\#{command}[rgb]{%0.2f,%0.2f,%0.2f}" % [r, g, b] else "\\#{command}{#{s}}" 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 #=begin maruku_doc # Attribute: latex_use_listings # Scope: document # Output: latex # Summary: Support for `listings` package. # Related: code_show_spaces, code_background_color, lang, code_lang # # If the `latex_use_listings` attribute is specified, then # code block are rendered using the `listings` package. # Otherwise, a standard `verbatim` environment is used. # # * If the `lang` attribute for the code block has been specified, # it gets passed to the `listings` package using the `lstset` macro. # The default lang for code blocks is specified through # the `code_lang` attribute. # # \lstset{language=ruby} # # Please refer to the documentation of the `listings` package for # supported languages. # # If a language is not supported, the `listings` package will emit # a warning during the compilation. Just press enter and nothing # wrong will happen. # # * If the `code_show_spaces` is specified, than spaces and tabs will # be shown using the macro: # # \lstset{showspaces=true,showtabs=true} # # * The background color is given by `code_background_color`. # #=end def to_latex_code if get_setting(:latex_use_listings) @doc.latex_require_package('listings') s = "\\lstset{columns=fixed,frame=shadowbox}" if get_setting(:code_show_spaces) s << "\\lstset{showspaces=true,showtabs=true}\n" else s << "\\lstset{showspaces=false,showtabs=false}\n" end color = latex_color get_setting(:code_background_color) s << "\\lstset{backgroundcolor=#{color}}\n" s << "\\lstset{basicstyle=\\ttfamily\\footnotesize}\n" lang = self.attributes[:lang] || @doc.attributes[:code_lang] || '{}' s << "\\lstset{language=#{lang}}\n" if lang "#{s}\n\\begin{lstlisting}\n#{self.raw_code}\n\\end{lstlisting}" else "\\begin{verbatim}#{self.raw_code}\\end{verbatim}\n" end end def to_latex_header header_levels = %w(section subsection subsubsection) h = header_levels[self.level - 1] || 'paragraph' title = children_to_latex if number = section_number title = number + title end if id = self.attributes[:id] # drop '#' at the beginning id = id[1..-1] if id.start_with? '#' %{\\hypertarget{%s}{}\\%s*{{%s}}\\label{%s}\n\n} % [ id, h, title, id ] else %{\\%s*{%s}\n\n} % [ h, title] end end def to_latex_ul if self.attributes[:toc] @doc.toc.to_latex else wrap_as_environment('itemize') end end def to_latex_quote wrap_as_environment('quote') end def to_latex_ol wrap_as_environment('enumerate') end def to_latex_li "\\item #{children_to_latex}\n" end def to_latex_strong "\\textbf{#{children_to_latex}}" end def to_latex_emphasis "\\emph{#{children_to_latex}}" end def wrap_as_span(c) "{#{c} #{children_to_latex}}" end def wrap_as_environment(name) "\\begin{#{name}}% #{children_to_latex} \\end{#{name}}\n" end SAFE_CHARS = Set.new(('a'..'z').to_a + ('A'..'Z').to_a) # the ultimate escaping # (is much better than using \verb) def latex_escape(source) source.chars.inject('') do |s, b| s << if b == '\\' '~' elsif SAFE_CHARS.include? b b else "\\char%d" % b[0].ord end end end def to_latex_entity entity_name = self.entity_name entity = MaRuKu::Out::EntityTable.instance.entity(entity_name) unless entity maruku_error "I don't know how to translate entity '#{entity_name}' to LaTeX." return "" end replace = entity.latex_string @doc.latex_require_package entity.latex_package if entity.latex_package if replace if replace.start_with?("\\") && !replace.end_with?('$', '}') replace + "{}" else replace end else tell_user "Cannot translate entity #{entity_name.inspect} to LaTeX." entity_name end end def to_latex_inline_code # Convert to printable latex chars s = latex_escape(self.raw_code) color = get_setting(:code_background_color) colorspec = latex_color(color, 'colorbox') "{#{colorspec}{\\tt #{s}}}" end def to_latex_immediate_link url = self.url text = url.gsub(/^mailto:/,'') # don't show mailto text = latex_escape(text) if url.start_with? '#' url = url[1..-1] "\\hyperlink{#{url}}{#{text}}" else "\\href{#{url}}{#{text}}" end end def to_latex_im_link url = self.url if url.start_with? '#' url = url[1..-1] "\\hyperlink{#{url}}{#{children_to_latex}}" else "\\href{#{url}}{#{children_to_latex}}" end end def to_latex_link id = self.ref_id || children_to_s ref = @doc.refs[sanitize_ref_id(id)] || @doc.refs[sanitize_ref_id(children_to_s)] if ref url = ref[:url] if url.start_with? '#' url = url[1..-1] "\\hyperlink{#{url}}{#{children_to_latex}}" else "\\href{#{url}}{#{children_to_latex}}" end else $stderr.puts "Could not find id = '#{id}'" children_to_latex end end def to_latex_email_address "\\href{mailto:#{self.email}}{#{latex_escape(self.email)}}" end def to_latex_table num_columns = self.align.size head, *rows = @children h = { :center => 'c' , :left => 'l' , :right => 'r'} align_string = self.align.map {|a| h[a] }.join('|') s = "\\begin{tabular}{#{align_string}}\n" s << array_to_latex(head, '&') + "\\\\" + "\n" s << "\\hline \n" rows.each do |row| s << array_to_latex(row, '&') + "\\\\" + "\n" end s << "\\end{tabular}" # puts table in its own paragraph s << "\n\n" end def to_latex_head_cell to_latex_cell end def to_latex_cell s="" if @attributes.has_key?(:colspan) # TODO figure out how to set the alignment (defaulting to left for now) s="\\multicolumn {"<< @attributes[:colspan]<<"}{|l|}{"<} LATEX_TO_CHARCODE = %w(^ ~ > <) # escapes special characters def string_to_latex(s) s = escape_to_latex(s) OtherGoodies.each do |k, v| s.gsub!(k, v) end s end # other things that are good on the eyes OtherGoodies = { /(\s)LaTeX/ => '\1\\LaTeX\\xspace ', # XXX not if already \LaTeX } private def escape_to_latex(s) s.chars.inject("") do |result, b| if LATEX_TO_CHARCODE.include? b result << "{\\tt \\symbol{#{b[0].ord}}}" elsif LATEX_ADD_SLASH.include? b result << '\\' << b elsif b == '\\' # there is no backslash in cmr10 fonts result << "$\\backslash$" else result << b end end end end module MaRuKu class MDDocument include MaRuKu::Out::Latex::MDDocumentExtensions end end maruku-0.7.2/lib/maruku/output/to_html.rb0000644000004100000410000005343012347070213020465 0ustar www-datawww-datarequire 'maruku/string_utils' require 'cgi' # This module groups all functions related to HTML export. module MaRuKu::Out::HTML # Escape text for use in HTML (content or attributes) by running it through # standard XML escaping (quotes and angle brackets and ampersands) def self.escapeHTML(text) CGI.escapeHTML(text) # TODO: When we drop Rubies < 1.9.3, re-add .gsub(/[^[:print:]\n\r\t]/, '') to # get rid of non-printable control characters. end # A simple class to represent an HTML element for output. class HTMLElement attr_accessor :name attr_accessor :attributes attr_accessor :children def initialize(name, attr={}, children=[]) self.name = name self.attributes = attr || {} self.children = Array(children) children << yield if block_given? end def <<(child) children << child if children self end def [](key) attributes[key.to_s] end def []=(key, value) attributes[key.to_s] = value end def add_class(class_name) attributes['class'] = ((attributes['class']||'').split(' ') + [class_name]).join(' ') end # These elements have no children and should be rendered with a self-closing tag. # It's not an exhaustive list, but they cover everything we use. SELF_CLOSING = Set.new %w[br hr img link meta] def to_html m = "<#{name}" attributes.each do |k, v| m << " #{k.to_s}=\"#{v.to_s}\"" end if SELF_CLOSING.include? name m << " />" else content = children.map(&:to_s) m << ">" << content.join('') << "" end end alias :to_str :to_html alias :to_s :to_html end # Render as an HTML fragment (no head, just the content of BODY). (returns a string) def to_html(context={}) output = "" children_to_html.each do |e| output << e.to_s end # render footnotes unless @doc.footnotes_order.empty? output << render_footnotes end output end Xhtml11_mathml2_svg11 = ' ' # Render to a complete HTML document (returns a string) def to_html_document(context={}) doc = to_html_document_tree xml = doc.to_s Xhtml11_mathml2_svg11 + xml end # Helper to create a text node def xtext(text) MaRuKu::Out::HTML.escapeHTML(text) end # Helper to create an element def xelem(type) HTMLElement.new(type) end def xml_newline "\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: doc_prefix # Scope: document # # String to disambiguate footnote links. #=end #=begin maruku_doc # Attribute: subject # Scope: document # Synonym 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 an HTMLElement document tree) def to_html_document_tree root = xelem('html') root['xmlns'] = 'http://www.w3.org/1999/xhtml' root['xmlns:svg'] = "http://www.w3.org/2000/svg" root['xml:lang'] = self.attributes[:lang] || 'en' root << xml_newline head = xelem('head') root << head # me = xelem('meta') me['http-equiv'] = 'Content-type' me['content'] = 'application/xhtml+xml;charset=utf-8' head << me %w(description keywords author revised).each do |m| if value = self.attributes[m.to_sym] meta = xelem('meta') meta['name'] = m meta['content'] = value.to_s head << meta end end self.attributes.each do |k,v| if k.to_s =~ /\Ameta-(.*)\z/ meta = xelem('meta') meta['name'] = $1 meta['content'] = v.to_s head << meta end end # Create title element doc_title = self.attributes[:title] || self.attributes[:subject] || "" begin title_content = MaRuKu::HTMLFragment.new(doc_title).to_html rescue title_content = xtext(doc_title) end title = xelem('title') << title_content head << title add_css_to(head) root << xml_newline body = xelem('body') children_to_html.each do |e| body << e.to_s end # render footnotes unless @doc.footnotes_order.empty? body << render_footnotes end # When we are rendering a whole document, we add a signature # at the bottom. if get_setting(:maruku_signature) body << maruku_html_signature end root << body end def add_css_to(head) if css_list = self.attributes[:css] css_list.split.each do |css| # link = xelem('link') link['type'] = 'text/css' link['rel'] = 'stylesheet' link['href'] = css head << link << xml_newline end end end # returns "st","nd","rd" or "th" as appropriate def day_suffix(day) s = { 1 => 'st', 2 => 'nd', 3 => 'rd', 21 => 'st', 22 => 'nd', 23 => 'rd', 31 => 'st' } s[day] || 'th'; end # formats a nice date def nice_date Time.now.strftime(" at %H:%M on %A, %B %d") + day_suffix(t.day) + t.strftime(", %Y") end def maruku_html_signature div = xelem('div') div['class'] = 'maruku_signature' div << xelem('hr') span = xelem('span') span['style'] = 'font-size: small; font-style: italic' div << span << xtext('Created by ') a = xelem('a') a['href'] = MaRuKu::MARUKU_URL a['title'] = 'Maruku: a Markdown-superset interpreter for Ruby' a << xtext('Maruku') span << xtext(nice_date + ".") div end def render_footnotes div = xelem('div') div['class'] = 'footnotes' div << xelem('hr') ol = xelem('ol') @doc.footnotes_order.each_with_index do |fid, i| num = i + 1 if f = self.footnotes[fid] li = f.wrap_as_element('li') li['id'] = "#{get_setting(:doc_prefix)}fn:#{num}" a = xelem('a') a['href'] = "\##{get_setting(:doc_prefix)}fnref:#{num}" a['rev'] = 'footnote' a << xtext([8617].pack('U*')) last = nil li.children.reverse_each do |child| if child.is_a?(HTMLElement) last = child break end end if last && last.name == "p" last << xtext(' ') << a else li.children << a end ol << li else maruku_error "Could not find footnote id '#{fid}' among [#{self.footnotes.keys.inspect}]." end end div << ol end def to_html_hrule xelem('hr') end def to_html_linebreak xelem('br') end # renders children as html and wraps into an element of given name # # Sets 'id' if meta is set def wrap_as_element(name, attributes={}) html_element name, children_to_html, attributes 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 HTML4Attributes = {} coreattrs = [:id, :class, :style, :title, :accesskey, :contenteditable, :dir, :draggable, :spellcheck, :tabindex] i18n = [:lang, :'xml:lang'] events = [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover, :onmousemove, :onmouseout, :onkeypress, :onkeydown, :onkeyup] common_attrs = coreattrs + i18n + events cells = [:align, :char, :charoff, :valign] # Each row maps a list of tags to the list of attributes beyond the common_attributes # that are valid on those elements [ ['body', [:onload, :onunload]], ['a', [:charset, :type, :name, :rel, :rev, :accesskey, :shape, :coords, :tabindex, :onfocus,:onblur]], ['img', [:longdesc, :name, :height, :width, :alt]], ['ol', [:reversed, :start]], ['li', [:value]], ['table', [:summary, :width, :frame, :rules, :border, :cellspacing, :cellpadding]], [%w(q blockquote), [:cite]], [%w(ins del), [:cite, :datetime]], [%w(colgroup col), [:span, :width] + cells], [%w(thead tbody tfoot), cells], [%w(td td th), [:abbr, :axis, :headers, :scope, :rowspan, :colspan] + cells], [%w(em code strong hr span dl dd dt address div p pre caption ul h1 h2 h3 h4 h5 h6), []] ].each do |elements, attributes| [*elements].each do |element| HTML4Attributes[element] = common_attrs + attributes end end # Pretty much the same as the HTMLElement constructor except it # copies standard attributes out of the Maruku Element's attributes hash. def html_element(name, content="", attributes={}) attributes = content if attributes.empty? && content.is_a?(Hash) Array(HTML4Attributes[name]).each do |att| if v = @attributes[att] attributes[att.to_s] = MaRuKu::Out::HTML.escapeHTML(v.to_s) end end content = yield if block_given? HTMLElement.new(name, attributes, content) end def to_html_ul if @attributes[:toc] # render toc @doc.toc.to_html else add_ws wrap_as_element('ul') end end def to_html_paragraph add_ws wrap_as_element('p') end def to_html_ol add_ws wrap_as_element('ol') end def to_html_li add_ws wrap_as_element('li') end def to_html_quote add_ws wrap_as_element('blockquote') end def to_html_strong wrap_as_element('strong') 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 def section_number return nil unless get_setting(:use_numbered_headers) n = Array(@attributes[:section_number]) return nil if n.empty? n.join('.') + ". " end # nil if not applicable, else SPAN element def render_section_number return nil unless section_number && !section_number.empty? # if we are bound to a section, add section number span = xelem('span') span['class'] = 'maruku_section_number' span << xtext(section_number) end def to_html_header element_name = "h#{self.level}" h = wrap_as_element element_name if span = render_section_number h.children.unshift(span) end add_ws h end #=begin maruku_doc # Attribute: html_use_syntax # Scope: global, document, element # Output: HTML # Summary: Enables the use of the `syntax` package. # Related: lang, code_lang # Default: # # 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
# {:lang=html html_use_syntax=true} # # produces: # # require 'maruku' # {:lang=ruby html_use_syntax=true} # # and # #
Div
# {:lang=html html_use_syntax=true} # #=end $syntax_loaded = false def to_html_code source = self.raw_code code_lang = self.lang || self.attributes[:lang] || @doc.attributes[:code_lang] code_lang = 'xml' if code_lang == 'html' code_lang = 'css21' if code_lang == 'css' use_syntax = get_setting :html_use_syntax element = if use_syntax && code_lang begin unless $syntax_loaded require 'rubygems' require 'syntax' require 'syntax/convertors/html' $syntax_loaded = true end convertor = Syntax::Convertors::HTML.for_syntax code_lang # eliminate trailing newlines otherwise Syntax crashes source = source.sub(/\n*\z/, '') html = convertor.convert(source) html.gsub!(/\'|'/,''') # IE bug d = MaRuKu::HTMLFragment.new(html) highlighted = d.to_html.sub(/\A
(.*)<\/pre>\z/m, '\1')
          code = HTMLElement.new('code', { :class => code_lang }, highlighted)

          pre = xelem('pre')
          # add a class here, too, for compatibility with existing implementations
          pre['class'] = code_lang
          pre << code
          pre
        rescue LoadError => e
          maruku_error "Could not load package 'syntax'.\n" +
            "Please install it, for example using 'gem install syntax'."
          to_html_code_using_pre(source, code_lang)
        rescue => e
          maruku_error "Error while using the syntax library for code:\n#{source.inspect}" +
            "Lang is #{code_lang} object is: \n" +
            self.inspect +
            "\nException: #{e.class}: #{e.message}"

          tell_user("Using normal PRE because the syntax library did not work.")
          to_html_code_using_pre(source, code_lang)
        end
      else
        to_html_code_using_pre(source, code_lang)
      end

    color = get_setting(:code_background_color)
    if color != MaRuKu::Globals[:code_background_color]
      element['style'] = "background-color: #{color};"
    end

    add_ws element
  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, code_lang=nil)
    code = xelem('code')
    pre = xelem('pre')
    pre << code

    if get_setting(:code_show_spaces)
      # 187 = raquo
      # 160 = nbsp
      # 172 = not
      source = source.gsub(/\t/,'»' + ' ' * 3).gsub(/ /,'¬')
    end

    code << xtext(source)

    code_lang ||= self.attributes[:lang]
    if code_lang
      pre['class'] = code['class'] = code_lang
    end

    pre
  end

  def to_html_inline_code
    code_attrs = {}
    source = xtext(self.raw_code)

    color = get_setting(:code_background_color)
    if color != MaRuKu::Globals[:code_background_color]
      code_attrs['style'] = "background-color: #{color};" + (code_attrs['style'] || "")
    end

    html_element('code', source, code_attrs)
  end

  def add_class_to(el, cl)
    el['class'] =
      if already = el['class']
        already + " " + cl
      else
        cl
      end
  end

  def to_html_immediate_link
    text = self.url.gsub(/^mailto:/, '') # don't show mailto
    html_element('a', text, 'href' => self.url)
  end

  def to_html_link
    a = {}
    id = self.ref_id || children_to_s

    if ref = @doc.refs[sanitize_ref_id(id)] || @doc.refs[sanitize_ref_id(children_to_s)]
      a['href'] = ref[:url] if ref[:url]
      a['title'] = ref[:title] if ref[:title]
    else
      maruku_error "Could not find ref_id = #{id.inspect} for #{self.inspect}\n" +
        "Available refs are #{@doc.refs.keys.inspect}"
      tell_user "Not creating a link for ref_id = #{id.inspect}.\n"
      if (self.ref_id)
        return "[#{children_to_s}][#{id}]"
      else
        return "[#{children_to_s}]"
      end
    end

    wrap_as_element('a', a)
  end

  def to_html_im_link
    if self.url
      a = {}
      a['href'] = self.url
      a['title'] = self.title if self.title
      wrap_as_element('a', a)
    else
      maruku_error "Could not find url in #{self.inspect}"
      tell_user "Not creating a link for ref_id = #{id.inspect}."
      wrap_as_element('span')
    end
  end

  def add_ws(e)
    [xml_newline, e, xml_newline]
  end

  ##### Email address

  def obfuscate(s)
    s.bytes.inject('') do |res, char|
      res << "&#%03d;" % char
    end
  end

  def to_html_email_address
    obfuscated = obfuscate(self.email)
    html_element('a', obfuscated, :href => "mailto:#{obfuscated}")
  end

  ##### Images

  def to_html_image
    a = {}
    id = self.ref_id
    if ref = @doc.refs[sanitize_ref_id(id)] || @doc.refs[sanitize_ref_id(children_to_s)]
      a['src'] = ref[:url].to_s
      a['alt'] = children_to_s
      a['title'] = ref[:title].to_s if ref[:title]
      html_element('img', nil, a)
    else
      maruku_error "Could not find id = #{id.inspect} for\n #{self.inspect}"
      tell_user "Could not create image with ref_id = #{id.inspect};" +
        " Using SPAN element as replacement."
      wrap_as_element('span')
    end
  end

  def to_html_im_image
    if self.url
      attrs = {}
      attrs['src'] = self.url.to_s
      attrs['alt'] = children_to_s
      attrs['title'] = self.title.to_s if self.title
      html_element('img', nil, attrs)
    else
      maruku_error "Image with no url: #{self.inspect}"
      tell_user "Could not create image without a source URL;" +
        " Using SPAN element as replacement."
      wrap_as_element('span')
    end
  end

  #=begin maruku_doc
  # Attribute: filter_html
  # Scope: document
  #
  # If true, raw HTML is discarded from the output.
  #
  #=end

  def to_html_raw_html
    return [] if get_setting(:filter_html)
    return parsed_html.to_html if parsed_html

    # If there's no parsed HTML
    raw_html = self.raw_html

    # Creates red box with offending HTML
    tell_user "Wrapping bad html in a PRE with class 'markdown-html-error'\n" +
      raw_html.gsub(/^/, '|')
    pre = xelem('pre')
    pre['style'] = 'border: solid 3px red; background-color: pink'
    pre['class'] = 'markdown-html-error'
    pre << xtext("Maruku could not parse this XML/HTML: \n#{raw_html}")
  end

  def to_html_abbr
    abbr = xelem('abbr')
    abbr << xtext(children[0])
    abbr['title'] = self.title if self.title
    abbr
  end

  def to_html_footnote_reference
    id = self.footnote_id

    # save the order of used footnotes
    order = @doc.footnotes_order

    # footnote has already been used
    return [] if order.include?(id)

    return [] unless @doc.footnotes[id]

    # take next number
    order << id

    num = order.index(id) + 1

    sup = xelem('sup')
    sup['id'] = "#{get_setting(:doc_prefix)}fnref:#{num}"
    a = xelem('a')
    a << xtext(num.to_s)
    a['href'] = "\##{get_setting(:doc_prefix)}fn:#{num}"
    a['rel'] = 'footnote'
    sup << a
  end

  ## Definition lists ###
  def to_html_definition_list
    add_ws wrap_as_element('dl')
  end

  def to_html_definition
    children_to_html
  end

  def to_html_definition_term
    add_ws wrap_as_element('dt')
  end

  def to_html_definition_data
    add_ws wrap_as_element('dd')
  end

  def to_html_table
    num_columns = self.align.size

    # The table data is passed as a multi-dimensional array
    # we just need to split the head from the body
    head, *rows = @children

    table = html_element('table')
    thead = xelem('thead')
    tr = xelem('tr')
    array_to_html(head).inject(tr, &:<<)
    thead << tr
    table << thead

    tbody = xelem('tbody')
    rows.each do |row|
      tr = xelem('tr')
      array_to_html(row).each_with_index do |x, i|
        x['style'] ="text-align: #{self.align[i].to_s};"
        tr << x
      end

      tbody << tr << xml_newline
    end

    table << tbody
  end

  def to_html_head_cell
    wrap_as_element('th')
  end

  def to_html_cell
    if @attributes[:scope]
      wrap_as_element('th')
    else
      wrap_as_element('td')
    end
  end

  def to_html_entity
    entity_name = self.entity_name

    if entity = MaRuKu::Out::EntityTable.instance.entity(entity_name)
      entity_name = entity.html_num
    end

    if entity_name.kind_of? Fixnum
      # Convert numeric entities to unicode characters
      xtext([entity_name].pack('U*'))
    else
      "&#{entity_name};"
    end
  end

  def to_html_xml_instr
    target = self.target || ''
    code = self.code || ''

    # A blank target is invalid XML. Just create a text node?
    if target.empty?
      xtext("")
    else
      ""
    end
  end

  # Convert each child to html
  def children_to_html
    array_to_html(@children)
  end

  def array_to_html(array)
    e = []
    array.each do |c|
      if c.kind_of?(String)
        e << xtext(c)
      else
        if c.kind_of?(HTMLElement)
          e << c
          next
        end

        method = c.kind_of?(MaRuKu::MDElement) ? "to_html_#{c.node_type}" : "to_html"
        next unless c.respond_to?(method)

        h = c.send(method)

        unless h
          raise "Nil html created by method  #{method}:\n#{h.inspect}\n" +
            " for object #{c.inspect[0,300]}"
        end

        if h.kind_of? Array
          e.concat h
        else
          e << h
        end
      end
    end
    e
  end

  def to_html_ref_definition
    []
  end

  def to_latex_ref_definition
    []
  end
end
maruku-0.7.2/lib/maruku/output/entity_table.rb0000644000004100000410000000142512347070213021477 0ustar  www-datawww-datarequire 'rexml/document'
require 'singleton'

module MaRuKu::Out
  Entity = Struct.new(:html_num, :html_entity, :latex_string, :latex_package)

  class EntityTable
    # Sad but true
    include Singleton

    def initialize
      @entity_table = {}

      xml = File.new(File.join(File.dirname(__FILE__), '..', '..', '..', 'data', 'entities.xml'))
      doc = REXML::Document.new(xml)
      doc.elements.each("//char") do |c|
        num = c.attributes['num'].to_i
        name = c.attributes['name']
        convert = c.attributes['convertTo']
        package = c.attributes['package']

        e = Entity.new(num, name, convert, package)
        @entity_table[name] = e
        @entity_table[num] = e
      end
    end

    def entity(name)
      @entity_table[name]
    end
  end
end

maruku-0.7.2/lib/maruku/output/to_markdown.rb0000644000004100000410000001125412347070213021341 0ustar  www-datawww-datamodule MaRuKu::Out::Markdown

  DefaultLineLength = 40

  def to_md(context={})
    children_to_md(context)
  end

  # " andrea censi " => [" andrea ", "censi "]
  def mysplit(c)
    res = c.split.map {|x| x + " " }
    if c[0] == ' ' && res[0]
      res[0] = " " + res[0]
    end
    res
  end

  def to_md_header(context)
    pounds = "#" * @level
    "#{pounds} #{children_to_md(context)} #{pounds}\n\n"
  end

  def to_md_inline_code(context)
    "`#{@raw_code}`"
  end

  def to_md_code(context)
    @raw_code.split("\n").collect { |line| "     " + line}.join("\n") + "\n\n"
  end

  def to_md_quote(context)
    line_length = (context[:line_length] || DefaultLineLength) - 2
    wrap(@children, line_length, context).split(/\n/).collect { |line| "> " + line}.join("\n") + "\n"
  end

  def to_md_hrule(context)
    "* * *\n"
  end

  def to_md_emphasis(context)
    "*#{children_to_md(context)}*"
  end

  def to_md_strong(context)
    "**#{children_to_md(context)}**"
  end

  def to_md_immediate_link(context)
    "<#{@url}>"
  end

  def to_md_email_address(context)
    "<#{@email}>"
  end

  def to_md_entity(context)
    "&#{@entity_name};"
  end

  def to_md_linebreak(context)
    "\n"
  end

  def to_md_paragraph(context)
    line_length = context[:line_length] || DefaultLineLength
    wrap(@children, line_length, context)+"\n"
  end

  def to_md_im_link(context)
    "[#{children_to_md(context)}](#{@url}#{" \"#{@title}\"" if @title})"
  end

  def to_md_link(context)
    "[#{children_to_md(context)}][#{@ref_id}]"
  end

  def to_md_im_image(context)
    "![#{children_to_md(context)}](#{@url}#{" \"#{@title}\"" if @title})"
  end

  def to_md_image(context)
    "![#{children_to_md(context)}][#{@ref_id}]"
  end

  def to_md_ref_definition(context)
    "[#{@ref_id}] #{@url}#{" \"#{@title}\"" if @title}"
  end

  def to_md_abbr_def(context)
    "*[#{self.abbr}]: #{self.text}\n"
  end

  def to_md_ol(context)
    len = (context[:line_length] || DefaultLineLength) - 2
    md = ""
    self.children.each_with_index do |li, i|
      #     s = (w=wrap(li.children, len-2, context)).rstrip.gsub(/^/, '    ')+"\n"
      #     s[0,4] = "#{i+1}.  "[0,4]
      #     puts w.inspect
      s = "#{i+1}. " + wrap(li.children, len-2, context).rstrip + "\n"
      md += s
    end
    md + "\n"
  end

  def to_md_ul(context)
    len = (context[:line_length] || DefaultLineLength) - 2
    md = ""
    self.children.each_with_index do |li, i|
      w = wrap(li.children, len-2, context)
      s = "- " + w
      #     puts "W: "+ w.inspect
      #   s = add_indent(w)
      #     puts "S: " +s.inspect
      #   s[0,1] = "-"
      md += s
    end
    md + "\n"
  end

  def add_indent(s,char="    ")
    t = s.split("\n").map{|x| char+x }.join("\n")
    s << ?\n if t[-1] == ?\n
    s
  end

  # Convert each child to html
  def children_to_md(context)
    array_to_md(@children, context)
  end

  def wrap(array, line_length, context)
    out = ""
    line = ""
    array.each do |c|
      if c.kind_of?(MaRuKu::MDElement) &&  c.node_type == :linebreak
        out << line.strip << "  \n"; line="";
        next
      end

      pieces =
        if c.kind_of? String
          mysplit(c)
        elsif c.kind_of?(MaRuKu::MDElement)
          method = "to_md_#{c.node_type}"
          method = "to_md" unless c.respond_to?(method)
          [c.send(method, context)].flatten
        else
          [c.to_md(context)].flatten
        end

      #     puts "Pieces: #{pieces.inspect}"
      pieces.each do |p|
        if p.size + line.size > line_length
          out << line.strip << "\n";
          line = ""
        end
        line << p
      end
    end
    out << line.strip << "\n" if line.size > 0
    out << ?\n if not out[-1] == ?\n
    out
  end


  def array_to_md(array, context, join_char='')
    e = []
    array.each do |c|
      if c.is_a?(String)
        e << c
      else
        method = c.kind_of?(MaRuKu::MDElement) ?
        "to_md_#{c.node_type}" : "to_md"

        if not c.respond_to?(method)
          #raise "Object does not answer to #{method}: #{c.class} #{c.inspect[0,100]}"
          #       tell_user "Using default for #{c.node_type}"
          method = 'to_md'
        end

        #     puts "#{c.inspect} created with method #{method}"
        h =  c.send(method, context)

        if h.nil?
          raise "Nil md for #{c.inspect} created with method #{method}"
        end

        if h.kind_of?Array
          e = e + h
        else
          e << h
        end
      end
    end
    e.join(join_char)
  end

end

module MaRuKu
  class MDDocument
    alias old_md to_md
    def to_md(context={})
      warn "Maruku#to_md is deprecated and will be removed in a near-future version of Maruku."
      old_md(context)
    end
  end
end
maruku-0.7.2/lib/maruku/output/to_s.rb0000644000004100000410000000026512347070213017761 0ustar  www-datawww-datamodule MaRuKu

  class MDElement

    # Strips all formatting from the string
    def to_s
      children_to_s
    end

    def children_to_s
      @children.join
    end
  end
end
maruku-0.7.2/lib/maruku/inspect_element.rb0000644000004100000410000000373712347070213020642 0ustar  www-datawww-datamodule MaRuKu
  class MDElement
    INSPECT_FORMS = {
      :paragraph          => ["par",      :children],
      :footnote_reference => ["foot_ref", :footnote_id],
      :entity             => ["entity",   :entity_name],
      :email_address      => ["email",    :email],
      :inline_code        => ["code",     :raw_code],
      :raw_html           => ["html",     :raw_html],
      :emphasis           => ["em",       :children],
      :strong             => ["strong",   :children],
      :immediate_link     => ["url",      :url],
      :image              => ["image",    :children, :ref_id],
      :im_image           => ["im_image", :children, :url, :title],
      :link               => ["link",     :children, :ref_id],
      :im_link            => ["im_link",  :children, :url, :title],
      :ref_definition     => ["ref_def",  :ref_id, :url, :title],
      :ial                => ["ial",      :ial],
      :li                 => ["li",       :children, :want_my_paragraph]
    }

    # Outputs the document AST as calls to document helpers.
    # (this should be `eval`-able to get a copy of the original element).
    def inspect
      if INSPECT_FORMS.has_key? @node_type
        name, *params = INSPECT_FORMS[@node_type]

        params = params.map do |p|
          if p == :children
            children_inspect
          else
            send(p).inspect
          end
        end
        params << @al.inspect if @al && !@al.empty?
      else
        name = 'el'
        params = [self.node_type.inspect, children_inspect]
        params << @meta_priv.inspect unless @meta_priv.empty? && self.al.empty?
        params << self.al.inspect unless self.al.empty?
      end

      "md_#{name}(#{params.join(', ')})"
    end

    private

    def children_inspect
      kids = @children.map(&:inspect)
      return kids.first if kids.size == 1

      comma = kids.join(", ")
      if comma.size < 70
        "[#{comma}]"
      else
        "[\n\t#{kids.join(",\n\t")}\n]"
      end
    end
  end
end
maruku-0.7.2/lib/maruku/maruku.rb0000644000004100000410000000065412347070213016763 0ustar  www-datawww-data# The public interface for Maruku.
#
# @example Render a document fragment
# Maruku.new("## Header ##").to_html
# # => ""
class Maruku < MaRuKu::MDDocument
  def initialize(s = nil, meta = {})
    super()
    self.attributes.merge! meta
    parse_doc(s) if s
  end

  def to_s
    warn "Maruku#to_s is deprecated and will be removed or changed in a near-future version of Maruku."
    super
  end
end
maruku-0.7.2/lib/maruku/ext/0000755000004100000410000000000012347070213015725 5ustar  www-datawww-datamaruku-0.7.2/lib/maruku/ext/div.rb0000644000004100000410000000632712347070213017044 0ustar  www-datawww-data#+-----------------------------------{.warning}------
#| this is the last warning!
#|
#| please, go away!
#|
#| +------------------------------------- {.menace} --
#| | or else terrible things will happen
#| +--------------------------------------------------
#+---------------------------------------------------

# TODO: Scope these properly
OpenDiv = /^[ ]{0,3}\+\-\-+\s*(\{([^{}]*?|".*?"|'.*?')*\})?\s*\-*\s*$/
CloseDiv = /^[ ]{0,3}\=\-\-+\s*(\{([^{}]*?|".*?"|'.*?')*\})?\s*\-*\s*$/
StartPipe = /^[ ]{0,3}\|(.*)$/ # $1 is rest of line
DecorativeClosing = OpenDiv

MaRuKu::In::Markdown.register_block_extension(
  :regexp  => OpenDiv,
  :handler => lambda do |doc, src, context|
    first = src.shift_line
    ial_at_beginning = first[OpenDiv, 1]
    ial_at_end = nil

    lines = []
    # if second line starts with "|"
    if src.cur_line =~ StartPipe
      # then we read until no more "|"
      while src.cur_line && src.cur_line =~ StartPipe
        lines.push $1
        src.shift_line
      end
      if src.cur_line =~ DecorativeClosing
        ial_at_end = $1
        src.shift_line
      end
    else
      # else we read until CloseDiv
      divs_open = 1
      while src.cur_line && divs_open > 0
        if src.cur_line =~ CloseDiv
          divs_open -= 1
          if divs_open == 0
            ial_at_end = $1
            src.shift_line
            break
          else
            lines.push src.shift_line
          end
        else
          if src.cur_line =~ OpenDiv
            divs_open += 1
          end
          lines.push src.shift_line
        end
      end

      if divs_open > 0
        doc.maruku_error("At end of input, I still have #{divs_open} DIVs open.",
          src, context)
        next true
      end
    end

    ial_at_beginning = nil unless ial_at_beginning && ial_at_beginning.size > 0
    ial_at_end = nil unless ial_at_end && ial_at_end.size > 0

    if ial_at_beginning && ial_at_end
      doc.maruku_error("Found two conflicting IALs: #{ial_at_beginning.inspect} and #{ial_at_end.inspect}",
        src, context)
    end

    al_string = ial_at_beginning || ial_at_end
    al = nil

    if al_string =~ /^\{(.*)\}\s*$/
      al = al_string && doc.read_attribute_list(
        MaRuKu::In::Markdown::SpanLevelParser::CharSource.new($1),
        nil, [nil])
    end

    context.push(
      doc.md_div(
        doc.parse_blocks(
          MaRuKu::In::Markdown::BlockLevelParser::LineSource.new(lines)),
        al))
    true
  end)

module MaRuKu
  class MDElement
    def md_div(children, al = nil)
      type = label = num = nil
      doc.refid2ref ||= {}
      if al
        al.each do |k, v|
          case k
          when :class; type = $1 if v =~ /^num_(\w*)/
          when :id; label = v
          end
        end
      end

      if type
        doc.refid2ref[type] ||= {}
        num = doc.refid2ref[type].length + 1
        if !label
          doc.id_counter += 1
      		label =  "div_" + doc.id_counter.to_s
        end
      end

      e = self.md_el(:div, children, {:label => label, :type => type, :num => num}, al)
      doc.refid2ref[type].update(label => e) if type && label
      e
    end
  end

  module Out
    module HTML
      def to_html_div
        add_ws wrap_as_element('div')
      end
    end
  end
end
maruku-0.7.2/lib/maruku/ext/math.rb0000644000004100000410000000156212347070213017207 0ustar  www-datawww-datarequire 'maruku/ext/math/elements'
require 'maruku/ext/math/parsing'
require 'maruku/ext/math/to_latex'
require 'maruku/ext/math/to_html'

require 'maruku/ext/math/mathml_engines/none'
require 'maruku/ext/math/mathml_engines/ritex'
require 'maruku/ext/math/mathml_engines/itex2mml'
require 'maruku/ext/math/mathml_engines/blahtex'

#=begin maruku_doc
# Attribute: math_enabled
# Scope: global, document
# Summary: Enables parsing of LaTeX math
#
# To explicitly disable the math parsing:
#
# 	Maruku.new(string, {:math_enabled => false})
# 	{:ruby}
#
#=end

MaRuKu::Globals[:math_enabled] = true


#=begin maruku_doc
# Attribute: math_numbered
# Scope: global, document
# Summary: Math openings which should be numerated
#
# Array containing any of `'\\['`, `'\\begin{equation}'`, `'$$'`.
#
# 	MaRuKu::Globals[:math_numbered] = ['\\[']
#
#=end

MaRuKu::Globals[:math_numbered] = []
maruku-0.7.2/lib/maruku/ext/fenced_code.rb0000644000004100000410000000607312347070213020476 0ustar  www-datawww-data# fenced_code.rb -- Maruku extension for fenced code blocks
#
# Copyright (C) 2009 Jason R. Blevins
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#  * Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#
#  * Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
#  * Neither the names of the copyright holders nor the names of any
#    contributors may be used to endorse or promote products derived from this
#    software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.


# 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'
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Or:
#
# ```ruby
# puts 'Hello world'
# ```
#

#=begin maruku_doc
# Attribute: :fenced_code_blocks
# Scope: global, document
# Summary: Enables fenced code blocks
#=end

module Maruku::In::Markdown
  module FencedCode
    OpenFence = /^([`~]{3,})(\w+)?\s*(\{([^{}]*?|".*?"|'.*?')*\})?\s*$/
  end
end

MaRuKu::In::Markdown::register_block_extension(
  :regexp  => Maruku::In::Markdown::FencedCode::OpenFence,
  :handler => lambda do |doc, src, context|
    return false unless doc.get_setting :fenced_code_blocks

    first = src.shift_line
    first =~ Maruku::In::Markdown::FencedCode::OpenFence
    close_fence = /^#{$1}[`~]*$/
    lang = $2
    ial = $3

    lines = []

    # read until CloseFence
    while src.cur_line
      if src.cur_line =~ close_fence
        src.shift_line
        break
      else
        lines << 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))
    end

    source = lines.join("\n")
    context.push doc.md_codeblock(source, lang, al)
    true
  end
)
maruku-0.7.2/lib/maruku/ext/math/0000755000004100000410000000000012347070213016656 5ustar  www-datawww-datamaruku-0.7.2/lib/maruku/ext/math/to_latex.rb0000644000004100000410000000155412347070213021027 0ustar  www-datawww-datamodule MaRuKu
  module Out
    module Latex
      def to_latex_inline_math
        fix_latex("$#{self.math.strip}$")
      end

      def to_latex_equation
        if self.label
          fix_latex("\\begin{equation}\n#{self.math.strip}\n\\label{#{self.label}}\\end{equation}\n")
        else
          fix_latex("\\begin{displaymath}\n#{self.math.strip}\n\\end{displaymath}\n")
        end
      end

      def to_latex_eqref
        "\\eqref{#{self.eqid}}"
      end

      def to_latex_divref
        "\\ref{#{self.refid}}"
      end

      private

      def fix_latex(str)
        return str unless self.get_setting(:html_math_engine) == 'itex2mml'
        s = str.gsub("\\mathop{", "\\operatorname{")
        s.gsub!(/\\begin\{svg\}.*?\\end\{svg\}/m, " ")
        s.gsub!("\\array{","\\itexarray{")
        s.gsub("\\space{", "\\itexspace{")
      end
    end
  end
end
maruku-0.7.2/lib/maruku/ext/math/to_html.rb0000644000004100000410000001155312347070213020656 0ustar  www-datawww-data#=begin maruku_doc
# Extension: math
# Attribute: html_math_engine
# Scope: document, element
# Output: html
# Summary: Select the rendering engine for MathML.
# Default: 
#
# Select the rendering engine for math.
#
# If you want to use your custom engine `foo`, then set:
#
#   HTML math engine: foo
# {:lang=markdown}
#
# and then implement two functions:
#
#   def convert_to_mathml_foo(kind, tex)
#     ...
#   end
#=end

#=begin maruku_doc
# Extension: math
# Attribute: html_png_engine
# Scope: document, element
# Output: html
# Summary: Select the rendering engine for math.
# Default: 
#
# Same thing as `html_math_engine`, only for PNG output.
#
#   def convert_to_png_foo(kind, tex)
#     # same thing
#     ...
#   end
# {:lang=ruby}
#
#=end

module MaRuKu
  module Out
    module HTML
      # Creates an xml Mathml document of this node's TeX code.
      #
      # @return [MaRuKu::Out::HTML::HTMLElement]
      def render_mathml(kind, tex)
        engine = get_setting(:html_math_engine)
        method = "convert_to_mathml_#{engine}"
        if self.respond_to? method
          mathml = self.send(method, kind, tex)
          return mathml || convert_to_mathml_none(kind, tex)
        end

        # TODO: Warn here
        raise "A method called #{method} should be defined."
        convert_to_mathml_none(kind, tex)
      end

      # Renders a PNG image of this node's TeX code.
      # Returns
      #
      # @return [MaRuKu::Out::HTML::PNG, nil]
      #   A struct describing the location and size of the image,
      #   or nil if no library is loaded that can render PNGs.
      def render_png(kind, tex)
        engine = get_setting(:html_png_engine)
        method = "convert_to_png_#{engine}".to_sym
        return self.send(method, kind, tex) if self.respond_to? method

        raise "A method called #{method} should be defined."
        nil
      end

      def pixels_per_ex
        $pixels_per_ex ||= render_png(:inline, "x").height
      end

      def adjust_png(png, use_depth)
        src = png.src

        height_in_px = png.height
        depth_in_px = png.depth
        height_in_ex = height_in_px / pixels_per_ex
        depth_in_ex = depth_in_px / pixels_per_ex
        total_height_in_ex = height_in_ex + depth_in_ex
        style = ""
        style << "vertical-align: -#{depth_in_ex}ex;" if use_depth
        style << "height: #{total_height_in_ex}ex;"

        img = xelem('img')
        img['src'] = src
        img['style'] = style
        img['alt'] = "$#{self.math.strip}$"
        img['class'] = 'maruku-png'
        img
      end

      def to_html_inline_math
        mathml = get_setting(:html_math_output_mathml) && render_mathml(:inline, self.math)
        if mathml
          mathml.add_class('maruku-mathml')
          return mathml.to_html
        end

        png = get_setting(:html_math_output_png) && render_png(:inline, self.math)

        HTMLElement.new 'span', 'class' => 'maruku-inline' do
          # TODO: It seems weird that we output an empty span if there's no PNG
          if png
            adjust_png(png, true)
          end
        end
      end

      def to_html_equation
        mathml = get_setting(:html_math_output_mathml) && render_mathml(:equation, self.math)
        png    = get_setting(:html_math_output_png)    && render_png(:equation, self.math)

        div = xelem('div')
        div['class'] = 'maruku-equation'
        if mathml
          if self.label  # then numerate
            span = xelem('span')
            span['class'] = 'maruku-eq-number'
            span << xtext("(#{self.num})")
            div << span
            div['id'] = "eq:#{self.label}"
          end
          mathml.add_class('maruku-mathml')
          div << mathml.to_html
        end

        if png
          img = adjust_png(png, false)
          div << img
          if self.label  # then numerate
            span = xelem('span')
            span['class'] = 'maruku-eq-number'
            span << xtext("(#{self.num})")
            div << span
            div['id'] = "eq:#{self.label}"
          end
        end

        div
      end

      def to_html_eqref
        unless eq = self.doc.eqid2eq[self.eqid]
          maruku_error "Cannot find equation #{self.eqid.inspect}"
          return xtext("(eq:#{self.eqid})")
        end

        a = xelem('a')
        a['class'] = 'maruku-eqref'
        a['href'] = "#eq:#{self.eqid}"
        a << xtext("(#{eq.num})")
        a
      end

      def to_html_divref
        unless hash = self.doc.refid2ref.values.find {|h| h.has_key?(self.refid)}
          maruku_error "Cannot find div #{self.refid.inspect}"
          return xtext("\\ref{#{self.refid}}")
        end
        ref= hash[self.refid]

        a = xelem('a')
        a['class'] = 'maruku-ref'
        a['href'] = "#" + self.refid
        a << xtext(ref.num.to_s)
        a
      end
    end
  end
end
maruku-0.7.2/lib/maruku/ext/math/elements.rb0000644000004100000410000000120012347070213021010 0ustar  www-datawww-datamodule MaRuKu
  class MDElement
    def md_inline_math(math)
      self.md_el(:inline_math, [], :math => math)
    end

    def md_equation(math, label, numerate)
      reglabel = /\\label\{(\w+)\}/
      math = math.gsub(reglabel, '') if label = math[reglabel, 1]
      num = nil
      if (label || numerate) && @doc # take number
        @doc.eqid2eq ||= {}
        num = @doc.eqid2eq.size + 1
        label = "eq#{num}" unless label # TODO do id for document
      end
      e = self.md_el(:equation, [], :math => math, :label => label, :num => num)
      @doc.eqid2eq[label] = e if label && @doc # take number
      e
    end
  end
end
maruku-0.7.2/lib/maruku/ext/math/mathml_engines/0000755000004100000410000000000012347070213021650 5ustar  www-datawww-datamaruku-0.7.2/lib/maruku/ext/math/mathml_engines/ritex.rb0000644000004100000410000000106712347070213023334 0ustar  www-datawww-datamodule MaRuKu::Out::HTML
	def convert_to_mathml_ritex(kind, tex)
		begin
			if not $ritex_parser
				require 'ritex'
			 	$ritex_parser = Ritex::Parser.new
			end
			
			mathml =  $ritex_parser.parse(tex.strip)
			doc = Document.new(mathml, {:respect_whitespace =>:all}).root
			return doc
		rescue LoadError => e
			maruku_error "Could not load package 'ritex'.\n"+
			"Please install it using:\n"+
			"   $ gem install ritex\n\n"+e.inspect
		rescue Racc::ParseError => e
			maruku_error "Could not parse TeX: \n#{tex}"+
				"\n\n #{e.inspect}"
		end
		nil
	end
end
maruku-0.7.2/lib/maruku/ext/math/mathml_engines/blahtex.rb0000644000004100000410000000514112347070213023625 0ustar  www-datawww-datarequire 'fileutils'
require 'digest/md5'
require 'rexml/document'

module MaRuKu::Out::HTML
  PNG = Struct.new(:src, :depth, :height)

  def convert_to_png_blahtex(kind, tex)
    FileUtils.mkdir_p get_setting(:html_png_dir)

    # first, we check whether this image has already been processed
    md5sum = Digest::MD5.hexdigest(tex + " params: ")
    result_file = File.join(get_setting(:html_png_dir), md5sum + ".txt")

    if File.exists?(result_file)
      result = File.read(result_file)
    else
      args = [
              '--png',
              '--use-preview-package',
              '--shell-dvipng',
              "dvipng -D #{Shellwords.shellescape(get_setting(:html_png_resolution).to_s)}",
              "--temp-directory #{Shellwords.shellescape(get_setting(:html_png_dir))}",
              "--png-directory #{Shellwords.shellescape(get_setting(:html_png_dir))}"
             ]
      args << '--displaymath' if kind == :equation

      result = run_blahtex(tex, args)
    end

    if result.nil? || result.empty?
      maruku_error "Blahtex error: empty output"
      return
    end

    doc = REXML::Document.new(result)
    png = doc.root.elements.to_a.first
    if png.name != 'png'
      maruku_error "Blahtex error: \n#{doc}"
      return
    end

    raise "No depth element in:\n #{doc}" unless depth = png.xpath('//depth')[0]
    raise "No height element in:\n #{doc}" unless height = png.xpath('//height')[0]
    raise "No md5 element in:\n #{doc}" unless md5 = png.xpath('//md5')[0]

    depth = depth.text.to_f
    height = height.text.to_f
    raise "Height or depth was 0! in \n #{doc}" if height == 0 || depth == 0

    md5 = md5.text

    PNG.new("#{get_setting(:html_png_url)}#{md5}.png", depth, height)
  rescue => e
    maruku_error "Error: #{e}"
    nil
  end

  def convert_to_mathml_blahtex(kind, tex)
    result = run_blahtex(tex, %w[--mathml])

    doc = REXML::Document.new(result)
    mathml = doc.get_elements('//markup').to_a.first
    unless mathml
      maruku_error "Blahtex error: \n#{doc}"
      return nil
    end

    mathml.name = 'math'
    mathml.attributes['xmlns'] = "http://www.w3.org/1998/Math/MathML"
    mathml.attributes['display'] = (kind == :inline) ? :inline : :block

    MaRuKu::HTMLFragment.new(mathml.to_s)
  rescue => e
    maruku_error "Error: #{e}"
    nil
  end

  private

  # Run blahtex, return output
  def run_blahtex(tex, args)
    IO.popen(['blahtex', *args].join(' '), 'w+') do |blahtex|
      blahtex.write tex
      blahtex.close_write

      output = blahtex.read
      blahtex.close_read

      raise "Error running blahtex" unless $?.success?

      output
    end
  end
end
maruku-0.7.2/lib/maruku/ext/math/mathml_engines/none.rb0000644000004100000410000000031012347070213023126 0ustar  www-datawww-datamodule MaRuKu::Out::HTML
  def convert_to_mathml_none(kind, tex)
    code = xelem('code')
    tex_node = xtext(tex)
    code << tex_node
  end

  def convert_to_png_none(kind, tex)
    nil
  end
end

maruku-0.7.2/lib/maruku/ext/math/mathml_engines/itex2mml.rb0000644000004100000410000000155512347070213023744 0ustar  www-datawww-datamodule MaRuKu::Out::HTML
  def convert_to_mathml_itex2mml(kind, tex)
    return if $already_warned_itex2mml
    begin
      require 'itextomml'
    rescue LoadError => e
      maruku_error "Could not load package 'itex2mml'.\nPlease install it." unless $already_warned_itex2mml
      $already_warned_itex2mml = true
      return nil
    end

    begin
      require 'instiki_stringsupport'
    rescue LoadError
      require 'itex_stringsupport'
    end

    parser = Itex2MML::Parser.new
    mathml =
      case kind
      when :equation
        parser.block_filter(tex)
      when :inline
        parser.inline_filter(tex)
      else
        maruku_error "Unknown itex2mml kind: #{kind}"
        return
      end

    MaRuKu::HTMLFragment.new(mathml.to_utf8)
  rescue => e
    maruku_error "Invalid MathML TeX: \n#{tex.gsub(/^/, 'tex>')}\n\n #{e.inspect}"
    nil
  end
end

maruku-0.7.2/lib/maruku/ext/math/parsing.rb0000644000004100000410000000635012347070213020652 0ustar  www-datawww-datamodule MaRuKu
  class MDDocument
    # A hash of equation ids to equation elements
    #
    # @return [String => MDElement]
    attr_accessor :eqid2eq

    def is_math_enabled?
      get_setting :math_enabled
    end
  end
end

# TODO: Properly scope all these regexps
# Everything goes; takes care of escaping the "\$" inside the expression
RegInlineMath = /\${1}((?:[^\$]|\\\$)+)\$/

MaRuKu::In::Markdown.register_span_extension(
  :chars => '$',
  :regexp => RegInlineMath,
  :handler => lambda do |doc, src, con|
    next false unless doc.is_math_enabled?
    next false unless m = src.read_regexp(RegInlineMath)
    math = m.captures.compact.first
    con.push doc.md_inline_math(math)
    true
  end)


MathOpen1 = Regexp.escape('\\begin{equation}')
MathClose1 = Regexp.escape('\\end{equation}')
MathOpen2 = Regexp.escape('\\[')
MathClose2 = Regexp.escape('\\]')
MathOpen3 = Regexp.escape('$$')
MathClose3 = Regexp.escape('$$')

EqLabel = /(?:\((\w+)\))/
EquationOpen = /#{MathOpen1}|#{MathOpen2}|#{MathOpen3}/
EquationClose = /#{MathClose1}|#{MathClose2}|#{MathClose3}/

# $1 is opening, $2 is tex
EquationStart = /^[ ]{0,3}(#{EquationOpen})(.*)$/
# $1 is tex, $2 is closing, $3 is tex
EquationEnd = /^(.*)(#{EquationClose})\s*#{EqLabel}?\s*$/
# $1 is opening, $2 is tex, $3 is closing, $4 is label
OneLineEquation = /^[ ]{0,3}(#{EquationOpen})(.*)(#{EquationClose})\s*#{EqLabel}?\s*$/

MaRuKu::In::Markdown.register_block_extension(
  :regexp  => EquationStart,
  :handler => lambda do |doc, src, con|
    next false unless doc.is_math_enabled?
    first = src.shift_line
    if first =~ OneLineEquation
      opening, tex, closing, label = $1, $2, $3, $4
      numerate = doc.get_setting(:math_numbered).include?(opening)
      con.push doc.md_equation(tex, label, numerate)
      next true
    end

    opening, tex = first.scan(EquationStart).first
    # ensure newline at end of first line of equation isn't swallowed
    tex << "\n"
    numerate = doc.get_setting(:math_numbered).include?(opening)
    label = nil
    loop do
      unless src.cur_line
        doc.maruku_error(
          "Stream finished while reading equation\n\n" + tex.gsub(/^/, '$> '),
          src, con)
        break
      end

      line = src.shift_line
      if line =~ EquationEnd
        tex_line, closing = $1, $2
        label = $3 if $3
        tex << tex_line << "\n"
        break
      end

      tex << line << "\n"
    end
    con.push doc.md_equation(tex, label, numerate)
    true
  end)


# This adds support for \eqref
RegEqrefLatex = /\\eqref\{(\w+?)\}/
RegEqPar = /\(eq:(\w+?)\)/
RegEqref = Regexp.union(RegEqrefLatex, RegEqPar)

MaRuKu::In::Markdown.register_span_extension(
  :chars => ["\\", '('],
  :regexp => RegEqref,
  :handler => lambda do |doc, src, con|
    return false unless doc.is_math_enabled?
    eqid = src.read_regexp(RegEqref).captures.compact.first
    con.push doc.md_el(:eqref, [], :eqid => eqid)
    true
  end)

# This adds support for \ref
RegRef = /\\ref\{(\w*?)\}/
MaRuKu::In::Markdown.register_span_extension(
  :chars => ["\\", '('],
  :regexp => RegRef,
  :handler => lambda do |doc, src, con|
    return false unless doc.is_math_enabled?
    refid = src.read_regexp(RegRef).captures.compact.first
    con.push doc.md_el(:divref, [], :refid => refid)
    true
  end)
maruku-0.7.2/lib/maruku/element.rb0000644000004100000410000000727512347070213017116 0ustar  www-datawww-datamodule MaRuKu
  # Rather than having a separate class for every possible element,
  # Maruku has a single {MDElement} class
  # that represents eveything in the document (paragraphs, headers, etc).
  # The type of each element is available via \{#node\_type}.
  class MDElement
    # The type of this node (e.g. `:quote`, `:image`, `:abbr`).
    # See {Helpers} for a list of possible values.
    #
    # @return [Symbol]
    attr_accessor :node_type

    # The child nodes of this element.
    #
    # @return [Array]
    attr_accessor :children

    # An attribute list. May not be nil.
    #
    # @return [AttributeList]
    attr_accessor :al

    # The processed attributes.
    #
    # For the {Maruku document root},
    # this contains properties listed
    # at the beginning of the document.
    # The properties will be downcased and any spaces
    # will be converted to underscores.
    # For example, if you write in the source document:
    #
    #     !!!text
    #     Title: test document
    #     My property: value
    #
    #     content content
    #
    # Then \{#attributes} will return:
    #
    #     {:title => "test document", :my_property => "value"}
    #
    # @return [{Symbol => String}]
    attr_accessor :attributes

    # The root element of the document
    # to which this element belongs.
    #
    # @return [Maruku]
    attr_accessor :doc

    def initialize(node_type = :unset, children = [], meta = {}, al = nil)
      self.children = children
      self.node_type = node_type
      self.attributes = {}

      # Define a new accessor on the singleton class for this instance
      # for each metadata key
      meta.each do |symbol, value|
        class << self
          self
        end.send(:attr_accessor, symbol)

        self.send("#{symbol}=", value)
      end

      self.al = al || AttributeList.new
      self.meta_priv = meta
    end

    # @private
    attr_accessor :meta_priv

    def ==(o)
      o.is_a?(MDElement) &&
        self.node_type == o.node_type &&
        self.meta_priv == o.meta_priv &&
        self.children == o.children
    end

    # Iterates through each {MDElement} child node of this element.
    # This includes deeply-nested child nodes.
    # If `e_node_type` is specified, only yields nodes of that type.
    def each_element(e_node_type=nil, &block)
      @children.each do |c|
        if c.is_a? MDElement then
          yield c if e_node_type.nil? || c.node_type == e_node_type
          c.each_element(e_node_type, &block)
        #
        # This handles the case where the children of an
        # element are arranged in a multi-dimensional array
        # (as in the case of a table)
        elsif c.is_a? Array then
          c.each do |cc|
            # A recursive call to each_element will ignore the current element
            # so we handle this case inline
            if cc.is_a? MDElement then
              yield cc if e_node_type.nil? || cc.node_type == e_node_type
              cc.each_element(e_node_type, &block)
            end
          end
        end

      end
    end

    # Iterates through each String child node of this element,
    # replacing it with the result of the block.
    # This includes deeply-nested child nodes.
    #
    # This destructively modifies this node and its children.
    #
    # @todo Make this non-destructive
    def replace_each_string(&block)
      @children.map! do |c|
        next yield c unless c.is_a?(MDElement)
        c.replace_each_string(&block)
        c
      end.flatten!
    end
  end

  # A specialization of Element that can keep track of
  # its parsed HTML as an attribute (rather than metadata)
  class MDHTMLElement < MDElement
    attr_accessor :parsed_html # HTMLFragment
  end
end
maruku-0.7.2/lib/maruku/html.rb0000644000004100000410000002057512347070213016427 0ustar  www-datawww-datarequire 'set'

$warned_nokogiri = false

module MaRuKu
  HTML_INLINE_ELEMS = Set.new %w[a abbr acronym audio b bdi bdo big br button canvas caption cite code
    col colgroup command datalist del details dfn dir em fieldset font form i img input ins
    kbd label legend mark meter optgroup option progress q rp rt ruby s samp select small
    source span strike strong sub summary sup tbody td tfoot th thead time tr track tt u var video wbr
    animate animateColor animateMotion animateTransform circle clipPath defs desc ellipse
    feGaussianBlur filter font-face font-face-name font-face-src foreignObject g glyph hkern
    linearGradient line marker mask metadata missing-glyph mpath path pattern polygon polyline
    radialGradient rect set stop svg switch text textPath title tspan use
    annotation annotation-xml maction math menclose merror mfrac mfenced mi mmultiscripts mn mo
    mover mpadded mphantom mprescripts mroot mrow mspace msqrt mstyle msub msubsup msup mtable
    mtd mtext mtr munder munderover none semantics]

  # Parse block-level markdown elements in these HTML tags
  BLOCK_TAGS = Set.new %w[div section]

  # This gets mixed into HTML MDElement nodes to hold the parsed document fragment
  module HTMLElement
    attr_accessor :parsed_html
  end

  # This is just a factory, not an actual class
  module HTMLFragment

    # HTMLFragment.new produces a concrete HTMLFragment implementation
    # that is either a NokogiriHTMLFragment or a REXMLHTMLFragment.
    def self.new(raw_html)
      if !$warned_nokogiri && MaRuKu::Globals[:html_parser] == 'nokogiri'
        begin
          require 'nokogiri'
          return NokogiriHTMLFragment.new(raw_html)
        rescue LoadError
          warn "Nokogiri could not be loaded. Falling back to REXML."
          $warned_nokogiri = true
        end
      end

      require 'rexml/document'
      REXMLHTMLFragment.new(raw_html)
    end
  end

  # Nokogiri backend for HTML handling
  class NokogiriHTMLFragment
    def initialize(raw_html)
      # Wrap our HTML in a dummy document with a doctype (just
      # for the entity references)
      wrapped = '
' + raw_html.strip + ''

      d = Nokogiri::XML::Document.parse(wrapped) {|c| c.nonet }
      @fragment = d.root
    end

    # @return The name of the first child element in the fragment.
    def first_node_name
      first_child = @fragment.children.first
      first_child ? first_child.name : nil
    end

    # Add a class to the children of this fragment
    def add_class(class_name)
      @fragment.children.each do |c|
        c['class'] = ((c['class']||'').split(' ') + [class_name]).join(' ')
      end
    end

    # Process markdown within the contents of some elements and
    # replace their contents with the processed version.
    #
    # @param doc [MaRuKu::MDDocument] A document to process.
    def process_markdown_inside_elements(doc)
      # find span elements or elements with 'markdown' attribute
      elts = @fragment.css("[markdown]")

      d = @fragment.children.first
      if d && HTML_INLINE_ELEMS.include?(d.name)
        elts << d unless d.attribute('markdown')
        elts += span_descendents(d)
      end

      elts.each do |e|
        how = e['markdown']
        e.remove_attribute('markdown')

        next if "0" == how # user requests no markdown parsing inside
        parse_blocks = (how == 'block') || BLOCK_TAGS.include?(e.name)

        # Select all text children of e
        e.xpath("./text()").each do |original_text|
          s = MaRuKu::Out::HTML.escapeHTML(original_text.text)
          unless s.strip.empty?
            parsed = parse_blocks ? doc.parse_text_as_markdown(s) : doc.parse_span(s)

            # restore leading and trailing spaces
            padding = /\A(\s*).*?(\s*)\z/.match(s)
            parsed = [padding[1]] + parsed + [padding[2]] if padding

            el = doc.md_el(:dummy, parsed)

            # Nokogiri collapses consecutive Text nodes, so replace it by a dummy element
            guard = Nokogiri::XML::Element.new('guard', @fragment)
            original_text.replace(guard)
            el.children_to_html.each do |x|
              guard.before(x.to_s)
            end
            guard.remove
          end
        end
      end
    end

    # Convert this fragment to an HTML or XHTML string.
    # @return [String]
    def to_html
      output_options = Nokogiri::XML::Node::SaveOptions::DEFAULT_XHTML ^
        Nokogiri::XML::Node::SaveOptions::FORMAT
      @fragment.children.inject("") do |out, child|
        out << child.serialize(:save_with => output_options, :encoding => 'UTF-8')
      end
    end

    private

    # Get all span-level descendents of the given element, recursively,
    # as a flat NodeSet.
    #
    # @param e [Nokogiri::XML::Node] An element.
    # @return [Nokogiri::XML::NodeSet]
    def span_descendents(e)
      ns = Nokogiri::XML::NodeSet.new(Nokogiri::XML::Document.new)
      e.element_children.inject(ns) do |descendents, c|
        if HTML_INLINE_ELEMS.include?(c.name)
          descendents << c
          descendents += span_descendents(c)
        end
        descendents
      end
    end
  end

  # An HTMLFragment implementation using REXML
  class REXMLHTMLFragment
    def initialize(raw_html)
      wrapped = '
' + raw_html.strip + ''

      @fragment = REXML::Document.new(wrapped).root
    end

    # The name of the first element in the fragment
    def first_node_name
      first_child = @fragment.children.first
      (first_child && first_child.respond_to?(:name)) ? first_child.name : nil
    end

    # Add a class to the children of this fragment
    def add_class(class_name)
      @fragment.each_element do |c|
        c.attributes['class'] = ((c.attributes['class']||'').split(' ') + [class_name]).join(' ')
      end
    end

    # Process markdown within the contents of some elements and
    # replace their contents with the processed version.
    def process_markdown_inside_elements(doc)
      elts = []
      @fragment.each_element('//*[@markdown]') do |e|
        elts << e
      end

      d = @fragment.children.first
      if d && HTML_INLINE_ELEMS.include?(first_node_name)
        elts << d unless d.attributes['markdown']
        elts += span_descendents(d)
      end

      # find span elements or elements with 'markdown' attribute
      elts.each do |e|
        # should we parse block-level or span-level?
        how = e.attributes['markdown']
        e.attributes.delete('markdown')

        next if "0" == how # user requests no markdown parsing inside
        parse_blocks = (how == 'block') || BLOCK_TAGS.include?(e.name)

        # Select all text children of e
        e.texts.each do |original_text|
          s = MaRuKu::Out::HTML.escapeHTML(original_text.value)
          unless s.strip.empty?
            # TODO extract common functionality
            parsed = parse_blocks ? doc.parse_text_as_markdown(s) : doc.parse_span(s)
            # restore leading and trailing spaces
            padding = /\A(\s*).*?(\s*)\z/.match(s)
            parsed = [padding[1]] + parsed + [padding[2]] if padding

            el = doc.md_el(:dummy, parsed)

            new_html = ""
            el.children_to_html.each do |x|
              new_html << x.to_s
            end
            new_html << ""

            newdoc = REXML::Document.new(new_html).root

            p = original_text.parent
            newdoc.children.each do |c|
              p.insert_before(original_text, c)
            end

            p.delete(original_text)
          end
        end
      end
    end

    def to_html
      formatter = REXML::Formatters::Default.new(true)
      @fragment.children.inject("") do |out, child|
        out << formatter.write(child, '')
      end
    end

    private

    # Get all span-level descendents of the given element, recursively,
    # as an Array.
    #
    # @param e [REXML::Element] An element.
    # @return [Array]
    def span_descendents(e)
      descendents = []
      e.each_element do |c|
        name = c.respond_to?(:name) ? c.name : nil
        if name && HTML_INLINE_ELEMS.include?(c.name)
          descendents << c
          descendents += span_descendents(c)
        end
      end
    end
  end
end
maruku-0.7.2/lib/maruku.rb0000644000004100000410000000622512347070213015457 0ustar  www-datawww-data#--
# Copyright (c) 2006 Andrea Censi
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++

module MaRuKu
  module In
    module Markdown
      module SpanLevelParser; end
      module BlockLevelParser; end
    end
  end

  module Out
    module Markdown; end
    module HTML; end
    module Latex; end
  end

  module Strings; end

  module Helpers; end

  module Errors; end

  class MDElement
    include MaRuKu
    include Out::Markdown
    include Out::HTML
    include Out::Latex
    include Strings
    include Helpers
    include Errors
  end

  class MDDocument < MDElement
    include In::Markdown
    include In::Markdown::SpanLevelParser
    include In::Markdown::BlockLevelParser
  end
end

class Maruku < MaRuKu::MDDocument; end


# Structures definition
require 'maruku/attributes'
require 'maruku/element'
require 'maruku/document'
require 'maruku/inspect_element'

require 'maruku/defaults'

# Less typing
require 'maruku/helpers'

# Code for parsing whole Markdown documents
require 'maruku/input/parse_doc'

# Ugly things kept in a closet
require 'maruku/string_utils'
require 'maruku/input/linesource'
require 'maruku/input/mdline'

# A class for reading and sanitizing inline HTML
require 'maruku/input/html_helper'

# Code for parsing Markdown block-level elements
require 'maruku/input/parse_block'

# Code for parsing Markdown span-level elements
require 'maruku/input/charsource'
require 'maruku/input/parse_span'

require 'maruku/input/extensions'

require 'maruku/errors'

# Code for creating a table of contents
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'

# Entity conversion for HTML and LaTeX
require 'maruku/output/entity_table'

# Exporting to html
require 'maruku/output/to_html'

# Exporting to latex
require 'maruku/output/to_latex'

# Pretty print
require 'maruku/output/to_markdown'

# S5 slides
require 'maruku/output/s5/to_s5'
require 'maruku/output/s5/fancy'

# Exporting to text: strips all formatting (not complete)
require 'maruku/output/to_s'

# class Maruku is the global interface
require 'maruku/maruku'
maruku-0.7.2/MIT-LICENSE.txt0000644000004100000410000000204012347070213015321 0ustar  www-datawww-dataCopyright (c) 2006 Andrea Censi

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
maruku-0.7.2/metadata.yml0000644000004100000410000002145212347070213015362 0ustar  www-datawww-data--- !ruby/object:Gem::Specification
name: maruku
version: !ruby/object:Gem::Version
  version: 0.7.2
platform: ruby
authors:
- Andrea Censi
- Nathan Weizenbaum
- Ben Hollis
autorequire: 
bindir: bin
cert_chain:
- |
  -----BEGIN CERTIFICATE-----
  MIIDbDCCAlSgAwIBAgIBATANBgkqhkiG9w0BAQUFADA+MQwwCgYDVQQDDANiZW4x
  GTAXBgoJkiaJk/IsZAEZFgliZW5ob2xsaXMxEzARBgoJkiaJk/IsZAEZFgNuZXQw
  HhcNMTQwNTI2MjExNjI2WhcNMTUwNTI2MjExNjI2WjA+MQwwCgYDVQQDDANiZW4x
  GTAXBgoJkiaJk/IsZAEZFgliZW5ob2xsaXMxEzARBgoJkiaJk/IsZAEZFgNuZXQw
  ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYZvEbHldtIRP8nQNyM6SQ
  oqi6pF1VznSiOzVIZi84MnTwab4jl4pEso/tnjpm+jpHoFc1RhJMwwaO9v0ih5/e
  VRZFZQyoKrPaP9Dq3q1iO9SXwoucGfoVCcvtfF2DGnFlkDZlswPWNdL/GTxuiM6X
  dzQ36hzSSZrgTms1AdPSuCHt3LTNRDSkpRGqDWdsPbKLi7eLSkGbUO1Ibe8JAtdE
  ueSaVAksFJvNgUxZHMSBkSrd33PRpiSi2g6IvogoeWGj+4vxJgGbPGGWHmsfVT28
  ggEdA8Ix8y223pCovPUJtCEoEdoNxTq7NUA9lUL2rZ0URc2jCiEKzQmtRAf8ZWSn
  AgMBAAGjdTBzMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSL7ijr
  kd/8I5COGX6gWvHNSCPyTDAcBgNVHREEFTATgRFiZW5AYmVuaG9sbGlzLm5ldDAc
  BgNVHRIEFTATgRFiZW5AYmVuaG9sbGlzLm5ldDANBgkqhkiG9w0BAQUFAAOCAQEA
  PHS/jYQNXccqlZVJUVz5hlkXCslHZs8OqfzOIPRQ4VZZY/USERfDCHou8eQRxeOG
  Ux9/jfp35TQRC/1OEx/7mDhixRo3vYCdHHUUUKOdko9VWSyTrTmVLq6V1Iwu7TCe
  K+yasGZ4CfUqUaK+MgFLEEI8k0q2TmRd534a3C6nGS69x9HmIqJISlpvwNYr1YCX
  mk4SFXYX0a5PWeGRiIKg4vPQy4PG1oFAN7+mAgSGNRtMG3Sx4qkMaYLfW0wd7zZ9
  IjHSEqEpekJnAXUJNPdgIBHUVUMNfcnULDPNzaBckgjGm0PqFMlknEOk+NxoXt7m
  ouF3Zkp3xx1U+2uMJ1SVRg==
  -----END CERTIFICATE-----
date: 2014-05-26 00:00:00.000000000 Z
dependencies: []
description: "Maruku is a Markdown interpreter in Ruby.\n\tIt features native export
  to HTML and PDF (via Latex). The\n\toutput is really beautiful!"
email: ben@benhollis.net
executables:
- maruku
- marutex
extensions: []
extra_rdoc_files: []
files:
- MIT-LICENSE.txt
- bin/maruku
- bin/marutex
- data/entities.xml
- docs/div_syntax.md
- docs/entity_test.md
- docs/markdown_syntax.md
- docs/maruku.md
- docs/math.md
- docs/other_stuff.md
- docs/proposal.md
- lib/maruku.rb
- lib/maruku/attributes.rb
- lib/maruku/defaults.rb
- lib/maruku/document.rb
- lib/maruku/element.rb
- lib/maruku/errors.rb
- lib/maruku/ext/div.rb
- lib/maruku/ext/fenced_code.rb
- lib/maruku/ext/math.rb
- lib/maruku/ext/math/elements.rb
- lib/maruku/ext/math/mathml_engines/blahtex.rb
- lib/maruku/ext/math/mathml_engines/itex2mml.rb
- lib/maruku/ext/math/mathml_engines/none.rb
- lib/maruku/ext/math/mathml_engines/ritex.rb
- lib/maruku/ext/math/parsing.rb
- lib/maruku/ext/math/to_html.rb
- lib/maruku/ext/math/to_latex.rb
- lib/maruku/helpers.rb
- lib/maruku/html.rb
- lib/maruku/input/charsource.rb
- lib/maruku/input/extensions.rb
- lib/maruku/input/html_helper.rb
- lib/maruku/input/linesource.rb
- lib/maruku/input/mdline.rb
- lib/maruku/input/parse_block.rb
- lib/maruku/input/parse_doc.rb
- lib/maruku/input/parse_span.rb
- lib/maruku/input_textile2/t2_parser.rb
- lib/maruku/inspect_element.rb
- lib/maruku/maruku.rb
- lib/maruku/output/entity_table.rb
- lib/maruku/output/s5/fancy.rb
- lib/maruku/output/s5/to_s5.rb
- lib/maruku/output/to_html.rb
- lib/maruku/output/to_latex.rb
- lib/maruku/output/to_markdown.rb
- lib/maruku/output/to_s.rb
- lib/maruku/string_utils.rb
- lib/maruku/textile2.rb
- lib/maruku/toc.rb
- lib/maruku/version.rb
- spec/block_docs/abbrev.md
- spec/block_docs/abbreviations.md
- spec/block_docs/alt.md
- spec/block_docs/amps.md
- spec/block_docs/attribute_sanitize.md
- spec/block_docs/attributes/att2.md
- spec/block_docs/attributes/att3.md
- spec/block_docs/attributes/attributes.md
- spec/block_docs/attributes/circular.md
- spec/block_docs/attributes/default.md
- spec/block_docs/auto_cdata.md
- spec/block_docs/blank.md
- spec/block_docs/blanks_in_code.md
- spec/block_docs/bug_def.md
- spec/block_docs/bug_table.md
- spec/block_docs/code.md
- spec/block_docs/code2.md
- spec/block_docs/code3.md
- spec/block_docs/code4.md
- spec/block_docs/data_loss.md
- spec/block_docs/div_without_newline.md
- spec/block_docs/divs/div1.md
- spec/block_docs/divs/div2.md
- spec/block_docs/divs/div3_nest.md
- spec/block_docs/easy.md
- spec/block_docs/email.md
- spec/block_docs/empty_cells.md
- spec/block_docs/encoding/iso-8859-1.md
- spec/block_docs/encoding/utf-8.md
- spec/block_docs/entities.md
- spec/block_docs/escape.md
- spec/block_docs/escaping.md
- spec/block_docs/extra_dl.md
- spec/block_docs/extra_header_id.md
- spec/block_docs/extra_table1.md
- spec/block_docs/fenced_code_blocks.md
- spec/block_docs/fenced_code_blocks_highlighted.md
- spec/block_docs/footnotes.md
- spec/block_docs/footnotes2.md
- spec/block_docs/hard.md
- spec/block_docs/header_after_par.md
- spec/block_docs/headers.md
- spec/block_docs/hex_entities.md
- spec/block_docs/hrule.md
- spec/block_docs/html3.md
- spec/block_docs/html4.md
- spec/block_docs/html5.md
- spec/block_docs/html_block_in_para.md
- spec/block_docs/html_inline.md
- spec/block_docs/html_trailing.md
- spec/block_docs/ie.md
- spec/block_docs/iframe.md
- spec/block_docs/ignore_bad_header.md
- spec/block_docs/images.md
- spec/block_docs/images2.md
- spec/block_docs/inline_html.md
- spec/block_docs/inline_html2.md
- spec/block_docs/inline_html_beginning.md
- spec/block_docs/issue106.md
- spec/block_docs/issue115.md
- spec/block_docs/issue117.md
- spec/block_docs/issue120.md
- spec/block_docs/issue123.md
- spec/block_docs/issue124.md
- spec/block_docs/issue126.md
- spec/block_docs/issue130.md
- spec/block_docs/issue20.md
- spec/block_docs/issue26.md
- spec/block_docs/issue29.md
- spec/block_docs/issue30.md
- spec/block_docs/issue31.md
- spec/block_docs/issue40.md
- spec/block_docs/issue64.md
- spec/block_docs/issue67.md
- spec/block_docs/issue70.md
- spec/block_docs/issue72.md
- spec/block_docs/issue74.md
- spec/block_docs/issue79.md
- spec/block_docs/issue83.md
- spec/block_docs/issue85.md
- spec/block_docs/issue88.md
- spec/block_docs/issue89.md
- spec/block_docs/issue90.md
- spec/block_docs/link.md
- spec/block_docs/links.md
- spec/block_docs/links2.md
- spec/block_docs/list1.md
- spec/block_docs/list12.md
- spec/block_docs/list2.md
- spec/block_docs/list_multipara.md
- spec/block_docs/lists.md
- spec/block_docs/lists10.md
- spec/block_docs/lists11.md
- spec/block_docs/lists12.md
- spec/block_docs/lists13.md
- spec/block_docs/lists14.md
- spec/block_docs/lists15.md
- spec/block_docs/lists6.md
- spec/block_docs/lists7b.md
- spec/block_docs/lists9.md
- spec/block_docs/lists_after_paragraph.md
- spec/block_docs/lists_blank.md
- spec/block_docs/lists_blockquote_code.md
- spec/block_docs/lists_need_blank_line.md
- spec/block_docs/lists_nested.md
- spec/block_docs/lists_nested_blankline.md
- spec/block_docs/lists_nested_deep.md
- spec/block_docs/lists_ol.md
- spec/block_docs/lists_paraindent.md
- spec/block_docs/lists_tab.md
- spec/block_docs/loss.md
- spec/block_docs/math-blahtex/equations.md
- spec/block_docs/math-blahtex/inline.md
- spec/block_docs/math-blahtex/math2.md
- spec/block_docs/math-blahtex/table.md
- spec/block_docs/math/embedded_invalid_svg.md
- spec/block_docs/math/embedded_svg.md
- spec/block_docs/math/equations.md
- spec/block_docs/math/inline.md
- spec/block_docs/math/math2.md
- spec/block_docs/math/notmath.md
- spec/block_docs/math/raw_mathml.md
- spec/block_docs/math/spaces_after_inline_math.md
- spec/block_docs/math/table.md
- spec/block_docs/math/table2.md
- spec/block_docs/misc_sw.md
- spec/block_docs/olist.md
- spec/block_docs/one.md
- spec/block_docs/paragraph.md
- spec/block_docs/paragraph_rules/dont_merge_ref.md
- spec/block_docs/paragraph_rules/tab_is_blank.md
- spec/block_docs/paragraphs.md
- spec/block_docs/recover/recover_links.md
- spec/block_docs/ref_with_period.md
- spec/block_docs/ref_with_title.md
- spec/block_docs/references/long_example.md
- spec/block_docs/references/spaces_and_numbers.md
- spec/block_docs/smartypants.md
- spec/block_docs/syntax_hl.md
- spec/block_docs/table_attributes.md
- spec/block_docs/table_colspan.md
- spec/block_docs/tables.md
- spec/block_docs/tables2.md
- spec/block_docs/test.md
- spec/block_docs/ticks.md
- spec/block_docs/toc.md
- spec/block_docs/triggering.md
- spec/block_docs/underscore_in_words.md
- spec/block_docs/wrapping.md
- spec/block_docs/xml.md
- spec/block_docs/xml3.md
- spec/block_docs/xml_comments.md
- spec/block_docs/xml_instruction.md
- spec/block_spec.rb
- spec/cli_spec.rb
- spec/span_spec.rb
- spec/spec_helper.rb
- spec/to_html_utf8_spec.rb
homepage: http://github.com/bhollis/maruku
licenses:
- MIT
metadata: {}
post_install_message: 
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
  requirements:
  - - ">="
    - !ruby/object:Gem::Version
      version: 1.8.7
required_rubygems_version: !ruby/object:Gem::Requirement
  requirements:
  - - ">="
    - !ruby/object:Gem::Version
      version: '0'
requirements: []
rubyforge_project: 
rubygems_version: 2.2.2
signing_key: 
specification_version: 4
summary: Maruku is a Markdown-superset interpreter written in Ruby.
test_files: []
has_rdoc: 
maruku-0.7.2/docs/0000755000004100000410000000000012347070213014003 5ustar  www-datawww-datamaruku-0.7.2/docs/div_syntax.md0000644000004100000410000000102112347070213016507 0ustar  www-datawww-data## Option number 1 ##

*	`[ ]{0,3}\+={2,}` pushes the stack
*	`[ ]{0,3}\-={2,}` pops the stack

	+================ {#id}
		IAL can be put on the same line of a push
		
	 +== {#id2}
		Or on the same line of a pop:
	 -==
	
	-==============

## Option number 2 ##

Double braces:

	{{
	
	}}{}

I don't like, it gets too messy because there are 
too many braces.



    +================ {#id}
    
         nested div:

     +========================
           inside nested DIV
     -========================

    -==============
maruku-0.7.2/docs/math.md0000644000004100000410000001016212347070213015256 0ustar  www-datawww-dataTitle: Math support in Maruku
LaTeX preamble: math_preamble.tex
LaTeX use listings: true
CSS: math.css style.css
use numbered headers: true

Math support in Maruku
======================

This document describes Maruku's support of inline LaTeX-style math.

There are many subtleties of which one must care for 
correctly serving the XHTML+MathML document to browsers.
In fact, *this documentation is __not__ enough to get you started*, 
unless you feel very adventurous.

* toc
{:toc}

Syntax
---------------------------------------

### Inline math

Inline math is contained inside couples of `$`. 

Everything inside will be passed as-is to LaTeX: no Markdown
interpretation will take place.

	Example: $x^{n}+y^{n} \neq z^{n}$ for $n \geq 3$

> Example: $x^{n}+y^{n} \neq z^{n}$ for $n \geq 3$

### Equations 

Equations are specified using either the `$$ ... $$` or `\[ ... \]`
LaTeX notation. Equations can span multiple lines.

	\[ 
	\sum_{n=1}^\infty \frac{1}{n} 
	\text{ is divergent, but } 
	\lim_{n \to \infty} \sum_{i=1}^n \frac{1}{i} - \ln n \text{exists.} 
	\]

> \[ 
> 	\sum_{n=1}^\infty \frac{1}{n} 
> 	\text{ is divergent, but } 
> 	\lim_{n \to \infty} \sum_{i=1}^n \frac{1}{i} - \ln n \quad \text{exists.} 
> \]

Some random AMSTeX symbols:

	$$ \beth \Subset \bigtriangleup \bumpeq \ggg \pitchfork $$ 

$$ \beth \Subset \bigtriangleup \bumpeq \ggg \pitchfork $$ 


## Cross references ## {#cross}

Create a label for an equation in two ways:

*	LaTeX style:
	
		Consider \eqref{a}:
	
		$$ \alpha = \beta  \label{a} $$

*	More readable style:

		Consider (eq:a):

		$$ \alpha = \beta $$        (a)
	 
You can mix the two.

Labels will work as expected also in the PDF output, whatever
style you use: Maruku will insert the necessary `\label` commands.

The following are 4 equations, labeled A,B,C,D:

$$ \alpha $$ (A)

\[ 
	\beta
\] (B) 

$$ \gamma \label{C} $$

\[ 
	\delta \label{D}
\]

You can now refer to (eq:A), (eq:B), \eqref{C}, \eqref{D}.


Enabling the extension
---------------------------------------

### On the command line 

Use the `-m` option to choose the kind of output. Possible choices are:

`--math-engine itex2mml` : Outputs MathML using [itex2mml](#using_itex2mml).  
`--math-engine ritex` : Outputs MathML using [ritex](#using_ritex).  
`--math-engine blahtex` : Outputs MathML using [blahtex](#using_blahtex).  
`--math-images blahtex` : Outputs PNGs  using [blahtex](#using_blahtex).

### With embedded Maruku

You have to enable the math extension like this:

	require 'maruku'          # loads maruku
	require 'maruku/ext/math' # loads the math extension

Use the following to choose the engine:

	MaRuKu::Globals[:html_math_engine] = 'itex2mml'
	MaRuKu::Globals[:html_png_engine] =  'blahtex'
	
Available MathML engines are 'none', 'itex2mml', 'blahtex'.
'blahtex' is the only PNG engine available.
	
External libraries needed
-------------------------

To output MathML or PNGs, it is needed to install one of the following libraries

### Using `itex2mml` ### {#using_itex2mml}

itex2mml supports much more LaTeX commands/environments than ritex.

Install itextomml with 

	$ gem install itextomml

This is a summary of the available LaTeX commands:

> 

Moreover, [Jacques Distler] is integrating Maruku+itex2mml+[Instiki].
You can find more information here:

> 

[Jacques Distler]: http://golem.ph.utexas.edu/~distler
[instiki]: http://golem.ph.utexas.edu/wiki/instiki/show/HomePage

### Using `ritex` ### {#using_ritex}

Install with 

	$ gem install ritex

ritex's abilities are very limited, but it is the easiest to install since, unlike `itextomml`, it is a pure-ruby implementation.

### Using `blahtex` ### {#using_blahtex}

Download from . Make sure you have
the command-line `blahtex` in your path.


Subtleties
----------

### Serving the right content/type ###


* Mozilla wants files to have the `.xhtml` extension.

...

### Where PNGS are put ###

*	`Globals[:math_png_dir]`

*	`Globals[:math_png_dir_url]`


### Styling equations ####

...

### Aligning PNGs ####


*	using `ex`

*	**IE7 bug**

...
maruku-0.7.2/docs/markdown_syntax.md0000644000004100000410000006523112347070213017564 0ustar  www-datawww-dataMarkdown: Syntax
================

*   [Overview](#overview)
    *   [Philosophy](#philosophy)
    *   [Inline HTML](#html)
    *   [Automatic Escaping for Special Characters](#autoescape)
*   [Block Elements](#block)
    *   [Paragraphs and Line Breaks](#p)
    *   [Headers](#header)
    *   [Blockquotes](#blockquote)
    *   [Lists](#list)
    *   [Code Blocks](#precode)
    *   [Horizontal Rules](#hr)
*   [Span Elements](#span)
    *   [Links](#link)
    *   [Emphasis](#em)
    *   [Code](#code)
    *   [Images](#img)
*   [Miscellaneous](#misc)
    *   [Backslash Escapes](#backslash)
    *   [Automatic Links](#autolink)


**Note:** This document is itself written using Markdown; you
can [see the source for it by adding '.text' to the URL][src].

  [src]: /projects/markdown/syntax.text

* * *

Overview

Philosophy

Markdown is intended to be as easy-to-read and easy-to-write as is feasible. Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions. While Markdown's syntax has been influenced by several existing text-to-HTML filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], [Grutatext] [5], and [EtText] [6] -- the single biggest source of inspiration for Markdown's syntax is the format of plain text email. [1]: http://docutils.sourceforge.net/mirror/setext.html [2]: http://www.aaronsw.com/2002/atx/ [3]: http://textism.com/tools/textile/ [4]: http://docutils.sourceforge.net/rst.html [5]: http://www.triptico.com/software/grutatxt.html [6]: http://ettext.taint.org/doc/ To this end, Markdown's syntax is comprised entirely of punctuation characters, which punctuation characters have been carefully chosen so as to look like what they mean. E.g., asterisks around a word actually look like \*emphasis\*. Markdown lists look like, well, lists. Even blockquotes look like quoted passages of text, assuming you've ever used email.

Inline HTML

Markdown's syntax is intended for one purpose: to be used as a format for *writing* for the web. Markdown is not a replacement for HTML, or even close to it. Its syntax is very small, corresponding only to a very small subset of HTML tags. The idea is *not* to create a syntax that makes it easier to insert HTML tags. In my opinion, HTML tags are already easy to insert. The idea for Markdown is to make it easy to read, write, and edit prose. HTML is a *publishing* format; Markdown is a *writing* format. Thus, Markdown's formatting syntax only addresses issues that can be conveyed in plain text. For any markup that is not covered by Markdown's syntax, you simply use HTML itself. There's no need to preface it or delimit it to indicate that you're switching from Markdown to HTML; you just use the tags. The only restrictions are that block-level HTML elements -- e.g. `
`, ``, `
`, `

`, etc. -- must be separated from surrounding content by blank lines, and the start and end tags of the block should not be indented with tabs or spaces. Markdown is smart enough not to add extra (unwanted) `

` tags around HTML block-level tags. For example, to add an HTML table to a Markdown article: This is a regular paragraph.

Foo
This is another regular paragraph. Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an HTML block. Span-level HTML tags -- e.g. ``, ``, or `` -- can be used anywhere in a Markdown paragraph, list item, or header. If you want, you can even use HTML tags instead of Markdown formatting; e.g. if you'd prefer to use HTML `` or `` tags instead of Markdown's link or image syntax, go right ahead. Unlike block-level HTML tags, Markdown syntax *is* processed within span-level tags.

Automatic Escaping for Special Characters

In HTML, there are two characters that demand special treatment: `<` and `&`. Left angle brackets are used to start tags; ampersands are used to denote HTML entities. If you want to use them as literal characters, you must escape them as entities, e.g. `<`, and `&`. Ampersands in particular are bedeviling for web writers. If you want to write about 'AT&T', you need to write '`AT&T`'. You even need to escape ampersands within URLs. Thus, if you want to link to: http://images.google.com/images?num=30&q=larry+bird you need to encode the URL as: http://images.google.com/images?num=30&q=larry+bird in your anchor tag `href` attribute. Needless to say, this is easy to forget, and is probably the single most common source of HTML validation errors in otherwise well-marked-up web sites. Markdown allows you to use these characters naturally, taking care of all the necessary escaping for you. If you use an ampersand as part of an HTML entity, it remains unchanged; otherwise it will be translated into `&`. So, if you want to include a copyright symbol in your article, you can write: © and Markdown will leave it alone. But if you write: AT&T Markdown will translate it to: AT&T Similarly, because Markdown supports [inline HTML](#html), if you use angle brackets as delimiters for HTML tags, Markdown will treat them as such. But if you write: 4 < 5 Markdown will translate it to: 4 < 5 However, inside Markdown code spans and blocks, angle brackets and ampersands are *always* encoded automatically. This makes it easy to use Markdown to write about HTML code. (As opposed to raw HTML, which is a terrible format for writing about HTML syntax, because every single `<` and `&` in your example code needs to be escaped.) * * *

Block Elements

Paragraphs and Line Breaks

A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs. The implication of the "one or more consecutive lines of text" rule is that Markdown supports "hard-wrapped" text paragraphs. This differs significantly from most other text-to-HTML formatters (including Movable Type's "Convert Line Breaks" option) which translate every line break character in a paragraph into a `
` tag. When you *do* want to insert a `
` break tag using Markdown, you end a line with two or more spaces, then type return. Yes, this takes a tad more effort to create a `
`, but a simplistic "every line break is a `
`" rule wouldn't work for Markdown. Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l] work best -- and look better -- when you format them with hard breaks. [bq]: #blockquote [l]: #list Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. Setext-style headers are "underlined" using equal signs (for first-level headers) and dashes (for second-level headers). For example: This is an H1 ============= This is an H2 ------------- Any number of underlining `=`'s or `-`'s will work. Atx-style headers use 1-6 hash characters at the start of the line, corresponding to header levels 1-6. For example: # This is an H1 ## This is an H2 ###### This is an H6 Optionally, you may "close" atx-style headers. This is purely cosmetic -- you can use this if you think it looks better. The closing hashes don't even need to match the number of hashes used to open the header. (The number of opening hashes determines the header level.) : # This is an H1 # ## This is an H2 ## ### This is an H3 ######

Blockquotes

Markdown uses email-style `>` characters for blockquoting. If you're familiar with quoting passages of text in an email message, then you know how to create a blockquote in Markdown. It looks best if you hard wrap the text and put a `>` before every line: > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse > id sem consectetuer libero luctus adipiscing. Markdown allows you to be lazy and only put the `>` before the first line of a hard-wrapped paragraph: > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by adding additional levels of `>`: > This is the first level of quoting. > > > This is nested blockquote. > > Back to the first level. Blockquotes can contain other Markdown elements, including headers, lists, and code blocks: > ## This is a header. > > 1. This is the first list item. > 2. This is the second list item. > > Here's some example code: > > return shell_exec("echo $input | $markdown_script"); Any decent text editor should make email-style quoting easy. For example, with BBEdit, you can make a selection and choose Increase Quote Level from the Text menu.

Lists

Markdown supports ordered (numbered) and unordered (bulleted) lists. Unordered lists use asterisks, pluses, and hyphens -- interchangably -- as list markers: * Red * Green * Blue is equivalent to: + Red + Green + Blue and: - Red - Green - Blue Ordered lists use numbers followed by periods: 1. Bird 2. McHale 3. Parish It's important to note that the actual numbers you use to mark the list have no effect on the HTML output Markdown produces. The HTML Markdown produces from the above list is:
  1. Bird
  2. McHale
  3. Parish
If you instead wrote the list in Markdown like this: 1. Bird 1. McHale 1. Parish or even: 3. Bird 1. McHale 8. Parish you'd get the exact same HTML output. The point is, if you want to, you can use ordinal numbers in your ordered Markdown lists, so that the numbers in your source match the numbers in your published HTML. But if you want to be lazy, you don't have to. If you do use lazy list numbering, however, you should still start the list with the number 1. At some point in the future, Markdown may support starting ordered lists at an arbitrary number. List markers typically start at the left margin, but may be indented by up to three spaces. List markers must be followed by one or more spaces or a tab. To make lists look nice, you can wrap items with hanging indents: * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. But if you want to be lazy, you don't have to: * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse id sem consectetuer libero luctus adipiscing. If list items are separated by blank lines, Markdown will wrap the items in `

` tags in the HTML output. For example, this input: * Bird * Magic will turn into:

  • Bird
  • Magic
But this: * Bird * Magic will turn into:
  • Bird

  • Magic

List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be intended by either 4 spaces or one tab: 1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. Donec sit amet nisl. Aliquam semper ipsum sit amet velit. 2. Suspendisse id sem consectetuer libero luctus adipiscing. It looks nice if you indent every line of the subsequent paragraphs, but here again, Markdown will allow you to be lazy: * This is a list item with two paragraphs. This is the second paragraph in the list item. You're only required to indent the first line. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. * Another item in the same list. To put a blockquote within a list item, the blockquote's `>` delimiters need to be indented: * A list item with a blockquote: > This is a blockquote > inside a list item. To put a code block within a list item, the code block needs to be indented *twice* -- 8 spaces or two tabs: * A list item with a code block: It's worth noting that it's possible to trigger an ordered list by accident, by writing something like this: 1986. What a great season. In other words, a *number-period-space* sequence at the beginning of a line. To avoid this, you can backslash-escape the period: 1986\. What a great season.

Code Blocks

Pre-formatted code blocks are used for writing about programming or markup source code. Rather than forming normal paragraphs, the lines of a code block are interpreted literally. Markdown wraps a code block in both `
` and `` tags.

To produce a code block in Markdown, simply indent every line of the
block by at least 4 spaces or 1 tab. For example, given this input:

    This is a normal paragraph:

        This is a code block.

Markdown will generate:

    

This is a normal paragraph:

This is a code block.
    
One level of indentation -- 4 spaces or 1 tab -- is removed from each line of the code block. For example, this: Here is an example of AppleScript: tell application "Foo" beep end tell will turn into:

Here is an example of AppleScript:

tell application "Foo"
        beep
    end tell
    
A code block continues until it reaches a line that is not indented (or the end of the article). Within a code block, ampersands (`&`) and angle brackets (`<` and `>`) are automatically converted into HTML entities. This makes it very easy to include example HTML source code using Markdown -- just paste it and indent it, and Markdown will handle the hassle of encoding the ampersands and angle brackets. For example, this: will turn into:
<div class="footer">
        &copy; 2004 Foo Corporation
    </div>
    
Regular Markdown syntax is not processed within code blocks. E.g., asterisks are just literal asterisks within a code block. This means it's also easy to use Markdown to write about Markdown's own syntax.

Horizontal Rules

You can produce a horizontal rule tag (`
`) by placing three or more hyphens, asterisks, or underscores on a line by themselves. If you wish, you may use spaces between the hyphens or asterisks. Each of the following lines will produce a horizontal rule: * * * *** ***** - - - --------------------------------------- * * *

Span Elements

Markdown supports two style of links: *inline* and *reference*. In both styles, the link text is delimited by [square brackets]. To create an inline link, use a set of regular parentheses immediately after the link text's closing square bracket. Inside the parentheses, put the URL where you want the link to point, along with an *optional* title for the link, surrounded in quotes. For example: This is [an example](http://example.com/ "Title") inline link. [This link](http://example.net/) has no title attribute. Will produce:

This is an example inline link.

This link has no title attribute.

If you're referring to a local resource on the same server, you can use relative paths: See my [About](/about/) page for details. Reference-style links use a second set of square brackets, inside which you place a label of your choosing to identify the link: This is [an example][id] reference-style link. You can optionally use a space to separate the sets of brackets: This is [an example] [id] reference-style link. Then, anywhere in the document, you define your link label like this, on a line by itself: [id]: http://example.com/ "Optional Title Here" That is: * Square brackets containing the link identifier (optionally indented from the left margin using up to three spaces); * followed by a colon; * followed by one or more spaces (or tabs); * followed by the URL for the link; * optionally followed by a title attribute for the link, enclosed in double or single quotes, or enclosed in parentheses. The following three link definitions are equivalent: [foo]: http://example.com/ "Optional Title Here" [foo]: http://example.com/ 'Optional Title Here' [foo]: http://example.com/ (Optional Title Here) **Note:** There is a known bug in Markdown.pl 1.0.1 which prevents single quotes from being used to delimit link titles. The link URL may, optionally, be surrounded by angle brackets: [id]: "Optional Title Here" You can put the title attribute on the next line and use extra spaces or tabs for padding, which tends to look better with longer URLs: [id]: http://example.com/longish/path/to/resource/here "Optional Title Here" Link definitions are only used for creating links during Markdown processing, and are stripped from your document in the HTML output. Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links: [link text][a] [link text][A] are equivalent. The *implicit link name* shortcut allows you to omit the name of the link, in which case the link text itself is used as the name. Just use an empty set of square brackets -- e.g., to link the word "Google" to the google.com web site, you could simply write: [Google][] And then define the link: [Google]: http://google.com/ Because link names may contain spaces, this shortcut even works for multiple words in the link text: Visit [Daring Fireball][] for more information. And then define the link: [Daring Fireball]: http://daringfireball.net/ Link definitions can be placed anywhere in your Markdown document. I tend to put them immediately after each paragraph in which they're used, but if you want, you can put them all at the end of your document, sort of like footnotes. Here's an example of reference links in action: I get 10 times more traffic from [Google] [1] than from [Yahoo] [2] or [MSN] [3]. [1]: http://google.com/ "Google" [2]: http://search.yahoo.com/ "Yahoo Search" [3]: http://search.msn.com/ "MSN Search" Using the implicit link name shortcut, you could instead write: I get 10 times more traffic from [Google][] than from [Yahoo][] or [MSN][]. [google]: http://google.com/ "Google" [yahoo]: http://search.yahoo.com/ "Yahoo Search" [msn]: http://search.msn.com/ "MSN Search" Both of the above examples will produce the following HTML output:

I get 10 times more traffic from Google than from Yahoo or MSN.

For comparison, here is the same paragraph written using Markdown's inline link style: I get 10 times more traffic from [Google](http://google.com/ "Google") than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or [MSN](http://search.msn.com/ "MSN Search"). The point of reference-style links is not that they're easier to write. The point is that with reference-style links, your document source is vastly more readable. Compare the above examples: using reference-style links, the paragraph itself is only 81 characters long; with inline-style links, it's 176 characters; and as raw HTML, it's 234 characters. In the raw HTML, there's more markup than there is text. With Markdown's reference-style links, a source document much more closely resembles the final output, as rendered in a browser. By allowing you to move the markup-related metadata out of the paragraph, you can add links without interrupting the narrative flow of your prose.

Emphasis

Markdown treats asterisks (`*`) and underscores (`_`) as indicators of emphasis. Text wrapped with one `*` or `_` will be wrapped with an HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML `` tag. E.g., this input: *single asterisks* _single underscores_ **double asterisks** __double underscores__ will produce: single asterisks single underscores double asterisks double underscores You can use whichever style you prefer; the lone restriction is that the same character must be used to open and close an emphasis span. Emphasis can be used in the middle of a word: un*fucking*believable But if you surround an `*` or `_` with spaces, it'll be treated as a literal asterisk or underscore. To produce a literal asterisk or underscore at a position where it would otherwise be used as an emphasis delimiter, you can backslash escape it: \*this text is surrounded by literal asterisks\*

Code

To indicate a span of code, wrap it with backtick quotes (`` ` ``). Unlike a pre-formatted code block, a code span indicates code within a normal paragraph. For example: Use the `printf()` function. will produce:

Use the printf() function.

To include a literal backtick character within a code span, you can use multiple backticks as the opening and closing delimiters: ``There is a literal backtick (`) here.`` which will produce this:

There is a literal backtick (`) here.

The backtick delimiters surrounding a code span may include spaces -- one after the opening, one before the closing. This allows you to place literal backtick characters at the beginning or end of a code span: A single backtick in a code span: `` ` `` A backtick-delimited string in a code span: `` `foo` `` will produce:

A single backtick in a code span: `

A backtick-delimited string in a code span: `foo`

With a code span, ampersands and angle brackets are encoded as HTML entities automatically, which makes it easy to include example HTML tags. Markdown will turn this: Please don't use any `` tags. into:

Please don't use any <blink> tags.

You can write this: `—` is the decimal-encoded equivalent of `—`. to produce:

&#8212; is the decimal-encoded equivalent of &mdash;.

Images

Admittedly, it's fairly difficult to devise a "natural" syntax for placing images into a plain text document format. Markdown uses an image syntax that is intended to resemble the syntax for links, allowing for two styles: *inline* and *reference*. Inline image syntax looks like this: ![Alt text](/path/to/img.jpg) ![Alt text](/path/to/img.jpg "Optional title") That is: * An exclamation mark: `!`; * followed by a set of square brackets, containing the `alt` attribute text for the image; * followed by a set of parentheses, containing the URL or path to the image, and an optional `title` attribute enclosed in double or single quotes. Reference-style image syntax looks like this: ![Alt text][id] Where "id" is the name of a defined image reference. Image references are defined using syntax identical to link references: [id]: url/to/image "Optional title attribute" As of this writing, Markdown has no syntax for specifying the dimensions of an image; if this is important to you, you can simply use regular HTML `` tags. * * *

Miscellaneous

Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this: Markdown will turn this into: http://example.com/ Automatic links for email addresses work similarly, except that Markdown will also perform a bit of randomized decimal and hex entity-encoding to help obscure your address from address-harvesting spambots. For example, Markdown will turn this: into something like this: address@exa mple.com which will render in a browser as a clickable link to "address@example.com". (This sort of entity-encoding trick will indeed fool many, if not most, address-harvesting bots, but it definitely won't fool all of them. It's better than nothing, but an address published in this way will probably eventually start receiving spam.)

Backslash Escapes

Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown's formatting syntax. For example, if you wanted to surround a word with literal asterisks (instead of an HTML `` tag), you can backslashes before the asterisks, like this: \*literal asterisks\* Markdown provides backslash escapes for the following characters: \ backslash ` backtick * asterisk _ underscore {} curly braces [] square brackets () parentheses # hash mark + plus sign - minus sign (hyphen) . dot ! exclamation mark maruku-0.7.2/docs/other_stuff.md0000644000004100000410000000367212347070213016665 0ustar www-datawww-data* *Jan. 22* With very minimal changes, Maruku now works in JRuby. It is very slow, though. Some benchmarks: * G4 1.5GhZ, Ruby 1.8.5: Maruku (to_html): parsing 0.65 sec + rendering 0.40 sec = 1.04 sec Maruku (to_latex): parsing 0.70 sec + rendering 0.21 sec = 0.91 sec * G4 1.5GhZ, JRuby 1.9.2: Maruku (to_html): parsing 4.77 sec + rendering 2.24 sec = 7.01 sec Maruku (to_latex): parsing 4.04 sec + rendering 1.12 sec = 5.16 sec * *Jan. 21* Integration of Blahtex. PNG export of formula and alignment works ok in Mozilla, Safari, Camino, Opera. IE7 is acting strangely. * Support for LaTeX-style formula input, and export to MathML. [Jacques Distler] is integrating Maruku into Instiki (a Ruby On Rails-based wiki software), as to have a Ruby wiki with proper math support. You know, these physicists like all those funny symbols. * To have the MathML export, it is needed to install one of: * [RiTeX] (`gem install ritex`) * [itex2MML] supports much more complex formulas than Ritex. * PNG for old browser is not here yet. The plan is to use BlahTeX. * Command line options for the `maruku` command: Usage: maruku [options] [file1.md [file2.md ... -v, --[no-]verbose Run verbosely -u, --[no-]unsafe Use unsafe features -b Break on error -m, --math-engine ENGINE Uses ENGINE to render MathML --pdf Write PDF --html Write HTML --tex Write LaTeX --inspect Shows the parsing result --version Show version -h, --help Show this message * Other things: * Created the embryo of an extension system. Please don't use it yet, as probably the API is bound to change. * There are a couple of hidden, unsafe, features that are not enabled by default. maruku-0.7.2/docs/maruku.md0000644000004100000410000002120412347070213015630 0ustar www-datawww-dataCSS: style.css Use numbered headers: true HTML use syntax: true LaTeX use listings: true LaTeX CJK: false LaTeX preamble: preamble.tex ![MaRuKu](logo.png){#logo} Mar**u**k**u**: a Markdown-superset interpreter =============================================== [Maruku] is a Markdown interpreter written in [Ruby]. > [Last release](#release_notes) is version 0.5.6 -- 2007-05-22. > > Install using [rubygems]: > > $ gem install maruku > > Use this command to update to latest version: > > $ gem update maruku > {#news} [rubygems]: http://rubygems.org * * * Maruku allows you to write in an easy-to-read-and-write syntax, like this: > [This document in Markdown][this_md] Then it can be translated to HTML: > [This document in HTML][this_html] or LaTeX, which is then converted to PDF: > [This document in PDF][this_pdf] Maruku implements: * the original [Markdown syntax][markdown_html] ([HTML][markdown_html] or [PDF][markdown_pdf]), translated by Maruku). * all the improvements in [PHP Markdown Extra]. * a new [meta-data syntax][meta_data_proposal] __Authors__: Maruku has been developed so far by [Andrea Censi]. Contributors are most welcome! __The name of the game__: Maruku is the [romaji] transliteration of the [katakana] transliteration of "Mark", the first word in Markdown. I chose this name because Ruby is Japanese, and also the sillable "ru" appears in Maruku. [romaji]: http://en.wikipedia.org/wiki/Romaji [katakana]: http://en.wikipedia.org/wiki/Katakana [tests]: http://maruku.rubyforge.org/tests/ [maruku]: http://maruku.rubyforge.org/ [markdown_html]: http://maruku.rubyforge.org/markdown_syntax.html [markdown_pdf]: http://maruku.rubyforge.org/markdown_syntax.pdf [this_md]: http://maruku.rubyforge.org/maruku.md [this_html]: http://maruku.rubyforge.org/maruku.html [this_pdf]: http://maruku.rubyforge.org/maruku.pdf [Andrea Censi]: http://www.dis.uniroma1.it/~acensi/ [contact]: http://www.dis.uniroma1.it/~acensi/contact.html [gem]: http://rubygems.rubyforge.org/ [tracker]: http://rubyforge.org/tracker/?group_id=2795 [ruby]: http://www.ruby-lang.org [bluecloth]: http://www.deveiate.org/projects/BlueCloth [Markdown syntax]: http://daringfireball.net/projects/markdown/syntax [PHP Markdown Extra]: http://www.michelf.com/projects/php-markdown/extra/ [math syntax]: http://maruku.rubyforge.org/math.xhtml [blahtex]: http://www.blahtex.org [ritex]: http://ritex.rubyforge.org [itex2mml]: http://golem.ph.utexas.edu/~distler/code/itexToMML/ [syntax]: http://syntax.rubyforge.org/ [listings]: http://www.ctan.org/tex-archive/macros/latex/contrib/listings/ [meta_data_proposal]: http://maruku.rubyforge.org/proposal.html [markdown-discuss]: http://six.pairlist.net/mailman/listinfo/markdown-discuss * * * Table of contents: (**auto-generated by Maruku!**) * This list will contain the toc (it doesn't matter what you write here) {:toc} * * * {:ruby: lang=ruby code_background_color='#efffef'} {:shell: lang=sh code_background_color='#efefff'} {:markdown: code_background_color='#ffefef'} {:html: lang=xml} Release notes {#release_notes} -------------- Note: Maruku seems to be very robust, nevertheless it is still beta-level software. So if you want to use it in production environments, please check back in a month or so, while we squash the remaining bugs. In the meantime, feel free to toy around, and please signal problems, request features, by [contacting me][contact] or using the [tracker][tracker]. For issues about the Markdown syntax itself and improvements to it, please write to the [Markdown-discuss mailing list][markdown-discuss]. Have fun! See the [changelog](http://maruku.rubyforge.org/changelog.html#stable). Usage -------- ### Embedded Maruku ### This is the basic usage: require 'rubygems' require 'maruku' doc = Maruku.new(markdown_string) puts doc.to_html {:ruby} The method `to_html` outputs only an HTML fragment, while the method `to_html_document` outputs a complete XHTML 1.0 document: puts doc.to_html_document {:ruby} You can have the REXML document tree with: tree = doc.to_html_document_tree {:ruby} ### From the command line ### There is one command-line program installed: `maruku`. Without arguments, it converts Markdown to HTML: $ maruku file.md # creates file.html {:shell} With the `--pdf` arguments, it converts Markdown to LaTeX, then calls `pdflatex` to transform to PDF: $ maruku --pdf file.md # creates file.tex and file.pdf {:shell} Maruku summary of features {#features} -------------------------- * Supported syntax * [Basic Markdown][markdown_syntax] * [Markdown Extra](#extra) * [Meta-data syntax](#meta) * Output * XHTML * Syntax highlighting via the [`syntax`][syntax] library. * LaTeX * [Translation of HTML entities to LaTeX](#entities) * Syntax highlighting via the [`listings`][listings] package. * Misc * [Documentation for supported attributes][supported_attributes] * [Automatic generation of the TOC](#toc-generation) [supported_attributes]: exd.html **Experimental features (not released yet)** * [LaTeX Math syntax][math_syntax] (not enabled by default) * An extension system for adding new syntax is available, but the API is bound to change in the future, so please don't use it. * LaTeX to MathML using either one of [`ritex`][ritex], [`itex2mml`][itex2mml], [`blahtex`][blahtex]. * LaTeX to PNG using [`blahtex`][blahtex]. ### New meta-data syntax {#meta} Maruku implements a syntax that allows to attach "meta" information to objects. See [this proposal][meta_data_proposal] for how to attach metadata to the elements. See the [documentation for supported attributes][supported_attributes]. Meta-data for the document itself is specified through the use of email headers: Title: A simple document containing meta-headers CSS: style.css Content of the document {:markdown} When creating the document through Maruku.new(s).to_html_document {:ruby} the title and stylesheet are added as expected. Meta-data keys are assumed to be case-insensitive. ### Automatic generation of the table of contents ### {#toc-generation} If you create a list, and then set the `toc` attribute, when rendering Maruku will create an auto-generated table of contents. * This will become a table of contents (this text will be scraped). {:toc} You can see an example of this at the beginning of this document. ### Use HTML entities ### {#entities} If you want to use HTML entities, go on! We will take care of the translation to LaTeX: Entity | Result ------------|---------- `©` | © `£` | £ `λ` | λ `—` | — See the [list of supported entities][ent_html] ([pdf][ent_pdf]). [ent_html]: http://maruku.rubyforge.org/entity_test.html [ent_pdf]: http://maruku.rubyforge.org/entity_test.pdf ### This header contains *emphasis* **strong text** and `code` #### Note that this header contains formatting and it still works, also in the table of contents. And [This is a *link* with **all** ***sort*** of `weird stuff`](#features) in the text. Examples of PHP Markdown Extra syntax {#extra} ------------------------------------- * tables Col1 | Very very long head | Very very long head| -----|:-------------------:|-------------------:| cell | center-align | right-align | {:markdown} Col1 | Very very long head | Very very long head| -----|:-------------------:|-------------------:| cell | center-align | right-align | * footnotes [^foot] * footnotes [^foot] [^foot]: I really was missing those. {:markdown} [^foot]: I really was missing those. * Markdown inside HTML elements
This is a div with Markdown **strong text**
{:html}
This is a div with Markdown **strong text**
* header ids ## Download ## {#download} {:markdown} For example, [a link to the download](#download) header. * definition lists Definition list : something very hard to parse {:markdown} Definition list : something very hard to parse * abbreviations or ABB for short. *[ABB]: Simply an abbreviation maruku-0.7.2/docs/proposal.md0000644000004100000410000001517512347070213016175 0ustar www-datawww-dataCSS: style.css LaTeX_use_listings: true html_use_syntax: true use_numbered_headers: true Proposal for adding a meta-data syntax to Markdown ============================================= This document describes a syntax for attaching meta-data to block-level elements (headers, paragraphs, code blocks,…), and to span-level elements (links, images,…). ***Note: this is an evolving proposal*** Last updated **January 10th, 2007**: * Changed the syntax for compatibility with a future extension mechanism. The first character in the curly braces must be a colon, optionally followed by a space: {: ref .class #id} The old syntax was `{ref .class #id}`. For ALDs, the new syntax is: {:ref_id: key=val .class #id } instead of: {ref_id}: key=val .class #id Converters that don't use this syntax may just ignore everything which is in curly braces and starts with ":". * IAL can be put both *before* and *after* the element. There is no ambiguity as a blank line is needed between elements: Paragraph 1 {:par2} Paragraph 2 is equivalent to: Paragraph 1 Paragraph 2 {:par2} * Simplified rules for escaping. *Table of contents:* > * Table of contents > {:toc} Overview -------- This proposal describes two additions to the Markdown syntax: 1. inline attribute lists (IAL) ## Header ## {: key=val .class #id ref_id} 2. attribute lists definitions (ALD) {:ref_id: key=val .class #id} Every span-level or block-level element can be followed by an IAL: ### Header ### {: #header1 class=c1} Paragraph *with emphasis*{: class=c1} second line of paragraph {: class=c1} In this example, the three IALs refer to the header, the emphasis span, and the entire paragraph, respectively. IALs can reference ALDs. The result of the following example is the same as the previous one: ### Header ### {: #header1 c1} Paragraph *with emphasis*{:c1} second line of paragraph {:c1} {:c1: class=c1} Attribute lists --------------- This is an example attribute list, which shows everything you can put inside: {: key1=val key2="long val" #myid .class1 .class2 ref1 ref2} More in particular, an attribute list is a whitespace-separated list of elements of 4 different kinds: 1. key/value pairs (quoted if necessary) 2. [references to ALD](#using_tags) (`ref1`,`ref2`) 3. [id specifiers](#class_id) (`#myid`) 4. [class specifiers](#class_id) (`.myclass`) ### `id` and `class` are special ### {#class_id} For ID and classes there are special shortcuts: * `#myid` is a shortcut for `id=myid` * `.myclass` means "add `myclass` to the current `class` attribute". So these are equivalent: {: .class1 .class2} {: class="class1 class2"} The following attribute lists are equivalent: {: #myid .class1 .class2} {: id=myid class=class1 .class2} {: id=myid class="class1 class2"} {: id=myid class="will be overridden" class=class1 .class2} Where to put inline attribute lists ---------------------------------- ### For block-level elements ### For paragraphs and other block-level elements, IAL go **after** the element: This is a paragraph. Line 2 of the paragraph. {: #myid .myclass} A quote with a citation url: > Who said that? {: cite=google.com} Note: empty lines between the block and the IAL are not tolerated. So this is not legal: This is a paragraph. Line 2 of the paragraph. {: #myid .myclass} Attribute lists may be indented up to 3 spaces: Paragraph1 {:ok} Paragraph2 {:ok} Paragraph2 {:ok} {:code_show_spaces} ### For headers ### For headers, you can put attribute lists on the same line: ### Header ### {: #myid} Header {: #myid .myclass} ------ or, as like other block-level elements, on the line below: ### Header ### {: #myid} Header ------ {: #myid .myclass} ### For span-level elements ### For span-level elements, meta-data goes immediately **after** in the flow. For example, in this: This is a *chunky paragraph*{: #id1} {: #id2} the ID of the `em` element is set to `id1` and the ID of the paragraph is set to `id2`. This works also for links, like this: This is [a link][ref]{:#myid rel=abc rev=abc} For images, this: This is ![Alt text](url "fresh carrots") is equivalent to: This is ![Alt text](url){:title="fresh carrots"} Using attributes lists definition {#using_tags} --------------------------------- In an attribute list, you can have: 1. `key=value` pairs, 2. id attributes (`#myid`) 3. class attributes (`.myclass`) Everything else is interpreted as a reference to an ALD. # Header # {:ref} Blah blah blah. {:ref: #myhead .myclass lang=fr} Of course, more than one IAL can reference the same ALD: # Header 1 # {:1} ... # Header 2 # {:1} {:1: .myclass lang=fr} The rules {:#grammar} --------- ### The issue of escaping ### 1. No escaping in code spans/blocks. 2. Everywhere else, **all** PUNCTUATION characters **can** be escaped, and **must** be escaped when they could trigger links, tables, etc. A punctuation character is anything not a letter, a number, or whitespace (`[^a-zA-Z0-9\s\n]`). 3. As a rule, quotes **must** be escaped inside quoted values: * Inside `"quoted values"`, you **must** escape `"`. * Inside `'quoted values'`, you **must** escape `'`. * Other examples: `"bah 'bah' bah"` = `"bah \'bah\' bah"` = `'bah \'bah\' bah'` `'bah "bah" bah'` = `'bah \"bah\" bah'` = `"bah \"bah\" bah"` 4. There is an exception for backward compatibility, in links/images titles: [text](url "title"with"quotes") The exception is not valid for attribute lists and in other contexts, where you have to use the canonical syntax. ### Syntax for attribute lists #### Consider the following attribute list: {: key=value ref key2="quoted value" } In this string, `key`, `value`, and `ref` can be substituted by any string that does not contain whitespace, or the unescaped characters `}`,`=`,`'`,`"`. Inside a quoted value you **must** escape the other kind of quote. Also, you **must** escape a closing curly brace `}` inside quoted values. This rule is for making life easier for interpreter that just want to skip the meta-data. If you don't implement this syntax, you can get rid of the IAL by using this regular expression (this is written in Ruby): r = /\{:(\\\}|[^\}])*\}/ s.gsub(r, '') # ignore metadata {:ruby} Basically: match everything contained in a couple of `{:` and `}`, taking care of escaping of `}`. This `\\\}|[^\}]` means: eat either any character which is not a `}` or an escape sequence `\}`. For this example, this is {: skipped="\}" val=\} bar} for me {: also this} the result is: this is for me maruku-0.7.2/docs/entity_test.md0000644000004100000410000000103112347070213016673 0ustar www-datawww-data List of symbols supported by Maruku =================================== maruku-0.7.2/checksums.yaml.gz.sig0000444000004100000410000000040012347070213017114 0ustar www-datawww-dataPLؚvU~6hD['("dԮ\F{qWğ<6(eXPYe:h dG ~IBG]9jD6"U軪PRz#؊@ӣu8miݽ7(gƳLtI.vݻ[s')>r+Z@ܶb2H֍M0'M6vYR,DA_kmjg(w|_}OƼȦE!'M Pmaruku-0.7.2/metadata.gz.sig0000444000004100000410000000040012347070213015746 0ustar www-datawww-data#}ԡMa9.M+SA\ӽ#3@?{kr"\D@,.nY\l yPD-w(9auzn n4tGl~ٹ'1lv7v,i1UkQ3Λ+ e@Λޥlx 0Zrc+ I97urB iek-jލ IO ֓kaUF­U[ruȽ =g8tE6ͺmaruku-0.7.2/checksums.yaml.gz0000444000004100000410000000041412347070213016340 0ustar www-datawww-dataƯSe;R0 "#X9~aRqzLJ5{.ox\||߯ te/,3T8pO_OnRBZk/JRde=bs(2}ǚH-h -^=Esh n{Y{.fh !ŐzG"ƽLU"a]mj20wy=gU  %4Ռ[❐g735EaxӨ궁gG-