maruku-0.7.3/0000755000004100000410000000000013321142720013050 5ustar www-datawww-datamaruku-0.7.3/docs/0000755000004100000410000000000013321142720014000 5ustar www-datawww-datamaruku-0.7.3/docs/proposal.md0000644000004100000410000001517513321142720016172 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.3/docs/maruku.md0000644000004100000410000002120413321142720015625 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.3/docs/div_syntax.md0000644000004100000410000000102113321142720016504 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.3/docs/other_stuff.md0000644000004100000410000000367213321142720016662 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.3/docs/markdown_syntax.md0000644000004100000410000006523113321142720017561 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.3/docs/entity_test.md0000644000004100000410000000103113321142720016670 0ustar www-datawww-data List of symbols supported by Maruku =================================== maruku-0.7.3/docs/math.md0000644000004100000410000001016213321142720015253 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.3/bin/0000755000004100000410000000000013321142720013620 5ustar www-datawww-datamaruku-0.7.3/bin/marutex0000755000004100000410000000013313321142720015230 0ustar www-datawww-data#!/usr/bin/env ruby ARGV.unshift "--pdf" load File.join(File.dirname(__FILE__), "maruku") maruku-0.7.3/bin/maruku0000755000004100000410000001125113321142720015052 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.3/spec/0000755000004100000410000000000013321142720014002 5ustar www-datawww-datamaruku-0.7.3/spec/block_spec.rb0000644000004100000410000000666013321142720016443 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.3/spec/span_spec.rb0000644000004100000410000002437513321142720016315 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(""), md_html(""), md_html("")]) *** Output of to_html *** maruku-0.7.3/spec/block_docs/issue29.md0000644000004100000410000000056713321142720017741 0ustar www-datawww-dataGenerating ids for unicode headers. Other markdown implementations drop the non-ASCII characters so the anchor is URL-valid. https://github.com/bhollis/maruku/issues/29 *** Parameters: *** {} *** Markdown input: *** # Übersicht *** Output of inspect *** md_el(:document, md_el(:header, "Übersicht", {:level=>1})) *** Output of to_html ***

Übersicht

maruku-0.7.3/spec/block_docs/list_multipara.md0000644000004100000410000000150713321142720021462 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.3/spec/block_docs/paragraph_rules/0000755000004100000410000000000013321142720021263 5ustar www-datawww-datamaruku-0.7.3/spec/block_docs/paragraph_rules/dont_merge_ref.md0000644000004100000410000000132013321142720024560 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.3/spec/block_docs/paragraph_rules/tab_is_blank.md0000644000004100000410000000066313321142720024222 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.3/spec/block_docs/header_after_par.md0000644000004100000410000000201713321142720021701 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.3/spec/block_docs/html_trailing.md0000644000004100000410000000102213321142720021256 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.3/spec/block_docs/block_quotes.md0000644000004100000410000000271013321142720021120 0ustar www-datawww-dataBlock quotes can continue over multiple lines *** Parameters: *** {} *** Markdown input: *** > Here's a quote. Which goes over two lines. > It continues here. > > And has a subquote. {: style='color:red'} > Here's a quote. > Which goes over two lines. {#foo} > Here's a quote. Which goes over two lines. *** Output of inspect *** md_el(:document,[ md_el(:quote, [md_par(["Here", md_entity("rsquo"), "s a quote. Which goes over two lines."]), md_par(["It continues here."]), md_el(:quote, md_par("And has a subquote.")) ],{},[[:style, "color:red"]]), md_el(:quote, md_par(["Here", md_entity("rsquo"), "s a quote. Which goes over two lines."]),{},[[:id, "foo"]]), md_el(:quote, md_par(["Here", md_entity("rsquo"), "s a quote. Which goes over two lines."])) ],{},[]) *** Output of to_html ***

Here’s a quote. Which goes over two lines.

It continues here.

And has a subquote.

Here’s a quote. Which goes over two lines.

Here’s a quote. Which goes over two lines.

*** Output of to_latex *** \begin{quote}% Here's a quote. Which goes over two lines. It continues here. \begin{quote}% And has a subquote. \end{quote} \end{quote} \begin{quote}% Here's a quote. Which goes over two lines. \end{quote} \begin{quote}% Here's a quote. Which goes over two lines. \end{quote}maruku-0.7.3/spec/block_docs/html4.md0000644000004100000410000000155013321142720017457 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: ***
*** Output of inspect *** md_el(:document,[ md_html("
\n\t\"\"\n\n
") ],{},[]) *** Output of to_html ***
*** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.3/spec/block_docs/inline_html2.md0000644000004100000410000000106713321142720021016 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.3/spec/block_docs/extra_dl.md0000644000004100000410000000354413321142720020236 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.3/spec/block_docs/entities.md0000644000004100000410000000716613321142720020264 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {} *** Markdown input: *** Maruku translates HTML entities to the equivalent in LaTeX: Entity | Result ------------|---------- `©` | © `£` | £ `a b` | a b `λ` | λ `—` | — Entity-substitution does not happen in code blocks or inline code. The following should not be translated: © It should read like this: `©`. *** Output of inspect *** md_el(:document,[ md_par(["Maruku translates HTML entities to the equivalent in LaTeX:"]), md_el(:table,[ [md_el(:head_cell,["Entity"],{},[]),md_el(:head_cell,["Result"],{},[])], [md_el(:cell,[md_code("©")],{},[]),md_el(:cell,[md_entity("copy")],{},[])], [md_el(:cell,[md_code("£")],{},[]),md_el(:cell,[md_entity("pound")],{},[])], [md_el(:cell,[md_code("a b")],{},[]),md_el(:cell,["a", md_entity("nbsp"), "b"],{},[])], [md_el(:cell,[md_code("λ")],{},[]),md_el(:cell,[md_entity("lambda")],{},[])], [md_el(:cell,[md_code("—")],{},[]),md_el(:cell,[md_entity("mdash")],{},[])] ],{:align=>[:left, :left]},[]), md_par([ "Entity-substitution does not happen in code blocks or inline code." ]), md_par(["The following should not be translated:"]), md_el(:code,[],{:raw_code=>"©", :lang=>nil},[]), md_par(["It should read like this: ", md_code("©"), "."]) ],{},[]) *** Output of to_html ***

Maruku translates HTML entities to the equivalent in LaTeX:

EntityResult
&copy;©
&pound;£
a&nbsp;ba b
&lambda;λ
&mdash;

Entity-substitution does not happen in code blocks or inline code.

The following should not be translated:

&copy;

It should read like this: &copy;.

*** Output of to_latex *** Maruku translates HTML entities to the equivalent in \LaTeX\xspace : \begin{tabular}{l|l} Entity&Result\\ \hline {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char38copy\char59}}&\copyright{}\\ {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char38pound\char59}}&\pounds{}\\ {\colorbox[rgb]{1.00,0.93,1.00}{\tt a\char38nbsp\char59b}}&a~b\\ {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char38lambda\char59}}&$\lambda$\\ {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char38mdash\char59}}&---\\ \end{tabular} Entity-substitution does not happen in code blocks or inline code. The following should not be translated: \begin{verbatim}©\end{verbatim} It should read like this: {\colorbox[rgb]{1.00,0.93,1.00}{\tt \char38copy\char59}}. *** Output of to_md *** Maruku translates HTML entities to the equivalent in LaTeX: Entity | Result ------------|---------- `©` | © `£` | £ `a b` | a b `λ` | λ `—` | — Entity-substitution does not happen in code blocks or inline code. The following should not be translated: © It should read like this: `©`. *** Output of to_s *** Maruku translates HTML entities to the equivalent in LaTeX:EntityResultabEntity-substitution does not happen in code blocks or inline code.The following should not be translated:It should read like this: . maruku-0.7.3/spec/block_docs/code3.md0000644000004100000410000000253513321142720017430 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.3/spec/block_docs/underscore_in_words.md0000644000004100000410000000071513321142720022506 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.3/spec/block_docs/lists_nested.md0000644000004100000410000000107613321142720021132 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.3/spec/block_docs/list12.md0000644000004100000410000000115213321142720017543 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** * [Maruku]: good. [maruku]: http://maruku.org/ *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[md_link(["Maruku"],nil), ": good."],{:want_my_paragraph=>false},[]) ],{},[]), md_ref_def("maruku", "http://maruku.org/", {:title=>nil}) ],{},[]) *** Output of to_html *** *** Output of to_latex *** \begin{itemize}% \item \href{http://maruku.org/}{Maruku}: good. \end{itemize} *** Output of to_md *** -aruku: good. *** Output of to_s *** Maruku: good. maruku-0.7.3/spec/block_docs/references/0000755000004100000410000000000013321142720020225 5ustar www-datawww-datamaruku-0.7.3/spec/block_docs/references/spaces_and_numbers.md0000644000004100000410000000053213321142720024402 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.3/spec/block_docs/references/long_example.md0000644000004100000410000000724413321142720023230 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.3/spec/block_docs/inline_html.md0000644000004100000410000000626613321142720020742 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.3/spec/block_docs/issue126.md0000644000004100000410000000041513321142720020007 0ustar www-datawww-dataHandle HTTPS links at the start of a line. https://github.com/bhollis/maruku/issues/126 *** Parameters: *** { } *** Markdown input: *** *** Output of inspect *** *** Output of to_html ***

https://google.com

maruku-0.7.3/spec/block_docs/lists_blockquote_code.md0000644000004100000410000000262613321142720023014 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.3/spec/block_docs/div_without_newline.md0000644000004100000410000000050313321142720022512 0ustar www-datawww-dataHandle blocks of block HTML without a newline. https://github.com/bhollis/maruku/issues/123 REXML won't clean up the HTML the way Nokogiri will... *** Parameters: *** { } *** Markdown input: *** Heres some HTML.
Foo
*** Output of inspect *** *** Output of to_html ***

Heres some HTML.

Foo
maruku-0.7.3/spec/block_docs/images2.md0000644000004100000410000000127613321142720017763 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.3/spec/block_docs/bad_cites.md0000644000004100000410000000710113321142720020342 0ustar www-datawww-dataComment *** Parameters: *** require 'maruku/ext/math'; {:math_enabled => true} *** Markdown input: *** 1111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111 (111 111111111111111111111111111111 1 111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111 11111111111111111111111111 11111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111 111111 11 1111111111111111111111111111111111111111111111111111111 111111111111 111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111 \cite{11111} *** Output of inspect *** md_el(:document,[ md_par(["1111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111 (111 111111111111111111111111111111 1 111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111 11111111111111111111111111 11111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111 111111 11 1111111111111111111111111111111111111111111111111111111 111111111111 111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111 ", md_el(:citation, [], {:cites=>["11111"]}) ]) ],{},[]) *** Output of to_html ***

1111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111 (111 111111111111111111111111111111 1 111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111 11111111111111111111111111 11111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111 111111 11 1111111111111111111111111111111111111111111111111111111 111111111111 111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111 [11111]

*** Output of to_latex *** 1111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111 (111 111111111111111111111111111111 1 111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111 11111111111111111111111111 11111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111 111111 11 1111111111111111111111111111111111111111111111111111111 111111111111 111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111 \cite{11111}maruku-0.7.3/spec/block_docs/lists_after_paragraph.md0000644000004100000410000001201313321142720022767 0ustar www-datawww-dataThis should not trigger the list *** 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 ### Paragraph with header on two lines: header 2 -------- Paragraph with html after
Woo
Paragraph with html after, indented: Emphasis Paragraph with html after, indented: Emphasis *tralla* Emph Paragraph with html after, indented: Emphasis *tralla* Emph *** 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"],{:level=>3},[]), md_par(["Paragraph with header on two lines:"]), md_el(:header,["header 2"],{:level=>2},[]), md_par("Paragraph with html after"), md_html("
Woo
"), md_par([ "Paragraph with html after, indented: ", md_html("Emphasis") ]), md_par([ "Paragraph with html after, indented: ", md_html("Emphasis"), " ", md_em(["tralla"]), " ", md_html("Emph") ]), md_par([ "Paragraph with html after, indented: ", md_html("Emphasis *tralla* Emph") ]) ],{},[]) *** 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:

Paragraph with header on two lines:

header 2

Paragraph with html after

Woo

Paragraph with html after, indented: Emphasis

Paragraph with html after, indented: Emphasis tralla Emph

Paragraph with html after, indented: Emphasis tralla Emph

*** 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}{}\subsubsection*{{header}}\label{header} Paragraph with header on two lines: \hypertarget{header_2}{}\subsection*{{header 2}}\label{header_2} Paragraph with html after Paragraph with html after, indented: Paragraph with html after, indented: \emph{tralla} Paragraph with html after, indented: *** 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 Paragraph with html after Paragraph with html after, indented: Paragraph with html after, indented: tralla Paragraph with html after, indented: *** 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:headerParagraph with html after Paragraph with html after, indented: Paragraph with html after, indented: tralla Paragraph with html after, indented: maruku-0.7.3/spec/block_docs/inline_html_beginning.md0000644000004100000410000000051213321142720022746 0ustar www-datawww-dataInline HTML at the beginning of a line shouldn't kill the rest of the line. https://github.com/bhollis/maruku/issues/67 *** Parameters: *** {} *** Markdown input: *** Two Half *** Output of inspect *** md_el(:document, md_par([md_html("Two"), " Half"])) *** Output of to_html ***

Two Half

maruku-0.7.3/spec/block_docs/lists_nested_deep.md0000644000004100000410000000105413321142720022123 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.3/spec/block_docs/issue31.md0000644000004100000410000000133113321142720017720 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.3/spec/block_docs/tables2.md0000644000004100000410000000762413321142720017773 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.3/spec/block_docs/toc.md0000644000004100000410000000571013321142720017216 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:use_numbered_headers => true} *** Markdown input: *** * Table of Contents {:toc} A title with *emphasis* ======================= ## Try ## {#try} First Subheader --------------- {#foo} Say something. ### A title with *emphasis* ### Say something else. Second Subheader -------------- You don't say. *** Output of inspect *** md_el(:document,[ md_el(:ul, md_el(:li, "Table of Contents", {:want_my_paragraph=>false}), {}, [[:ref, "toc"]]), md_el(:header,["A title with ", md_em(["emphasis"])],{:level=>1},[]), md_el(:header, "Try", {:level=>2}, [[:id, "try"]]), md_el(:header, "First Subheader", {:level=>2}), md_par("Say something."), md_el(:header, ["A title with ", md_em("emphasis")], {:level=>3}), md_par("Say something else."), md_el(:header, "Second Subheader", {:level=>2}), md_par(["You don", md_entity("rsquo"), "t say."]) ],{},[]) *** Output of to_html ***

A title with emphasis

1. Try

2. First Subheader

Say something.

2.1. A title with emphasis

Say something else.

3. Second Subheader

You don’t say.

*** Output of to_latex *** \noindent1. \hyperlink{try}{Try}\dotfill \pageref*{try} \linebreak \noindent2. \hyperlink{foo}{First Subheader}\dotfill \pageref*{foo} \linebreak \noindent2.1. \hyperlink{a_title_with_emphasis_2}{A title with \emph{emphasis}}\dotfill \pageref*{a_title_with_emphasis_2} \linebreak \noindent3. \hyperlink{second_subheader}{Second Subheader}\dotfill \pageref*{second_subheader} \linebreak \hypertarget{a_title_with_emphasis}{}\section*{{A title with \emph{emphasis}}}\label{a_title_with_emphasis} \hypertarget{try}{}\subsection*{{1. Try}}\label{try} \hypertarget{foo}{}\subsection*{{2. First Subheader}}\label{foo} Say something. \hypertarget{a_title_with_emphasis_2}{}\subsubsection*{{2.1. A title with \emph{emphasis}}}\label{a_title_with_emphasis_2} Say something else. \hypertarget{second_subheader}{}\subsection*{{3. Second Subheader}}\label{second_subheader} You don't say. *** 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.3/spec/block_docs/issue90.md0000644000004100000410000000227213321142720017732 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.3/spec/block_docs/issue106.md0000644000004100000410000000265113321142720020011 0ustar www-datawww-dataCode with list-delimiters in it - https://github.com/bhollis/maruku/issues/106 *** Parameters: *** {} *** Markdown input: *** This is code (4 spaces): * Code * Code (again) This is also code * Code * Code (again) This is code (1 tab): * Code * Code (again) *** Output of inspect *** md_el(:document,[ md_par(["This is code (4 spaces):"]), md_el(:code,[],{:raw_code=>"* Code * Code (again)", :lang=>nil},[]), md_par(["This is also code"]), md_el(:code,[],{:raw_code=>"* Code * Code (again)", :lang=>nil},[]), md_par(["This is code (1 tab):"]), md_el(:code,[],{:raw_code=>"* Code * Code (again)", :lang=>nil},[]) ],{},[]) *** Output of to_html ***

This is code (4 spaces):

* Code
  * Code (again)

This is also code

* Code
* Code (again)

This is code (1 tab):

* Code
	* Code (again)
*** Output of to_latex *** This is code (4 spaces): \begin{verbatim}* Code * Code (again)\end{verbatim} This is also code \begin{verbatim}* Code * Code (again)\end{verbatim} This is code (1 tab): \begin{verbatim}* Code * Code (again)\end{verbatim} *** Output of to_md *** This is code (4 spaces): * Code * Code (again) This is also code * Code * Code (again) This is code (1 tab): * Code * Code (again) *** Output of to_s *** This is code (4 spaces):This is also codeThis is code (1 tab): maruku-0.7.3/spec/block_docs/math-blahtex/0000755000004100000410000000000013321142720020462 5ustar www-datawww-datamaruku-0.7.3/spec/block_docs/math-blahtex/table.md0000644000004100000410000000135113321142720022073 0ustar www-datawww-dataWrite a comment here *** Parameters: *** require 'maruku/ext/math';{:html_math_engine => 'blahtex' } *** 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 *** α
β
*** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.3/spec/block_docs/math-blahtex/math2.md0000644000004100000410000000277513321142720022032 0ustar www-datawww-data *** Parameters: *** require 'maruku/ext/math' {:math_numbered => ['\\['], :html_math_engine => 'blahtex' } *** 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) α
α
β
γ
*** 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.3/spec/block_docs/math-blahtex/inline.md0000644000004100000410000000271513321142720022267 0ustar www-datawww-data *** Parameters: *** require 'maruku/ext/math'; {:html_math_engine => 'blahtex'} *** 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:

  • α
  • xn+ynzn

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.3/spec/block_docs/math-blahtex/equations.md0000644000004100000410000000210213321142720023007 0ustar www-datawww-dataWrite a comment here *** Parameters: *** require 'maruku/ext/math';{:html_math_engine => 'blahtex'} *** Markdown input: *** $$ x = y $$ $$ x = y $$ $$ x = y $$ $$ x = y $$ *** Output of inspect *** *** Output of to_html ***
x=y
x=y
x=y
x=y
*** Output of to_latex *** maruku-0.7.3/spec/block_docs/test.md0000644000004100000410000000066613321142720017415 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.3/spec/block_docs/abbreviations.md0000644000004100000410000000345413321142720021264 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.3/spec/block_docs/email.md0000644000004100000410000000205013321142720017512 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.3/spec/block_docs/bug_table.md0000644000004100000410000000225313321142720020354 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.3/spec/block_docs/code.md0000644000004100000410000000146113321142720017342 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.3/spec/block_docs/lists_paraindent.md0000644000004100000410000000105013321142720021765 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.3/spec/block_docs/data_loss.md0000644000004100000410000000071013321142720020375 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** 1. abcd efgh ijkl *** Output of inspect *** md_el(:document,[ md_el(:ol,[md_el(:li,["abcd efgh ijkl"],{:want_my_paragraph=>false},[])],{},[]) ],{},[]) *** Output of to_html ***
  1. abcd efgh ijkl
*** Output of to_latex *** \begin{enumerate}% \item abcd efgh ijkl \end{enumerate} *** Output of to_md *** 1. abcd efgh ijkl *** Output of to_s *** abcd efgh ijkl maruku-0.7.3/spec/block_docs/hrule.md0000644000004100000410000000124013321142720017542 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.3/spec/block_docs/issue64.md0000644000004100000410000000171613321142720017735 0ustar www-datawww-dataNested list with a single item. https://github.com/bhollis/maruku/issues/64 *** Parameters: *** {} *** Markdown input: *** A nested list with a single item (does not work) - three items: - item 1 - item 2 - item 3 - one item: - item - two items: - item a - item b *** Output of inspect *** md_el(:document, [ md_par("A nested list with a single item (does not work)"), md_el(:ul, [ md_li([ "three items:", md_el(:ul, [ md_li("item 1", false), md_li("item 2", false), md_li("item 3", false) ]) ], false), md_li(["one item:", md_el(:ul, md_li("item", false))], false), md_li([ "two items:", md_el(:ul, [md_li("item a", false), md_li("item b", false)]) ], false) ]) ]) *** Output of to_html ***

A nested list with a single item (does not work)

  • three items:
    • item 1
    • item 2
    • item 3
  • one item:
    • item
  • two items:
    • item a
    • item b
maruku-0.7.3/spec/block_docs/wrapping.md0000644000004100000410000000747213321142720020267 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.3/spec/block_docs/lists_tab.md0000644000004100000410000000145013321142720020412 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.3/spec/block_docs/lists_need_blank_line.md0000644000004100000410000000311113321142720022731 0ustar www-datawww-datalist syntax needs a newline before it to be a valid list! *** Parameters: *** {} *** Markdown input: *** This is not a list: * one * two This is a list: * one * two This is a list: * one ciao This is a list: 1. one 1. two This is a list: 1987. one ciao *** Output of inspect *** md_el(:document,[ md_par(["This is not a list: * one * two"]), md_par(["This is a list:"]), md_el(:ul,[md_li("one", false), md_li("two", false)],{},[]), md_par(["This is a list:"]), md_el(:ul,md_li("one ciao", false),{},[]), md_par(["This is a list:"]), md_el(:ol,[md_li("one", false), md_li("two", false)],{},[]), md_par(["This is a list:"]), md_el(:ol,md_li("one ciao", false),{},[]) ],{},[]) *** Output of to_html ***

This is not a list: * one * two

This is a list:

  • one
  • two

This is a list:

  • one ciao

This is a list:

  1. one
  2. two

This is a list:

  1. one ciao
*** Output of to_latex *** This is not a list: * one * two This is a list: \begin{itemize}% \item one \item two \end{itemize} This is a list: \begin{itemize}% \item one ciao \end{itemize} This is a list: \begin{enumerate}% \item one \item two \end{enumerate} This is a list: \begin{enumerate}% \item one ciao \end{enumerate} *** Output of to_md *** This is a list: -ne -wo This is not a list: * one ciao This is a list: 1. one 2. two This is not a list: 1987. one ciao *** Output of to_s *** This is a list:onetwoThis is not a list: * one ciaoThis is a list:onetwoThis is not a list: 1987. one ciao maruku-0.7.3/spec/block_docs/extra_header_id.md0000644000004100000410000000416113321142720021537 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.3/spec/block_docs/tables.md0000644000004100000410000000463713321142720017712 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.3/spec/block_docs/lists_nested_blankline.md0000644000004100000410000000072213321142720023146 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.3/spec/block_docs/empty_cells.md0000644000004100000410000000174513321142720020755 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.3/spec/block_docs/images.md0000644000004100000410000000731713321142720017703 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.3/spec/block_docs/issue20.md0000644000004100000410000000045413321142720017723 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.3/spec/block_docs/extra_table1.md0000644000004100000410000000236613321142720021010 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:css=>"style.css"} *** Markdown input: *** CSS: style.css 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,["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 ***
First HeaderSecond Header
Content CellContent Cell
Content CellContent Cell
*** Output of to_latex *** \begin{tabular}{l|l} First Header&Second Header\\ \hline Content Cell&Content Cell\\ Content Cell&Content Cell\\ \end{tabular} *** Output of to_md *** First HeaderSecond HeaderContent CellContent CellContent CellContent Cell *** Output of to_s *** First HeaderSecond HeaderContent CellContent CellContent CellContent Cell maruku-0.7.3/spec/block_docs/encoding/0000755000004100000410000000000013321142720017672 5ustar www-datawww-datamaruku-0.7.3/spec/block_docs/encoding/iso-8859-1.md0000644000004100000410000000107313321142720021560 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.3/spec/block_docs/encoding/utf-8.md0000644000004100000410000000073613321142720021165 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.3/spec/block_docs/attributes/0000755000004100000410000000000013321142720020272 5ustar www-datawww-datamaruku-0.7.3/spec/block_docs/attributes/circular.md0000644000004100000410000000065713321142720022430 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.3/spec/block_docs/attributes/att2.md0000644000004100000410000000051213321142720021464 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.3/spec/block_docs/attributes/att3.md0000644000004100000410000000075313321142720021474 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.3/spec/block_docs/attributes/attributes.md0000644000004100000410000000327213321142720023006 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.3/spec/block_docs/attributes/default.md0000644000004100000410000000074013321142720022241 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.3/spec/block_docs/issue67.md0000644000004100000410000000076513321142720017743 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.3/spec/block_docs/ticks.md0000644000004100000410000000103013321142720017535 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.3/spec/block_docs/hex_entities.md0000644000004100000410000000267113321142720021124 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef. *** Output of inspect *** md_el(:document,[ md_par([ "Examples of numeric character references include ", md_entity(169), " or ", md_entity(169), " for the copyright symbol, ", md_entity(913), " or ", md_entity(913), " for the Greek capital letter alpha, and ", md_entity(1575), " or ", md_entity(1575), " for the Arabic letter alef." ]) ],{},[]) *** Output of to_html ***

Examples of numeric character references include © or © for the copyright symbol, Α or Α for the Greek capital letter alpha, and ا or ا for the Arabic letter alef.

*** Output of to_latex *** Examples of numeric character references include \copyright{} or \copyright{} for the copyright symbol, $A$ or $A$ for the Greek capital letter alpha, and or for the Arabic letter alef. *** Output of to_md *** Examples of numeric character references include &169; or &169; for the copyright symbol, &913; or &913; for the Greek capital letter alpha, and &1575; or &1575; for the Arabic letter alef. *** Output of to_s *** Examples of numeric character references include or for the copyright symbol, or for the Greek capital letter alpha, and or for the Arabic letter alef. maruku-0.7.3/spec/block_docs/footnotes2.md0000644000004100000410000000576313321142720020543 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.3/spec/block_docs/escaping.md0000644000004100000410000000417713321142720020230 0ustar www-datawww-dataThis should threat the last as a literal asterisk. *** Parameters: *** {:on_error=>:warning} *** Markdown input: *** Hello: ! \! \` \{ \} \[ \] \( \) \# \. \! * \* * Ora, *emphasis*, **bold**, * <- due asterischi-> * , un underscore-> _ , _emphasis_, incre*dible*e! This is ``Code with a special: -> ` <- ``(after) `Start ` of paragraph End of `paragraph ` *** Output of inspect *** md_el(:document,[ md_par(["Hello: ! ! ` { } [ ] ( ) # . ! * * *"]), md_par([ "Ora, ", md_em(["emphasis"]), ", ", md_strong(["bold"]), ", * <- due asterischi-> * , un underscore-> _ , ", md_em(["emphasis"]), ", incre", md_em(["dible"]), "e!" ]), md_par(["This is ", md_code("Code with a special: -> ` <-"), "(after)"]), md_par([md_code("Start "), " of paragraph"]), md_par(["End of ", md_code("paragraph ")]) ],{},[]) *** Output of to_html ***

Hello: ! ! ` { } [ ] ( ) # . ! * * *

Ora, emphasis, bold, * <- due asterischi-> * , un underscore-> _ , emphasis, incrediblee!

This is Code with a special: -> ` <-(after)

Start of paragraph

End of paragraph

*** Output of to_latex *** Hello: ! ! ` \{ \} [ ] ( ) \# . ! * * * Ora, \emph{emphasis}, \textbf{bold}, * {\tt \symbol{60}}- due asterischi-{\tt \symbol{62}} * , un underscore-{\tt \symbol{62}} \_ , \emph{emphasis}, incre\emph{dible}e! This is {\colorbox[rgb]{1.00,0.93,1.00}{\tt Code\char32with\char32a\char32special\char58\char32\char45\char62\char32\char96\char32\char60\char45}}(after) {\colorbox[rgb]{1.00,0.93,1.00}{\tt Start\char32}} of paragraph End of {\colorbox[rgb]{1.00,0.93,1.00}{\tt paragraph\char32}} *** Output of to_md *** Hello: ! \! \` \{ \} \[ \] \( \) \# \. \! * \* * Ora, *emphasis*, **bold**, * <- due asterischi-> * , un underscore-> _ , *emphasis*, incre*dible*e! This is ``Code with a special: -> ` <- ``(after) `Start ` of paragraph End of `paragraph ` *** Output of to_s *** Hello: ! ! ` { } [ ] ( ) # . ! * * *Ora, emphasis, bold, * <- due asterischi-> * , un underscore-> _ , emphasis, incrediblee!This is (after) of paragraphEnd of maruku-0.7.3/spec/block_docs/auto_cdata.md0000644000004100000410000000161313321142720020533 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.3/spec/block_docs/smartypants.md0000644000004100000410000000633213321142720021017 0ustar www-datawww-data *** Parameters: *** {} *** Markdown input: *** 'Twas a "test" to 'remember' in the '90s. 'Twas a "test" to 'remember' in the '90s. It was --- in a sense --- really... interesting. It was --- in a sense --- really... interesting. I -- too -- met << some curly quotes >> there or <>No space. I -- too -- met << some curly quotes >> there or <>No space. She was 6\"12\'. > She was 6\"12\'. *** Output of inspect *** md_el(:document,[ md_el(:code,[],{:raw_code=>"'Twas a \"test\" to 'remember' in the '90s.", :lang=>nil},[]), md_par([ md_entity("lsquo"), "Twas a ", md_entity("ldquo"), "test", md_entity("rdquo"), " to ", md_entity("lsquo"), "remember", md_entity("rsquo"), " in the ", md_entity("rsquo"), "90s." ]), md_el(:code,[],{:raw_code=>"It was --- in a sense --- really... interesting.", :lang=>nil},[]), md_par([ "It was ", md_entity("mdash"), " in a sense ", md_entity("mdash"), " really", md_entity("hellip"), " interesting." ]), md_el(:code,[],{:raw_code=>"I -- too -- met << some curly quotes >> there or <>No space.", :lang=>nil},[]), md_par([ "I ", md_entity("ndash"), " too ", md_entity("ndash"), " met ", md_entity("laquo"), md_entity("nbsp"), "some curly quotes", md_entity("nbsp"), md_entity("raquo"), " there or ", md_entity("laquo"), "here", md_entity("raquo"), "No space." ]), md_el(:code,[],{:raw_code=>"She was 6\\\"12\\'.", :lang=>nil},[]), md_el(:quote,[ md_par(["She was 6", md_entity("quot"), "12", md_entity("apos"), "."]) ],{},[]) ],{},[]) *** Output of to_html ***
'Twas a "test" to 'remember' in the '90s.

‘Twas a “test” to ‘remember’ in the ’90s.

It was --- in a sense --- really... interesting.

It was — in a sense — really… interesting.

I -- too -- met << some curly quotes >> there or <<here>>No space.

I – too – met « some curly quotes » there or «here»No space.

She was 6\"12\'.

She was 6"12'.

*** Output of to_latex *** \begin{verbatim}'Twas a "test" to 'remember' in the '90s.\end{verbatim} `Twas a ``test'' to `remember' in the '90s. \begin{verbatim}It was --- in a sense --- really... interesting.\end{verbatim} It was --- in a sense --- really\ldots{} interesting. \begin{verbatim}I -- too -- met << some curly quotes >> there or <>No space.\end{verbatim} I -- too -- met \guillemotleft{}~some curly quotes~\guillemotright{} there or \guillemotleft{}here\guillemotright{}No space. \begin{verbatim}She was 6\"12\'.\end{verbatim} \begin{quote}% She was 6"12'. \end{quote} *** Output of to_md *** 'Twas a "test" to 'remember' in the '90s. 'Twas a "test" to 'remember' in the '90s. It was --- in a sense --- really... interesting. It was --- in a sense --- really... interesting. I -- too -- met << some curly quotes >> there or <>No space. I -- too -- met << some curly quotes >> there or <>No space. She was 6\"12\'. > She was 6\"12\'. *** Output of to_s *** Twas a test to remember in the 90s.It was in a sense really interesting.I too met some curly quotes there or hereNo space.She was 612. maruku-0.7.3/spec/block_docs/headers.md0000644000004100000410000000245113321142720020043 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.3/spec/block_docs/table_colspan.md0000644000004100000410000000354413321142720021242 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.3/spec/block_docs/issue70.md0000644000004100000410000000045613321142720017732 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.3/spec/block_docs/issue115.md0000644000004100000410000000075713321142720020016 0ustar www-datawww-dataMarkdown in comments should not be parsed. https://github.com/bhollis/maruku/issues/115 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("")]) *** Output of to_html *** maruku-0.7.3/spec/block_docs/misc_sw.md0000644000004100000410000006574013321142720020106 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:archive=>false, :date=>"Nov 20 2006", :inmenu=>true, :subject_short=>"painless software", :subject=>"Software not painful to use", :topic=>"/misc/coolsw", :order=>"-9.5"} *** Markdown input: *** Subject: Software not painful to use Subject_short: painless software Topic: /misc/coolsw Archive: no Date: Nov 20 2006 Order: -9.5 inMenu: true ### General ### * *Operating System* : [Mac OS X][switch]: heaven, after the purgatory of Linux and the hell of Windows. * *Browser*: [Firefox][firefox]. On a Mac, [Camino][camino]. * *Email*: [GMail][gmail], "search, don't sort" really works. * *Text Editor*: [TextMate][textmate], you have to buy it, but it's worth every penny. There are rumours that it's been converting (recovering) Emacs users (addicts). Unfortunately, it's Mac only. An alternative is [jedit][jedit] (GPL, Java). ### Development ### * *Build system*: [cmake][cmake], throw the [autotools][autotools] away. * *Source code control system*: ditch CVS for [subversion][subversion]. * *Project management*: [Trac][trac] tracks everything. * *Scripting language*: [Ruby][ruby] is Japanese pragmatism (and has a [poignant][poignant] guide). Python, you say? Python is too academic and snob: $ python Python 2.4.1 (\#1, Jun 4 2005, 00:54:33) Type "help", "copyright", "credits" or "license" for more information. >>> exit 'Use Ctrl-D (i.e. EOF) to exit.' >>> quit 'Use Ctrl-D (i.e. EOF) to exit.' * *Java IDE*: [JBuilder][jbuilder] is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained [generics][java-generics] and got opensourced. * *Mark-up language*: HTML is so 2001, why don't you take at look at [Markdown][markdown]? [Look at the source of this page](data/misc_markdown.png). * *C++ libraries*: * [QT][qt] for GUIs. * [GSL][gsl] for math. * [Magick++][magick] for manipulating images. * [Cairo][cairo] for creating PDFs. * [Boost][boost] for just about everything else. ### Research ### * *Writing papers*: [LaTeX][latex] * *Writing papers & enjoying the process*: [LyX][lyx] * *Handsome figures in your papers*: [xfig][xfig] or, better, [jfig][jfig]. * *The occasional presentation with many graphical content*: [OpenOffice Impress][impress] (using the [OOOlatex plugin][ooolatex]); the alternative is PowerPoint with the [TexPoint][texpoint] plugin. * *Managing BibTeX*: [jabref][jabref]: multi-platform, for all your bibtex needs. * *IEEExplore and BibTeX*: convert citations using [BibConverter][bibconverter]. ### Cool websites ### * *Best site in the wwworld*: [Wikipedia][wikipedia] * [Mutopia][mutopia] for sheet music; [the Gutenberg Project][gutenberg] for books; [LiberLiber][liberliber] for books in italian. * *Blogs*: [Bloglines][bloglines] * *Sharing photos*: [flickr][flickr] exposes an API you can use. [firefox]: http://getfirefox.com/ [gmail]: http://gmail.com/ [bloglines]: http://bloglines.com/ [wikipedia]: http://en.wikipedia.org/ [ruby]: http://www.ruby-lang.org/ [poignant]: http://poignantguide.net/ruby/ [webgen]: http://webgen.rubyforge.org/ [markdown]: http://daringfireball.net/projects/markdown/ [latex]: http://en.wikipedia.org/wiki/LaTeX [lyx]: http://www.lyx.org [impress]: http://www.openoffice.org/product/impress.html [ooolatex]: http://ooolatex.sourceforge.net/ [texpoint]: http://texpoint.necula.org/ [jabref]: https://www.jabref.org/ [camino]: http://www.caminobrowser.org/ [switch]: http://www.apple.com/getamac/ [textmate]: http://www.apple.com/getamac/ [cmake]: http://www.cmake.org/ [xfig]: http://www.xfig.org/ [jfig]: http://tams-www.informatik.uni-hamburg.de/applets/jfig/ [subversion]: http://subversion.tigris.org [jbuilder]: http://www.borland.com/us/products/jbuilder/index.html [flickr]: http://www.flickr.com/ [myflickr]: http://www.flickr.com/photos/censi [bibconverter]: http://www.bibconverter.net/ieeexplore/ [autotools]: http://sources.redhat.com/autobook/ [jedit]: http://www.jedit.org/ [qt]: http://www.trolltech.no/ [gsl]: http://www.gnu.org/software/gsl/ [magick]: http://www.imagemagick.org/Magick++/ [cairo]: http://cairographics.org/ [boost]: http://www.boost.org/ [markdown]: http://en.wikipedia.org/wiki/Markdown [trac]: http://trac.edgewall.org/ [mutopia]: http://www.mutopiaproject.org/ [liberliber]: http://www.liberliber.it/ [gutenberg]: http://www.gutenberg.org/ [java-generics]: http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html *** Output of inspect *** md_el(:document,[ md_el(:header,["General"],{:level=>3},[]), md_el(:ul,[ md_el(:li,[ md_em(["Operating System"]), " : ", md_link(["Mac OS X"],"switch"), ": heaven, after the purgatory of Linux and the hell of Windows." ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Browser"]), ": ", md_link(["Firefox"],"firefox"), ". On a Mac, ", md_link(["Camino"],"camino"), "." ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Email"]), ": ", md_link(["GMail"],"gmail"), ", ", md_entity("ldquo"), "search, don", md_entity("rsquo"), "t sort", md_entity("rdquo"), " really works." ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Text Editor"]), ": ", md_link(["TextMate"],"textmate"), ", you have to buy it, but it", md_entity("rsquo"), "s worth every penny. There are rumours that it", md_entity("rsquo"), "s been converting (recovering) Emacs users (addicts). Unfortunately, it", md_entity("rsquo"), "s Mac only. An alternative is ", md_link(["jedit"],"jedit"), " (GPL, Java)." ],{:want_my_paragraph=>false},[]) ],{},[]), md_el(:header,["Development"],{:level=>3},[]), md_el(:ul,[ md_el(:li,[ md_par([ md_em(["Build system"]), ": ", md_link(["cmake"],"cmake"), ", throw the ", md_link(["autotools"],"autotools"), " away." ]) ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_par([ md_em(["Source code control system"]), ": ditch CVS for ", md_link(["subversion"],"subversion"), "." ]) ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_par([ md_em(["Project management"]), ": ", md_link(["Trac"],"trac"), " tracks everything." ]) ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_par([ md_em(["Scripting language"]), ": ", md_link(["Ruby"],"ruby"), " is Japanese pragmatism (and has a ", md_link(["poignant"],"poignant"), " guide). Python, you say? Python is too academic and snob:" ]), md_el(:code,[],{:raw_code=>"$ python \nPython 2.4.1 (\\#1, Jun 4 2005, 00:54:33) \nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n>>> exit\n'Use Ctrl-D (i.e. EOF) to exit.'\n>>> quit\n'Use Ctrl-D (i.e. EOF) to exit.'", :lang=>nil},[]) ],{:want_my_paragraph=>true},[]), md_el(:li,[ md_par([ md_em(["Java IDE"]), ": ", md_link(["JBuilder"],"jbuilder"), " is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained ", md_link(["generics"],"java-generics"), " and got opensourced." ]) ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_par([ md_em(["Mark-up language"]), ": HTML is so 2001, why don", md_entity("rsquo"), "t you take at look at ", md_link(["Markdown"],"markdown"), "? ", md_im_link(["Look at the source of this page"], "data/misc_markdown.png", nil), "." ]) ],{:want_my_paragraph=>false},[]), md_li([ md_par([md_em("C++ libraries"), ":"]), md_el(:ul, [ md_el(:li, [md_link("QT", "qt"), " for GUIs."], {:want_my_paragraph=>false}), md_el(:li, [md_link("GSL", "gsl"), " for math."], {:want_my_paragraph=>false}), md_el(:li, [md_link("Magick++", "magick"), " for manipulating images."], {:want_my_paragraph=>false}), md_el(:li, [md_link("Cairo", "cairo"), " for creating PDFs."], {:want_my_paragraph=>false}), md_el(:li, [md_link("Boost", "boost"), " for just about everything else."], {:want_my_paragraph=>false}) ]) ], false) ],{},[]), md_el(:header,["Research"],{:level=>3},[]), md_el(:ul,[ md_el(:li,[md_em(["Writing papers"]), ": ", md_link(["LaTeX"],"latex")],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Writing papers & enjoying the process"]), ": ", md_link(["LyX"],"lyx") ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Handsome figures in your papers"]), ": ", md_link(["xfig"],"xfig"), " or, better, ", md_link(["jfig"],"jfig"), "." ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["The occasional presentation with many graphical content"]), ": ", md_link(["OpenOffice Impress"],"impress"), " (using the ", md_link(["OOOlatex plugin"],"ooolatex"), "); the alternative is PowerPoint with the ", md_link(["TexPoint"],"texpoint"), " plugin." ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Managing BibTeX"]), ": ", md_link(["jabref"],"jabref"), ": multi-platform, for all your bibtex needs." ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["IEEExplore and BibTeX"]), ": convert citations using ", md_link(["BibConverter"],"bibconverter"), "." ],{:want_my_paragraph=>false},[]) ],{},[]), md_el(:header,["Cool websites"],{:level=>3},[]), md_el(:ul,[ md_el(:li,[ md_em(["Best site in the wwworld"]), ": ", md_link(["Wikipedia"],"wikipedia") ],{:want_my_paragraph=>false},[]), md_el(:li,[ md_link(["Mutopia"],"mutopia"), " for sheet music; ", md_link(["the Gutenberg Project"],"gutenberg"), " for books; ", md_link(["LiberLiber"],"liberliber"), " for books in italian." ],{:want_my_paragraph=>false},[]), md_el(:li,[md_em(["Blogs"]), ": ", md_link(["Bloglines"],"bloglines")],{:want_my_paragraph=>false},[]), md_el(:li,[ md_em(["Sharing photos"]), ": ", md_link(["flickr"],"flickr"), " exposes an API you can use." ],{:want_my_paragraph=>false},[]) ],{},[]), md_ref_def("firefox", "http://getfirefox.com/", {:title=>nil}), md_ref_def("gmail", "http://gmail.com/", {:title=>nil}), md_ref_def("bloglines", "http://bloglines.com/", {:title=>nil}), md_ref_def("wikipedia", "http://en.wikipedia.org/", {:title=>nil}), md_ref_def("ruby", "http://www.ruby-lang.org/", {:title=>nil}), md_ref_def("poignant", "http://poignantguide.net/ruby/", {:title=>nil}), md_ref_def("webgen", "http://webgen.rubyforge.org/", {:title=>nil}), md_ref_def("markdown", "http://daringfireball.net/projects/markdown/", {:title=>nil}), md_ref_def("latex", "http://en.wikipedia.org/wiki/LaTeX", {:title=>nil}), md_ref_def("lyx", "http://www.lyx.org", {:title=>nil}), md_ref_def("impress", "http://www.openoffice.org/product/impress.html", {:title=>nil}), md_ref_def("ooolatex", "http://ooolatex.sourceforge.net/", {:title=>nil}), md_ref_def("texpoint", "http://texpoint.necula.org/", {:title=>nil}), md_ref_def("jabref", "https://www.jabref.org/", {:title=>nil}), md_ref_def("camino", "http://www.caminobrowser.org/", {:title=>nil}), md_ref_def("switch", "http://www.apple.com/getamac/", {:title=>nil}), md_ref_def("textmate", "http://www.apple.com/getamac/", {:title=>nil}), md_ref_def("cmake", "http://www.cmake.org/", {:title=>nil}), md_ref_def("xfig", "http://www.xfig.org/", {:title=>nil}), md_ref_def("jfig", "http://tams-www.informatik.uni-hamburg.de/applets/jfig/", {:title=>nil}), md_ref_def("subversion", "http://subversion.tigris.org", {:title=>nil}), md_ref_def("jbuilder", "http://www.borland.com/us/products/jbuilder/index.html", {:title=>nil}), md_ref_def("flickr", "http://www.flickr.com/", {:title=>nil}), md_ref_def("myflickr", "http://www.flickr.com/photos/censi", {:title=>nil}), md_ref_def("bibconverter", "http://www.bibconverter.net/ieeexplore/", {:title=>nil}), md_ref_def("autotools", "http://sources.redhat.com/autobook/", {:title=>nil}), md_ref_def("jedit", "http://www.jedit.org/", {:title=>nil}), md_ref_def("qt", "http://www.trolltech.no/", {:title=>nil}), md_ref_def("gsl", "http://www.gnu.org/software/gsl/", {:title=>nil}), md_ref_def("magick", "http://www.imagemagick.org/Magick++/", {:title=>nil}), md_ref_def("cairo", "http://cairographics.org/", {:title=>nil}), md_ref_def("boost", "http://www.boost.org/", {:title=>nil}), md_ref_def("markdown", "http://en.wikipedia.org/wiki/Markdown", {:title=>nil}), md_ref_def("trac", "http://trac.edgewall.org/", {:title=>nil}), md_ref_def("mutopia", "http://www.mutopiaproject.org/", {:title=>nil}), md_ref_def("liberliber", "http://www.liberliber.it/", {:title=>nil}), md_ref_def("gutenberg", "http://www.gutenberg.org/", {:title=>nil}), md_ref_def("java-generics", "http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html", {:title=>nil}) ],{},[]) *** Output of to_html ***

General

  • Operating System : Mac OS X: heaven, after the purgatory of Linux and the hell of Windows.
  • Browser: Firefox. On a Mac, Camino.
  • Email: GMail, “search, don’t sort” really works.
  • Text Editor: TextMate, you have to buy it, but it’s worth every penny. There are rumours that it’s been converting (recovering) Emacs users (addicts). Unfortunately, it’s Mac only. An alternative is jedit (GPL, Java).

Development

  • Build system: cmake, throw the autotools away.

  • Source code control system: ditch CVS for subversion.

  • Project management: Trac tracks everything.

  • Scripting language: Ruby is Japanese pragmatism (and has a poignant guide). Python, you say? Python is too academic and snob:

    $ python       
    Python 2.4.1 (\#1, Jun  4 2005, 00:54:33) 
    Type "help", "copyright", "credits" or "license" for more information.
    >>> exit
    'Use Ctrl-D (i.e. EOF) to exit.'
    >>> quit
    'Use Ctrl-D (i.e. EOF) to exit.'
  • Java IDE: JBuilder is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained generics and got opensourced.

  • Mark-up language: HTML is so 2001, why don’t you take at look at Markdown? Look at the source of this page.

  • C++ libraries:

    • QT for GUIs.
    • GSL for math.
    • Magick++ for manipulating images.
    • Cairo for creating PDFs.
    • Boost for just about everything else.

Research

  • Writing papers: LaTeX
  • Writing papers & enjoying the process: LyX
  • Handsome figures in your papers: xfig or, better, jfig.
  • The occasional presentation with many graphical content: OpenOffice Impress (using the OOOlatex plugin); the alternative is PowerPoint with the TexPoint plugin.
  • Managing BibTeX: jabref: multi-platform, for all your bibtex needs.
  • IEEExplore and BibTeX: convert citations using BibConverter.

Cool websites

*** Output of to_latex *** \hypertarget{general}{}\subsubsection*{{General}}\label{general} \begin{itemize}% \item \emph{Operating System} : \href{http://www.apple.com/getamac/}{Mac OS X}: heaven, after the purgatory of Linux and the hell of Windows. \item \emph{Browser}: \href{http://getfirefox.com/}{Firefox}. On a Mac, \href{http://www.caminobrowser.org/}{Camino}. \item \emph{Email}: \href{http://gmail.com/}{GMail}, ``search, don't sort'' really works. \item \emph{Text Editor}: \href{http://www.apple.com/getamac/}{TextMate}, you have to buy it, but it's worth every penny. There are rumours that it's been converting (recovering) Emacs users (addicts). Unfortunately, it's Mac only. An alternative is \href{http://www.jedit.org/}{jedit} (GPL, Java). \end{itemize} \hypertarget{development}{}\subsubsection*{{Development}}\label{development} \begin{itemize}% \item \emph{Build system}: \href{http://www.cmake.org/}{cmake}, throw the \href{http://sources.redhat.com/autobook/}{autotools} away. \item \emph{Source code control system}: ditch CVS for \href{http://subversion.tigris.org}{subversion}. \item \emph{Project management}: \href{http://trac.edgewall.org/}{Trac} tracks everything. \item \emph{Scripting language}: \href{http://www.ruby-lang.org/}{Ruby} is Japanese pragmatism (and has a \href{http://poignantguide.net/ruby/}{poignant} guide). Python, you say? Python is too academic and snob: \begin{verbatim}$ python Python 2.4.1 (\#1, Jun 4 2005, 00:54:33) Type "help", "copyright", "credits" or "license" for more information. >>> exit 'Use Ctrl-D (i.e. EOF) to exit.' >>> quit 'Use Ctrl-D (i.e. EOF) to exit.'\end{verbatim} \item \emph{Java IDE}: \href{http://www.borland.com/us/products/jbuilder/index.html}{JBuilder} is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained \href{http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html}{generics} and got opensourced. \item \emph{Mark-up language}: HTML is so 2001, why don't you take at look at \href{http://en.wikipedia.org/wiki/Markdown}{Markdown}? \href{data/misc_markdown.png}{Look at the source of this page}. \item \emph{C++ libraries}: \begin{itemize}% \item \href{http://www.trolltech.no/}{QT} for GUIs. \item \href{http://www.gnu.org/software/gsl/}{GSL} for math. \item \href{http://www.imagemagick.org/Magick++/}{Magick++} for manipulating images. \item \href{http://cairographics.org/}{Cairo} for creating PDFs. \item \href{http://www.boost.org/}{Boost} for just about everything else. \end{itemize} \end{itemize} \hypertarget{research}{}\subsubsection*{{Research}}\label{research} \begin{itemize}% \item \emph{Writing papers}: \href{http://en.wikipedia.org/wiki/LaTeX}{LaTeX} \item \emph{Writing papers \& enjoying the process}: \href{http://www.lyx.org}{LyX} \item \emph{Handsome figures in your papers}: \href{http://www.xfig.org/}{xfig} or, better, \href{http://tams-www.informatik.uni-hamburg.de/applets/jfig/}{jfig}. \item \emph{The occasional presentation with many graphical content}: \href{http://www.openoffice.org/product/impress.html}{OpenOffice Impress} (using the \href{http://ooolatex.sourceforge.net/}{OOOlatex plugin}); the alternative is PowerPoint with the \href{http://texpoint.necula.org/}{TexPoint} plugin. \item \emph{Managing BibTeX}: \href{https://www.jabref.org/}{jabref}: multi-platform, for all your bibtex needs. \item \emph{IEEExplore and BibTeX}: convert citations using \href{http://www.bibconverter.net/ieeexplore/}{BibConverter}. \end{itemize} \hypertarget{cool_websites}{}\subsubsection*{{Cool websites}}\label{cool_websites} \begin{itemize}% \item \emph{Best site in the wwworld}: \href{http://en.wikipedia.org/}{Wikipedia} \item \href{http://www.mutopiaproject.org/}{Mutopia} for sheet music; \href{http://www.gutenberg.org/}{the Gutenberg Project} for books; \href{http://www.liberliber.it/}{LiberLiber} for books in italian. \item \emph{Blogs}: \href{http://bloglines.com/}{Bloglines} \item \emph{Sharing photos}: \href{http://www.flickr.com/}{flickr} exposes an API you can use. \end{itemize} *** Output of to_md *** Subject: Software not painful to use Subject_short: painless software Topic: /misc/coolsw Archive: no Date: Nov 20 2006 Order: -9.5 inMenu: true ### General * *Operating System* : [Mac OS X][switch]: heaven, after the purgatory of Linux and the hell of Windows. * *Browser*: [Firefox][firefox]. On a Mac, [Camino][camino]. * *Email*: [GMail][gmail], "search, don't sort" really works. * *Text Editor*: [TextMate][textmate], you have to buy it, but it's worth every penny. There are rumours that it's been converting (recovering) Emacs users (addicts). Unfortunately, it's Mac only. An alternative is [jedit][jedit] (GPL, Java). ### Development * *Build system*: [cmake][cmake], throw the [autotools][autotools] away. * *Source code control system*: ditch CVS for [subversion][subversion]. * *Project management*: [Trac][trac] tracks everything. * *Scripting language*: [Ruby][ruby] is Japanese pragmatism (and has a [poignant][poignant] guide). Python, you say? Python is too academic and snob: $ python Python 2.4.1 (\#1, Jun 4 2005, 00:54:33) Type "help", "copyright", "credits" or "license" for more information. >>> exit 'Use Ctrl-D (i.e. EOF) to exit.' >>> quit 'Use Ctrl-D (i.e. EOF) to exit.' * *Java IDE*: [JBuilder][jbuilder] is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained [generics][java-generics] and got opensourced. * *Mark-up language*: HTML is so 2001, why don't you take at look at [Markdown][markdown]? [Look at the source of this page](data/misc_markdown.png). * *C++ libraries*: * [QT][qt] for GUIs. * [GSL][gsl] for math. * [Magick++][magick] for manipulating images. * [Cairo][cairo] for creating PDFs. * [Boost][boost] for just about everything else. ### Research * *Writing papers*: [LaTeX][latex] * *Writing papers & enjoying the process*: [LyX][lyx] * *Handsome figures in your papers*: [xfig][xfig] or, better, [jfig][jfig]. * *The occasional presentation with many graphical content*: [OpenOffice Impress][impress] (using the [OOOlatex plugin][ooolatex]); the alternative is PowerPoint with the [TexPoint][texpoint] plugin. * *Managing BibTeX*: [jabref][jabref]: multi-platform, for all your bibtex needs. * *IEEExplore and BibTeX*: convert citations using [BibConverter][bibconverter]. ### Cool websites * *Best site in the wwworld*: [Wikipedia][wikipedia] * [Mutopia][mutopia] for sheet music; [the Gutenberg Project][gutenberg] for books; [LiberLiber][liberliber] for books in italian. * *Blogs*: [Bloglines][bloglines] * *Sharing photos*: [flickr][flickr] exposes an API you can use. [firefox]: http://getfirefox.com/ [gmail]: http://gmail.com/ [bloglines]: http://bloglines.com/ [wikipedia]: http://en.wikipedia.org/ [ruby]: http://www.ruby-lang.org/ [poignant]: http://poignantguide.net/ruby/ [webgen]: http://webgen.rubyforge.org/ [markdown]: http://daringfireball.net/projects/markdown/ [latex]: http://en.wikipedia.org/wiki/LaTeX [lyx]: http://www.lyx.org [impress]: http://www.openoffice.org/product/impress.html [ooolatex]: http://ooolatex.sourceforge.net/ [texpoint]: http://texpoint.necula.org/ [jabref]: https://www.jabref.org/ [camino]: http://www.caminobrowser.org/ [switch]: http://www.apple.com/getamac/ [textmate]: http://www.apple.com/getamac/ [cmake]: http://www.cmake.org/ [xfig]: http://www.xfig.org/ [jfig]: http://tams-www.informatik.uni-hamburg.de/applets/jfig/ [subversion]: http://subversion.tigris.org [jbuilder]: http://www.borland.com/us/products/jbuilder/index.html [flickr]: http://www.flickr.com/ [myflickr]: http://www.flickr.com/photos/censi [bibconverter]: http://www.bibconverter.net/ieeexplore/ [autotools]: http://sources.redhat.com/autobook/ [jedit]: http://www.jedit.org/ [qt]: http://www.trolltech.no/ [gsl]: http://www.gnu.org/software/gsl/ [magick]: http://www.imagemagick.org/Magick++/ [cairo]: http://cairographics.org/ [boost]: http://www.boost.org/ [markdown]: http://en.wikipedia.org/wiki/Markdown [trac]: http://trac.edgewall.org/ [mutopia]: http://www.mutopiaproject.org/ [liberliber]: http://www.liberliber.it/ [gutenberg]: http://www.gutenberg.org/ [java-generics]: http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html *** Output of to_s *** GeneralOperating System : Mac OS X: heaven, after the purgatory of Linux and the hell of Windows.Browser: Firefox. On a Mac, Camino.Email: GMail, search, dont sort really works.Text Editor: TextMate, you have to buy it, but its worth every penny. There are rumours that its been converting (recovering) Emacs users (addicts). Unfortunately, its Mac only. An alternative is jedit (GPL, Java).DevelopmentBuild system: cmake, throw the autotools away.Source code control system: ditch CVS for subversion.Project management: Trac tracks everything.Scripting language: Ruby is Japanese pragmatism (and has a poignant guide). Python, you say? Python is too academic and snob:Java IDE: JBuilder is great software and has a free version (IMHO better than Eclipse). Java is not a pain anymore since it gained generics and got opensourced.Mark-up language: HTML is so 2001, why dont you take at look at Markdown? Look at the source of this page.C++ libraries: * QT for GUIs. * GSL for math. * Magick++ for manipulating images. * Cairo for creating PDFs. * Boost for just about everything else.ResearchWriting papers: LaTeXWriting papers & enjoying the process: LyXHandsome figures in your papers: xfig or, better, jfig.The occasional presentation with many graphical content: OpenOffice Impress (using the OOOlatex plugin); the alternative is PowerPoint with the TexPoint plugin.Managing BibTeX: jabref: multi-platform, for all your bibtex needs.IEEExplore and BibTeX: convert citations using BibConverter.Cool websitesBest site in the wwworld: WikipediaMutopia for sheet music; the Gutenberg Project for books; LiberLiber for books in italian.Blogs: BloglinesSharing photos: flickr exposes an API you can use. maruku-0.7.3/spec/block_docs/links2.md0000644000004100000410000000102613321142720017627 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.3/spec/block_docs/xml_instruction.md0000644000004100000410000000230113321142720021663 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.3/spec/block_docs/lists10.md0000644000004100000410000000101613321142720017723 0ustar www-datawww-dataWrite a comment here *** Parameters: *** {} # params *** Markdown input: *** List: - è`gcc` *** Output of inspect *** md_el(:document,[ md_par(["List:"]), md_el(:ul,[ md_el(:li,["è", md_code("gcc")],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***

List:

  • ègcc
*** Output of to_latex *** List: \begin{itemize}% \item è{\colorbox[rgb]{1.00,0.93,1.00}{\tt gcc}} \end{itemize} *** Output of to_md *** List: - è`gcc` *** Output of to_s *** List:è maruku-0.7.3/spec/block_docs/issue124.md0000644000004100000410000000102313321142720020001 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.3/spec/block_docs/issue85.md0000644000004100000410000000162013321142720017732 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.3/spec/block_docs/footnotes.md0000644000004100000410000000564313321142720020456 0ustar www-datawww-dataWrite a comment abouth the test here. *** Parameters: *** {:footnotes_used=>["^b", "^c", "^a"]} *** Markdown input: *** That's some text with a footnote [^b] and another [^c] and another [^a]. [^a]: And that's the footnote. That's the second paragraph of the footnote. [^b]: And that's the footnote. This is second sentence (same paragraph). [^c]: This is the very long one. That's the second paragraph. This is not a footnote. *** Output of inspect *** md_el(:document,[ md_par([ "That", md_entity("rsquo"), "s some text with a footnote ", md_foot_ref("^b"), " and another ", md_foot_ref("^c"), " and another ", md_foot_ref("^a"), "." ]), md_el(:footnote,[ md_par(["And that", md_entity("rsquo"), "s the footnote."]), md_par([ "That", md_entity("rsquo"), "s the second paragraph of the footnote." ]) ],{:footnote_id=>"^a"},[]), md_el(:footnote,[ md_par([ "And that", md_entity("rsquo"), "s the footnote. This is second sentence (same paragraph)." ]) ],{:footnote_id=>"^b"},[]), md_el(:footnote,[ md_par(["This is the very long one."]), md_par(["That", md_entity("rsquo"), "s the second paragraph."]) ],{:footnote_id=>"^c"},[]), md_par(["This is not a footnote."]) ],{},[]) *** Output of to_html ***

That’s some text with a footnote 1 and another 2 and another 3.

This is not a footnote.


  1. And that’s the footnote. This is second sentence (same paragraph).

  2. This is the very long one.

    That’s the second paragraph.

  3. And that’s the footnote.

    That’s the second paragraph of the footnote.

*** Output of to_latex *** That's some text with a footnote \footnote{And that's the footnote. This is second sentence (same paragraph).} and another \footnote{This is the very long one. That's the second paragraph.} and another \footnote{And that's the footnote. That's the second paragraph of the footnote.} . This is not a footnote. *** Output of to_md *** That s some text with a footnote and another and another . And that s the footnote. That s the second paragraph of the footnote. And that s the footnote. This is second sentence (same paragraph). This is the very long one. That s the second paragraph. This is not a footnote. *** Output of to_s *** Thats some text with a footnote and another and another .And thats the footnote.Thats the second paragraph of the footnote.And thats the footnote. This is second sentence (same paragraph).This is the very long one.Thats the second paragraph.This is not a footnote. maruku-0.7.3/spec/block_docs/paragraph.md0000644000004100000410000000047413321142720020400 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.3/spec/block_docs/xml.md0000644000004100000410000000240313321142720017225 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.3/spec/block_docs/cites.md0000644000004100000410000000355213321142720017542 0ustar www-datawww-dataComment *** Parameters: *** require 'maruku/ext/math'; {:math_enabled => true} *** Markdown input: *** This is a single citation: \cite{Foo1993}. This contains multiple citations: \cite{Foo1993,Bar, Baz22}. Here are some cites that match INSPIRE and MathSciNet: \cite{chacaltana:2010ks, MR3046557, fubar,Chacaltana:2014ica}. How about a blank \cite{}? Or \cite{,}? *** Output of inspect *** md_el(:document,[ md_par(["This is a single citation: ", md_el(:citation, [], {:cites=>["Foo1993"]}), ". This contains multiple citations: ", md_el(:citation, [], {:cites=>["Foo1993", "Bar", "Baz22"]}), "." ]), md_par(["Here are some cites that match INSPIRE and MathSciNet: ", md_el(:citation, [], {:cites=>["chacaltana:2010ks", "MR3046557", "fubar", "Chacaltana:2014ica"]}), "." ]), md_par(["How about a blank ", md_el(:citation, [], {:cites=>[]}), "? Or ", md_el(:citation, [], {:cites=>[]}), "?" ]) ],{},[]) *** Output of to_html ***

This is a single citation: [Foo1993]. This contains multiple citations: [Foo1993,Bar,Baz22].

Here are some cites that match INSPIRE and MathSciNet: [chacaltana:2010ks,MR3046557,fubar,Chacaltana:2014ica].

How about a blank []? Or []?

*** Output of to_latex *** This is a single citation: \cite{Foo1993}. This contains multiple citations: \cite{Foo1993,Bar,Baz22}. Here are some cites that match INSPIRE and MathSciNet: \cite{chacaltana:2010ks,MR3046557,fubar,Chacaltana:2014ica}. How about a blank \cite{}? Or \cite{}?maruku-0.7.3/spec/block_docs/abbrev.md0000644000004100000410000016604113321142720017677 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.3/spec/block_docs/triggering.md0000644000004100000410000000724413321142720020576 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.3/spec/block_docs/ignore_bad_header.md0000644000004100000410000000057513321142720022036 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.3/spec/block_docs/alt.md0000644000004100000410000000054713321142720017214 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.3/spec/block_docs/issue79.md0000644000004100000410000000057113321142720017741 0ustar www-datawww-dataNon-ASCII characters in a PRE tag. See https://github.com/bhollis/maruku/issues/79 *** Parameters: *** {} *** Markdown input: ***

á é í ó ú

á é í ó ú
*** Output of inspect *** md_el(:document, [md_html("

á é í ó ú

"), md_html("
\ná é í ó ú\n
")]) *** Output of to_html ***

á é í ó ú

á é í ó ú
maruku-0.7.3/spec/block_docs/ref_with_title.md0000644000004100000410000000066313321142720021443 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.3/spec/block_docs/html3.md0000644000004100000410000000261713321142720017463 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.3/spec/block_docs/fenced_code_blocks_highlighted.md0000644000004100000410000000175313321142720024547 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.3/spec/block_docs/atx_headers.md0000644000004100000410000000105213321142720020713 0ustar www-datawww-dataHeader levels go up to 6. More #'s is not a header (see Commonmark Spec). *** Parameters: *** {} *** Markdown input: *** #### A header #### ######## Not a header ######## *** Output of inspect *** md_el(:document,[ md_el(:header, "A header", {:level=>4}, []), md_par("######## Not a header ########", []) ],{},[]) *** Output of to_html ***

A header

######## Not a header ########

*** Output of to_latex *** \hypertarget{a_header}{}\paragraph*{{A header}}\label{a_header} \#\#\#\#\#\#\#\# Not a header \#\#\#\#\#\#\#\#maruku-0.7.3/spec/block_docs/ie.md0000644000004100000410000000522013321142720017022 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.3/spec/block_docs/divs/0000755000004100000410000000000013321142720017051 5ustar www-datawww-datamaruku-0.7.3/spec/block_docs/divs/div3_nest.md0000644000004100000410000000240413321142720021271 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.3/spec/block_docs/divs/div2.md0000644000004100000410000000057413321142720020245 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.3/spec/block_docs/divs/div1.md0000644000004100000410000000357613321142720020251 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.3/spec/block_docs/issue117.md0000644000004100000410000000042313321142720020006 0ustar www-datawww-dataSection tags should not get

put around them. https://github.com/bhollis/maruku/issues/117 *** Parameters: *** {} *** Markdown input: ***

## Header
*** Output of inspect *** *** Output of to_html ***

Header

maruku-0.7.3/spec/block_docs/lists.md0000644000004100000410000001723213321142720017571 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.3/spec/block_docs/paragraphs.md0000644000004100000410000000150213321142720020554 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.3/spec/block_docs/blank.md0000644000004100000410000000056613321142720017524 0ustar www-datawww-dataWrite a comment about the test here. *** Parameters: *** {} *** Markdown input: *** Linea 1 Linea 2 *** Output of inspect *** md_el(:document,[md_par(["Linea 1"]), md_par(["Linea 2"])],{},[]) *** Output of to_html ***

Linea 1

Linea 2

*** Output of to_latex *** Linea 1 Linea 2 *** Output of to_md *** Linea 1 Linea 2 *** Output of to_s *** Linea 1Linea 2 maruku-0.7.3/spec/block_docs/lists9.md0000644000004100000410000000155213321142720017660 0ustar www-datawww-dataMaruku should not unnecessarily wrap
  • 's in

    *** Parameters: *** {} # params *** Markdown input: *** - Due 1. tre 1. tre 1. tre - Due *** Output of inspect *** md_el(:document,[ md_el(:ul,[ md_el(:li,[ "Due", md_el(:ol,[ md_el(:li,["tre"],{:want_my_paragraph=>false},[]), md_el(:li,["tre"],{:want_my_paragraph=>false},[]), md_el(:li,["tre"],{:want_my_paragraph=>false},[]) ],{},[]) ],{:want_my_paragraph=>false},[]), md_el(:li,["Due"],{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***

    • Due
      1. tre
      2. tre
      3. tre
    • Due
    *** Output of to_latex *** \begin{itemize}% \item Due\begin{enumerate}% \item tre \item tre \item tre \end{enumerate} \item Due \end{itemize} *** Output of to_md *** -ue* tre * tre * tre -ue *** Output of to_s *** DuetretretreDue maruku-0.7.3/spec/block_docs/lists6.md0000644000004100000410000000327113321142720017655 0ustar www-datawww-dataMaruku improperly wraps list elements in paragraphs and doesn't handle nested lists right. *** Parameters: *** {} *** Markdown input: *** Here's another: 1. First 2. Second: * Fee * Fie * Foe 3. Third Same thing but with paragraphs: 1. First 2. Second: * Fee * Fie * Foe 3. Third *** Output of inspect *** md_el(:document,[ md_par(["Here", md_entity("rsquo"), "s another:"]), md_el(:ol,[ md_el(:li,["First"],{:want_my_paragraph=>false},[]), md_el(:li,[ "Second:", md_el(:ul,[ md_el(:li,["Fee"],{:want_my_paragraph=>false},[]), md_el(:li,["Fie"],{:want_my_paragraph=>false},[]), md_el(:li,["Foe"],{:want_my_paragraph=>false},[]) ],{},[]) ],{:want_my_paragraph=>false},[]), md_el(:li,["Third"],{:want_my_paragraph=>false},[]) ],{},[]), md_par(["Same thing but with paragraphs:"]), md_el(:ol,[ md_el(:li,[md_par("First")],{:want_my_paragraph=>true},[]), md_el(:li,[ md_par("Second:"), md_el(:ul,[ md_el(:li,["Fee"],{:want_my_paragraph=>false},[]), md_el(:li,["Fie"],{:want_my_paragraph=>false},[]), md_el(:li,["Foe"],{:want_my_paragraph=>false},[]) ],{},[]) ],{:want_my_paragraph=>true},[]), md_el(:li,md_par("Third"),{:want_my_paragraph=>false},[]) ],{},[]) ],{},[]) *** Output of to_html ***

    Here’s another:

    1. First
    2. Second:
      • Fee
      • Fie
      • Foe
    3. Third

    Same thing but with paragraphs:

    1. First

    2. Second:

      • Fee
      • Fie
      • Foe
    3. Third

    *** Output of to_latex *** *** Output of to_md *** *** Output of to_s *** maruku-0.7.3/spec/block_docs/html_inline.md0000644000004100000410000000121713321142720020731 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.3/spec/block_docs/lists14.md0000644000004100000410000000171613321142720017736 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.3/spec/block_docs/lists13.md0000644000004100000410000000163313321142720017733 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.3/spec/block_docs/hard.md0000644000004100000410000000233713321142720017351 0ustar www-datawww-dataMore complicated tests for emphasis. *** Parameters: *** {} *** Markdown input: *** *This is in italic, and **this is bold italics**.* But **is this bold and *this bold-italic* **? Or just plain ***bold italics***. *** Output of inspect *** md_el(:document, [md_par([ md_em([ "This is in italic, and ", md_strong(["this is bold italics"]), "." ]), " But ", md_strong([ "is this bold and ", md_em(["this bold-italic"]) ]), "? Or just plain ", md_emstrong(["bold italics"]), "." ]) ],{},[]) *** Output of to_html ***

    This is in italic, and this is bold italics. But is this bold and this bold-italic? Or just plain bold italics.

    *** Output of to_latex *** \emph{This is in italic, and \textbf{this is bold italics}.} But \textbf{is this bold and \emph{this bold-italic}}? Or just plain \textbf{\emph{bold italics}}. *** Output of to_md *** *This is in italic, and **this is bold italics**.* But **is this bold and *this bold-italic* **? Or just plain ***bold italics***. *** Output of to_s *** This is in italic, and this is bold italics. But is this bold and this bold-italic? Or just plain bold italics. maruku-0.7.3/spec/block_docs/loss.md0000644000004100000410000000062313321142720017407 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.3/spec/block_docs/lists_ol2.md0000644000004100000410000001006413321142720020341 0ustar www-datawww-dataMaruku handles some weirdly indented lists and paragraphs within lists. *** Parameters: *** {} *** Markdown input: *** 1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. ATTENZIONE! - Uno - Due 1. tre 1. tre 1. tre - Due 2. 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(:ol,[ md_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!"]), md_el(:ul,[ md_li(["Uno"],false), md_li(["Due", md_el(:ol,[ md_li(["tre"],false), md_li(["tre"],false), md_li(["tre"],false) ],{},[]) ],false), md_li(["Due"],false) ],{},[]) ],true), md_li([ md_par(["Suspendisse id sem consectetuer libero luctus adipiscing."]) ],false) ],{},[]), md_par(["Ancora"]), md_el(:ul,[ md_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." ]) ],true), md_li([md_par(["Another item in the same list."])],false) ],{},[]) ],{},[]) *** Output of to_html ***
    1. This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.

      ATTENZIONE!

      • Uno
      • Due
        1. tre
        2. tre
        3. tre
      • Due
    2. 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{enumerate}% \item This is a list item with two paragraphs. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. ATTENZIONE! \begin{itemize}% \item Uno \item Due\begin{enumerate}% \item tre \item tre \item tre \end{enumerate} \item Due \end{itemize} \item Suspendisse id sem consectetuer libero luctus adipiscing. \end{enumerate} 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_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!UnoDuetretretreDueSuspendisse 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.3/spec/block_docs/lists15.md0000644000004100000410000000123013321142720017726 0ustar www-datawww-dataIAL following list *** Parameters: *** {} *** Markdown input: *** * First item * {#foo} Second item * Third item {:fubar style="color:red"} Now, a paragraph. *** Output of inspect *** md_el(:document, [ md_el(:ul, [ md_li("First item", false), md_li("Second item", false, [[:id, "foo"]]), md_li("Third item", false) ], {}, []), md_par("Now, a paragraph.") ],{},[]) *** Output of to_html ***
    • First item
    • Second item
    • Third item

    Now, a paragraph.

    *** Output of to_latex *** \begin{itemize}% \item First item \item Second item \item Third item \end{itemize} Now, a paragraph.maruku-0.7.3/spec/block_docs/issue130.md0000644000004100000410000000063113321142720020002 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.3/spec/block_docs/issue40.md0000644000004100000410000000174513321142720017731 0ustar www-datawww-dataScript tags should be OK with unescaped ampersands. https://github.com/bhollis/maruku/issues/40 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.3/spec/block_docs/issue123.md0000644000004100000410000000057413321142720020012 0ustar www-datawww-dataHandle script tag without a newline. https://github.com/bhollis/maruku/issues/123 *** Parameters: *** { } *** Markdown input: *** Lets add Jade to our dependencies: *** Output of inspect *** *** Output of to_html ***

    Lets add Jade to our dependencies:

    maruku-0.7.3/spec/block_docs/code4.md0000644000004100000410000000256713321142720017436 0ustar www-datawww-dataCodes which look like lists *** Parameters: *** {} *** Markdown input: *** This is code (4 spaces): * Code * Code (again) This is also code * Code * Code (again) This is code (1 tab): * Code * Code (again) *** Output of inspect *** md_el(:document,[ md_par(["This is code (4 spaces):"]), md_el(:code,[],{:raw_code=>"* Code * Code (again)", :lang=>nil},[]), md_par(["This is also code"]), md_el(:code,[],{:raw_code=>"* Code * Code (again)", :lang=>nil},[]), md_par(["This is code (1 tab):"]), md_el(:code,[],{:raw_code=>"* Code * Code (again)", :lang=>nil},[]) ],{},[]) *** Output of to_html ***

    This is code (4 spaces):

    * Code
      * Code (again)

    This is also code

    * Code
    * Code (again)

    This is code (1 tab):

    * Code
    	* Code (again)
    *** Output of to_latex *** This is code (4 spaces): \begin{verbatim}* Code * Code (again)\end{verbatim} This is also code \begin{verbatim}* Code * Code (again)\end{verbatim} This is code (1 tab): \begin{verbatim}* Code * Code (again)\end{verbatim} *** Output of to_md *** This is code (4 spaces): * Code * Code (again) This is also code * Code * Code (again) This is code (1 tab): * Code * Code (again) *** Output of to_s *** This is code (4 spaces):This is also codeThis is code (1 tab): maruku-0.7.3/spec/block_docs/issue26.md0000644000004100000410000000072113321142720017726 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.3/spec/block_docs/link.md0000644000004100000410000000424513321142720017370 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.3/spec/spec_helper.rb0000644000004100000410000000014413321142720016617 0ustar www-datawww-datarequire 'json' require 'simplecov' SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/..')) maruku-0.7.3/data/0000755000004100000410000000000013321142720013761 5ustar www-datawww-datamaruku-0.7.3/data/entities.xml0000644000004100000410000003235513321142720016337 0ustar www-datawww-data maruku-0.7.3/lib/0000755000004100000410000000000013321142720013616 5ustar www-datawww-datamaruku-0.7.3/lib/maruku.rb0000644000004100000410000000622513321142720015454 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.3/lib/maruku/0000755000004100000410000000000013321142720015122 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/version.rb0000644000004100000410000000145113321142720017135 0ustar www-datawww-datamodule MaRuKu # The Maruku version. VERSION = '0.7.3' # @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.3/lib/maruku/string_utils.rb0000644000004100000410000000717013321142720020202 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.3/lib/maruku/document.rb0000644000004100000410000000201113321142720017257 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.refid2ref = {} self.id_counter = 0 parse_doc(s) if s end end end maruku-0.7.3/lib/maruku/textile2.rb0000644000004100000410000000005113321142720017203 0ustar www-datawww-datarequire 'maruku/input_textile2/t2_parser'maruku-0.7.3/lib/maruku/output/0000755000004100000410000000000013321142720016462 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/output/to_html.rb0000644000004100000410000005343113321142720020463 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? Integer
          # 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.3/lib/maruku/output/s5/0000755000004100000410000000000013321142720017011 5ustar  www-datawww-datamaruku-0.7.3/lib/maruku/output/s5/fancy.rb0000644000004100000410000005776713321142720020464 0ustar  www-datawww-datamodule MaRuKu
      S5_external =<
      
      
      
      
      
      
    EOF
    
    
      S5_Fancy =<
    
    
    
    
    
    
    
    
    EOF
    
    end
    
    maruku-0.7.3/lib/maruku/output/s5/to_s5.rb0000644000004100000410000000662113321142720020374 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.3/lib/maruku/output/entity_table.rb0000644000004100000410000000150413321142720021472 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 def each @entity_table.each end end end maruku-0.7.3/lib/maruku/output/to_s.rb0000644000004100000410000000026513321142720017756 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.3/lib/maruku/output/to_latex.rb0000644000004100000410000003263713321142720020641 0ustar www-datawww-datarequire 'set' require 'maruku/output/entity_table' 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.3/lib/maruku/output/to_markdown.rb0000644000004100000410000001125413321142720021336 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.3/lib/maruku/helpers.rb0000644000004100000410000001054113321142720017112 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.3/lib/maruku/errors.rb0000644000004100000410000000445013321142720016766 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" + < "" 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.3/lib/maruku/input_textile2/0000755000004100000410000000000013321142720020101 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/input_textile2/t2_parser.rb0000644000004100000410000000646213321142720022337 0ustar www-datawww-dataclass String Textile2_EmptyLine = /^\s*$/ Textile2_Signature = /^(\S+\.?)\.\s(.*)/ def t2_empty? self =~ Textile2_EmptyLine end def t2_contains_signature? self =~ Textile2_Signature end # sig, rest = t2_get_signature def t2_get_signature self =~ Textile2_Signature return Textile2Signature.new($1), $2 end end class Textile2Signature Reg = %r{ ^ # block name is 1 ([A-Za-z0-9]+)? # style is 2 ( \{ # open bracket ([^\}]+) # style spec is 3 \} # close bracket )? # language is 4 (\[(\w+)\])? # value is 5 # class and id (?: \( # open par (\w+)? # optional class specification is 6 (?:\#(\w+))? # optional id is 7 \) # close par )? # alignment is 8 (\<|\>|\<\>|\=)? # 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.3/lib/maruku/attributes.rb0000644000004100000410000000675713321142720017654 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 <] 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 if c.is_a?(String) c.replace_each_string(&block) c end @children.flatten! unless self.node_type == :table 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 class Array def replace_each_string(&block) self.map! do |c| next yield c if c.is_a?(String) c.replace_each_string(&block) c end end end maruku-0.7.3/lib/maruku/toc.rb0000644000004100000410000001154013321142720016235 0ustar www-datawww-datamodule MaRuKu # A section in the table of contents of a document. class Section # The depth of the section (0 for toplevel). # # Equivalent to `header_element.level`. # # @return [Fixnum] attr_accessor :section_level # The nested section number, e.g. `[1, 2, 5]` for Section 1.2.5. # # @return [Array] 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.3/lib/maruku/inspect_element.rb0000644000004100000410000000373713321142720020637 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.3/lib/maruku/defaults.rb0000644000004100000410000000216213321142720017257 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.3/lib/maruku/html.rb0000644000004100000410000002057513321142720016424 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.3/lib/maruku/ext/0000755000004100000410000000000013321142720015722 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/ext/math/0000755000004100000410000000000013321142720016653 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/ext/math/to_html.rb0000644000004100000410000001315613321142720020654 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 def to_html_citation span = xelem('span') span['class'] = 'maruku-citation' span << xtext('[') self.cites.each do |c| if c =~ /(\w+):(\d\d\d\d\w{2,3})/ # INSPIRE a = xelem('a') a << xtext(c) a['href'] = "http://inspirehep.net/search?p=#{$1}%3A#{$2}" span << a << xtext(',') elsif c =~ /MR(\d+)/ # MathReviews a = xelem('a') a << xtext(c) a['href'] = "http://www.ams.org/mathscinet-getitem?mr=#{$1}" span << a << xtext(',') else span << xtext(c + ',') end end span.children.last.chop! unless span.children.last == '[' span << xtext(']') span end end end end maruku-0.7.3/lib/maruku/ext/math/elements.rb0000644000004100000410000000120013321142720021005 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.3/lib/maruku/ext/math/parsing.rb0000644000004100000410000000714213321142720020647 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) # This adds support for \cite RegCite = /\\cite\{([^}]*?)\}/ MaRuKu::In::Markdown.register_span_extension( :chars => ["\\"], :regexp => RegCite, :handler => lambda do |doc, src, con| return false unless doc.is_math_enabled? cites = src.read_regexp(RegCite).captures.compact.first.split(/\s*,\s*/) con.push doc.md_el(:citation, [], :cites => cites) true end) maruku-0.7.3/lib/maruku/ext/math/to_latex.rb0000644000004100000410000000167513321142720021030 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 def to_latex_citation "\\cite{#{self.cites.join(',')}}" 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.3/lib/maruku/ext/math/mathml_engines/0000755000004100000410000000000013321142720021645 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/ext/math/mathml_engines/itex2mml.rb0000644000004100000410000000155513321142720023741 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.3/lib/maruku/ext/math/mathml_engines/ritex.rb0000644000004100000410000000106713321142720023331 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.3/lib/maruku/ext/math/mathml_engines/none.rb0000644000004100000410000000031013321142720023123 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.3/lib/maruku/ext/math/mathml_engines/blahtex.rb0000644000004100000410000000514113321142720023622 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.3/lib/maruku/ext/div.rb0000644000004100000410000000632713321142720017041 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.3/lib/maruku/ext/math.rb0000644000004100000410000000156213321142720017204 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.3/lib/maruku/ext/fenced_code.rb0000644000004100000410000000607313321142720020473 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.3/lib/maruku/input/0000755000004100000410000000000013321142720016261 5ustar www-datawww-datamaruku-0.7.3/lib/maruku/input/parse_block.rb0000644000004100000410000005035713321142720021104 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 if level > 6 text = parse_span line return md_par(text, al) end 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 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, :code].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 if md_type == :code && num_leading_spaces > len+6 lines << strip_indent(src.cur_line, num_leading_spaces-4) src.shift_line next 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 && ( [:text, :quote].include?(src.cur_line.md_type) or src.cur_line.md_type == :empty && ( src.next_line && src.next_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.3/lib/maruku/input/parse_doc.rb0000644000004100000410000001026513321142720020551 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.send(: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.3/lib/maruku/input/parse_span.rb0000644000004100000410000005150613321142720020750 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 ' ' : ' '; 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.3/lib/maruku/input/html_helper.rb0000644000004100000410000001557613321142720021127 0ustar www-datawww-datamodule MaRuKu::In::Markdown::SpanLevelParser # This class helps me read and sanitize HTML blocks class HTMLHelper Tag = %r{^<(/)?(\w+)\s*([^>]*?)>}m PartialTag = %r{^<.*}m CData = %r{^\s*}m EverythingElse = %r{^[^<]+}m CommentStart = %r{^} 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.3/lib/maruku/input/charsource.rb0000644000004100000410000001465413321142720020756 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.3/maruku.gemspec0000644000004100000410000002271213321142720015725 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: maruku 0.7.3 ruby lib Gem::Specification.new do |s| s.name = "maruku".freeze s.version = "0.7.3" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Andrea Censi".freeze, "Nathan Weizenbaum".freeze, "Ben Hollis".freeze] s.date = "2017-01-15" s.description = "Maruku is a Markdown interpreter in Ruby.\n It features native export to HTML and PDF (via Latex). The\n output is really beautiful!".freeze s.email = "ben@benhollis.net".freeze s.executables = ["maruku".freeze, "marutex".freeze] s.files = ["MIT-LICENSE.txt".freeze, "bin/maruku".freeze, "bin/marutex".freeze, "data/entities.xml".freeze, "docs/div_syntax.md".freeze, "docs/entity_test.md".freeze, "docs/markdown_syntax.md".freeze, "docs/maruku.md".freeze, "docs/math.md".freeze, "docs/other_stuff.md".freeze, "docs/proposal.md".freeze, "lib/maruku.rb".freeze, "lib/maruku/attributes.rb".freeze, "lib/maruku/defaults.rb".freeze, "lib/maruku/document.rb".freeze, "lib/maruku/element.rb".freeze, "lib/maruku/errors.rb".freeze, "lib/maruku/ext/div.rb".freeze, "lib/maruku/ext/fenced_code.rb".freeze, "lib/maruku/ext/math.rb".freeze, "lib/maruku/ext/math/elements.rb".freeze, "lib/maruku/ext/math/mathml_engines/blahtex.rb".freeze, "lib/maruku/ext/math/mathml_engines/itex2mml.rb".freeze, "lib/maruku/ext/math/mathml_engines/none.rb".freeze, "lib/maruku/ext/math/mathml_engines/ritex.rb".freeze, "lib/maruku/ext/math/parsing.rb".freeze, "lib/maruku/ext/math/to_html.rb".freeze, "lib/maruku/ext/math/to_latex.rb".freeze, "lib/maruku/helpers.rb".freeze, "lib/maruku/html.rb".freeze, "lib/maruku/input/charsource.rb".freeze, "lib/maruku/input/extensions.rb".freeze, "lib/maruku/input/html_helper.rb".freeze, "lib/maruku/input/linesource.rb".freeze, "lib/maruku/input/mdline.rb".freeze, "lib/maruku/input/parse_block.rb".freeze, "lib/maruku/input/parse_doc.rb".freeze, "lib/maruku/input/parse_span.rb".freeze, "lib/maruku/input_textile2/t2_parser.rb".freeze, "lib/maruku/inspect_element.rb".freeze, "lib/maruku/maruku.rb".freeze, "lib/maruku/output/entity_table.rb".freeze, "lib/maruku/output/s5/fancy.rb".freeze, "lib/maruku/output/s5/to_s5.rb".freeze, "lib/maruku/output/to_html.rb".freeze, "lib/maruku/output/to_latex.rb".freeze, "lib/maruku/output/to_markdown.rb".freeze, "lib/maruku/output/to_s.rb".freeze, "lib/maruku/string_utils.rb".freeze, "lib/maruku/textile2.rb".freeze, "lib/maruku/toc.rb".freeze, "lib/maruku/version.rb".freeze, "spec/block_docs/abbrev.md".freeze, "spec/block_docs/abbreviations.md".freeze, "spec/block_docs/abbreviations2.md".freeze, "spec/block_docs/alt.md".freeze, "spec/block_docs/amps.md".freeze, "spec/block_docs/attribute_sanitize.md".freeze, "spec/block_docs/attributes/att2.md".freeze, "spec/block_docs/attributes/att3.md".freeze, "spec/block_docs/attributes/attributes.md".freeze, "spec/block_docs/attributes/circular.md".freeze, "spec/block_docs/attributes/default.md".freeze, "spec/block_docs/atx_headers.md".freeze, "spec/block_docs/auto_cdata.md".freeze, "spec/block_docs/bad_cites.md".freeze, "spec/block_docs/bad_divrefs.md".freeze, "spec/block_docs/blank.md".freeze, "spec/block_docs/blanks_in_code.md".freeze, "spec/block_docs/block_quotes.md".freeze, "spec/block_docs/bug_def.md".freeze, "spec/block_docs/bug_table.md".freeze, "spec/block_docs/cites.md".freeze, "spec/block_docs/code.md".freeze, "spec/block_docs/code2.md".freeze, "spec/block_docs/code3.md".freeze, "spec/block_docs/code4.md".freeze, "spec/block_docs/data_loss.md".freeze, "spec/block_docs/div_without_newline.md".freeze, "spec/block_docs/divs/div1.md".freeze, "spec/block_docs/divs/div2.md".freeze, "spec/block_docs/divs/div3_nest.md".freeze, "spec/block_docs/easy.md".freeze, "spec/block_docs/email.md".freeze, "spec/block_docs/empty_cells.md".freeze, "spec/block_docs/encoding/iso-8859-1.md".freeze, "spec/block_docs/encoding/utf-8.md".freeze, "spec/block_docs/entities.md".freeze, "spec/block_docs/escape.md".freeze, "spec/block_docs/escaping.md".freeze, "spec/block_docs/extra_dl.md".freeze, "spec/block_docs/extra_header_id.md".freeze, "spec/block_docs/extra_table1.md".freeze, "spec/block_docs/fenced_code_blocks.md".freeze, "spec/block_docs/fenced_code_blocks_highlighted.md".freeze, "spec/block_docs/footnotes.md".freeze, "spec/block_docs/footnotes2.md".freeze, "spec/block_docs/hard.md".freeze, "spec/block_docs/header_after_par.md".freeze, "spec/block_docs/headers.md".freeze, "spec/block_docs/hex_entities.md".freeze, "spec/block_docs/hrule.md".freeze, "spec/block_docs/html3.md".freeze, "spec/block_docs/html4.md".freeze, "spec/block_docs/html5.md".freeze, "spec/block_docs/html_block_in_para.md".freeze, "spec/block_docs/html_inline.md".freeze, "spec/block_docs/html_trailing.md".freeze, "spec/block_docs/ie.md".freeze, "spec/block_docs/iframe.md".freeze, "spec/block_docs/ignore_bad_header.md".freeze, "spec/block_docs/images.md".freeze, "spec/block_docs/images2.md".freeze, "spec/block_docs/inline_html.md".freeze, "spec/block_docs/inline_html2.md".freeze, "spec/block_docs/inline_html_beginning.md".freeze, "spec/block_docs/issue106.md".freeze, "spec/block_docs/issue115.md".freeze, "spec/block_docs/issue117.md".freeze, "spec/block_docs/issue120.md".freeze, "spec/block_docs/issue123.md".freeze, "spec/block_docs/issue124.md".freeze, "spec/block_docs/issue126.md".freeze, "spec/block_docs/issue130.md".freeze, "spec/block_docs/issue20.md".freeze, "spec/block_docs/issue26.md".freeze, "spec/block_docs/issue29.md".freeze, "spec/block_docs/issue30.md".freeze, "spec/block_docs/issue31.md".freeze, "spec/block_docs/issue40.md".freeze, "spec/block_docs/issue64.md".freeze, "spec/block_docs/issue67.md".freeze, "spec/block_docs/issue70.md".freeze, "spec/block_docs/issue72.md".freeze, "spec/block_docs/issue74.md".freeze, "spec/block_docs/issue79.md".freeze, "spec/block_docs/issue83.md".freeze, "spec/block_docs/issue85.md".freeze, "spec/block_docs/issue88.md".freeze, "spec/block_docs/issue89.md".freeze, "spec/block_docs/issue90.md".freeze, "spec/block_docs/link.md".freeze, "spec/block_docs/links.md".freeze, "spec/block_docs/links2.md".freeze, "spec/block_docs/list1.md".freeze, "spec/block_docs/list12.md".freeze, "spec/block_docs/list2.md".freeze, "spec/block_docs/list_multipara.md".freeze, "spec/block_docs/lists.md".freeze, "spec/block_docs/lists10.md".freeze, "spec/block_docs/lists11.md".freeze, "spec/block_docs/lists12.md".freeze, "spec/block_docs/lists13.md".freeze, "spec/block_docs/lists14.md".freeze, "spec/block_docs/lists15.md".freeze, "spec/block_docs/lists6.md".freeze, "spec/block_docs/lists7b.md".freeze, "spec/block_docs/lists9.md".freeze, "spec/block_docs/lists_after_paragraph.md".freeze, "spec/block_docs/lists_blank.md".freeze, "spec/block_docs/lists_blockquote_code.md".freeze, "spec/block_docs/lists_need_blank_line.md".freeze, "spec/block_docs/lists_nested.md".freeze, "spec/block_docs/lists_nested_blankline.md".freeze, "spec/block_docs/lists_nested_deep.md".freeze, "spec/block_docs/lists_ol.md".freeze, "spec/block_docs/lists_ol2.md".freeze, "spec/block_docs/lists_paraindent.md".freeze, "spec/block_docs/lists_tab.md".freeze, "spec/block_docs/loss.md".freeze, "spec/block_docs/math-blahtex/equations.md".freeze, "spec/block_docs/math-blahtex/inline.md".freeze, "spec/block_docs/math-blahtex/math2.md".freeze, "spec/block_docs/math-blahtex/table.md".freeze, "spec/block_docs/math/embedded_invalid_svg.md".freeze, "spec/block_docs/math/embedded_svg.md".freeze, "spec/block_docs/math/equations.md".freeze, "spec/block_docs/math/inline.md".freeze, "spec/block_docs/math/math2.md".freeze, "spec/block_docs/math/notmath.md".freeze, "spec/block_docs/math/raw_mathml.md".freeze, "spec/block_docs/math/spaces_after_inline_math.md".freeze, "spec/block_docs/math/table.md".freeze, "spec/block_docs/math/table2.md".freeze, "spec/block_docs/misc_sw.md".freeze, "spec/block_docs/olist.md".freeze, "spec/block_docs/one.md".freeze, "spec/block_docs/paragraph.md".freeze, "spec/block_docs/paragraph_rules/dont_merge_ref.md".freeze, "spec/block_docs/paragraph_rules/tab_is_blank.md".freeze, "spec/block_docs/paragraphs.md".freeze, "spec/block_docs/recover/recover_links.md".freeze, "spec/block_docs/ref_with_period.md".freeze, "spec/block_docs/ref_with_title.md".freeze, "spec/block_docs/references/long_example.md".freeze, "spec/block_docs/references/spaces_and_numbers.md".freeze, "spec/block_docs/smartypants.md".freeze, "spec/block_docs/syntax_hl.md".freeze, "spec/block_docs/table_attributes.md".freeze, "spec/block_docs/table_colspan.md".freeze, "spec/block_docs/tables.md".freeze, "spec/block_docs/tables2.md".freeze, "spec/block_docs/test.md".freeze, "spec/block_docs/ticks.md".freeze, "spec/block_docs/toc.md".freeze, "spec/block_docs/triggering.md".freeze, "spec/block_docs/underscore_in_words.md".freeze, "spec/block_docs/wrapping.md".freeze, "spec/block_docs/xml.md".freeze, "spec/block_docs/xml3.md".freeze, "spec/block_docs/xml_comments.md".freeze, "spec/block_docs/xml_instruction.md".freeze, "spec/block_spec.rb".freeze, "spec/cli_spec.rb".freeze, "spec/span_spec.rb".freeze, "spec/spec_helper.rb".freeze, "spec/to_html_utf8_spec.rb".freeze] s.homepage = "http://github.com/bhollis/maruku".freeze s.licenses = ["MIT".freeze] s.required_ruby_version = Gem::Requirement.new(">= 1.8.7".freeze) s.rubygems_version = "2.5.2.1".freeze s.summary = "Maruku is a Markdown-superset interpreter written in Ruby.".freeze end maruku-0.7.3/MIT-LICENSE.txt0000644000004100000410000000204013321142720015316 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.