From ff63e894b2befc07c643fa7b07e94c0d838a6aa5 Mon Sep 17 00:00:00 2001 From: Jacques Distler Date: Wed, 14 Feb 2007 20:32:24 -0600 Subject: [PATCH] Sync with latest Maruku. Finally able to ditch BlueCloth completely. --- app/views/markdown_help.rhtml | 6 +- lib/bluecloth_tweaked.rb | 1127 ----------------- lib/chunks/engines.rb | 6 +- .../plugins/maruku/lib/maruku/attributes.rb | 5 +- vendor/plugins/maruku/lib/maruku/ext/math.rb | 30 + .../maruku/lib/maruku/ext/math/elements.rb | 5 +- .../maruku/lib/maruku/ext/math/parsing.rb | 139 +- .../maruku/lib/maruku/ext/math/to_html.rb | 2 +- vendor/plugins/maruku/lib/maruku/helpers.rb | 2 + .../maruku/lib/maruku/input/charsource.rb | 2 +- .../maruku/lib/maruku/input/extensions.rb | 12 +- .../maruku/lib/maruku/input/parse_block.rb | 15 +- .../lib/maruku/input/parse_span_better.rb | 8 +- .../lib/maruku/input_textile2/t2_parser.rb | 163 +++ vendor/plugins/maruku/lib/maruku/maruku.rb | 2 +- .../maruku/lib/maruku/output/to_html.rb | 97 +- .../maruku/lib/maruku/tests/new_parser.rb | 19 +- vendor/plugins/maruku/lib/maruku/version.rb | 2 +- 18 files changed, 393 insertions(+), 1249 deletions(-) delete mode 100644 lib/bluecloth_tweaked.rb create mode 100644 vendor/plugins/maruku/lib/maruku/input_textile2/t2_parser.rb diff --git a/app/views/markdown_help.rhtml b/app/views/markdown_help.rhtml index 067be08d..15b98630 100644 --- a/app/views/markdown_help.rhtml +++ b/app/views/markdown_help.rhtml @@ -1,12 +1,14 @@ -

Markdown formatting tips (advanced)

+

Markdown formatting tips (basics, extended syntax, metadata)

+ + + -
_your text_your text
**your text**your text
`my code`my code
* Bulleted list
* Second item
• Bulleted list
• Second item
1. Numbered list
1. Second item
1. Numbered list
2. Second item
Definition list
: is useful
Definition list
is useful
[link name](URL)link name
![Alt text](URL)Image
## Header ##
### Subheader ###
#### Etc. ####
Header
Subheader
Etc.
***Horizontal ruler
<http://url>
<email@add.com>
Auto-linked
![Alt text](URL)Image
diff --git a/lib/bluecloth_tweaked.rb b/lib/bluecloth_tweaked.rb deleted file mode 100644 index 92883441..00000000 --- a/lib/bluecloth_tweaked.rb +++ /dev/null @@ -1,1127 +0,0 @@ -#!/usr/bin/env ruby -# -# Bluecloth is a Ruby implementation of Markdown, a text-to-HTML conversion -# tool. -# -# == Synopsis -# -# doc = BlueCloth::new " -# ## Test document ## -# -# Just a simple test. -# " -# -# puts doc.to_html -# -# == Authors -# -# * Michael Granger -# -# == Contributors -# -# * Martin Chase - Peer review, helpful suggestions -# * Florian Gross - Filter options, suggestions -# -# == Copyright -# -# Original version: -# Copyright (c) 2003-2004 John Gruber -# -# All rights reserved. -# -# Ruby port: -# Copyright (c) 2004 The FaerieMUD Consortium. -# -# BlueCloth is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. -# -# BlueCloth is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# == To-do -# -# * Refactor some of the larger uglier methods that have to do their own -# brute-force scanning because of lack of Perl features in Ruby's Regexp -# class. Alternately, could add a dependency on 'pcre' and use most Perl -# regexps. -# -# * Put the StringScanner in the render state for thread-safety. -# -# == Version -# -# $Id: bluecloth.rb,v 1.3 2004/05/02 15:56:33 webster132 Exp $ -# - -require 'digest/md5' -require 'logger' -require 'strscan' - - -### BlueCloth is a Ruby implementation of Markdown, a text-to-HTML conversion -### tool. -class BlueCloth < String - - ### Exception class for formatting errors. - class FormatError < RuntimeError - - ### Create a new FormatError with the given source +str+ and an optional - ### message about the +specific+ error. - def initialize( str, specific=nil ) - if specific - msg = "Bad markdown format near %p: %s" % [ str, specific ] - else - msg = "Bad markdown format near %p" % str - end - - super( msg ) - end - end - - - # Release Version - Version = '0.0.3' - - # SVN Revision - SvnRev = %q$Rev: 37 $ - - # SVN Id tag - SvnId = %q$Id: bluecloth.rb,v 1.3 2004/05/02 15:56:33 webster132 Exp $ - - # SVN URL - SvnUrl = %q$URL: svn+ssh://cvs.faeriemud.org/var/svn/BlueCloth/trunk/lib/bluecloth.rb $ - - - # Rendering state struct. Keeps track of URLs, titles, and HTML blocks - # midway through a render. I prefer this to the globals of the Perl version - # because globals make me break out in hives. Or something. - RenderState = Struct::new( "RenderState", :urls, :titles, :html_blocks, :log ) - - # Tab width for #detab! if none is specified - TabWidth = 4 - - # The tag-closing string -- set to '>' for HTML - EmptyElementSuffix = "/>"; - - # Table of MD5 sums for escaped characters - EscapeTable = {} - '\\`*_{}[]()#.!'.split(//).each {|char| - hash = Digest::MD5::hexdigest( char ) - - EscapeTable[ char ] = { - :md5 => hash, - :md5re => Regexp::new( hash ), - :re => Regexp::new( '\\\\' + Regexp::escape(char) ), - } - } - - - ################################################################# - ### I N S T A N C E M E T H O D S - ################################################################# - - ### Create a new BlueCloth string. - def initialize( content="", *restrictions ) - @log = Logger::new( $deferr ) - @log.level = $DEBUG ? - Logger::DEBUG : - ($VERBOSE ? Logger::INFO : Logger::WARN) - @scanner = nil - - # Add any restrictions, and set the line-folding attribute to reflect - # what happens by default. - restrictions.flatten.each {|r| __send__("#{r}=", true) } - @fold_lines = true - - super( content ) - - @log.debug "String is: %p" % self - end - - - ###### - public - ###### - - # Filters for controlling what gets output for untrusted input. (But really, - # you're filtering bad stuff out of untrusted input at submission-time via - # untainting, aren't you?) - attr_accessor :filter_html, :filter_styles - - # RedCloth-compatibility accessor. Line-folding is part of Markdown syntax, - # so this isn't used by anything. - attr_accessor :fold_lines - - - ### Render Markdown-formatted text in this string object as HTML and return - ### it. The parameter is for compatibility with RedCloth, and is currently - ### unused, though that may change in the future. - def to_html( lite=false ) - - # Create a StringScanner we can reuse for various lexing tasks - @scanner = StringScanner::new( '' ) - - # Make a structure to carry around stuff that gets placeholdered out of - # the source. - rs = RenderState::new( {}, {}, {} ) - - # Make a copy of the string with normalized line endings, tabs turned to - # spaces, and a couple of guaranteed newlines at the end - text = self.gsub( /\r\n?/, "\n" ).detab - text += "\n\n" - @log.debug "Normalized line-endings: %p" % text - - # Filter HTML if we're asked to do so - if self.filter_html - text.gsub!( "<", "<" ) - text.gsub!( ">", ">" ) - @log.debug "Filtered HTML: %p" % text - end - - # Simplify blank lines - text.gsub!( /^ +$/, '' ) - @log.debug "Tabs -> spaces/blank lines stripped: %p" % text - - # Replace HTML blocks with placeholders - text = hide_html_blocks( text, rs ) - @log.debug "Hid HTML blocks: %p" % text - @log.debug "Render state: %p" % rs - - # Strip link definitions, store in render state - text = strip_link_definitions( text, rs ) - @log.debug "Stripped link definitions: %p" % text - @log.debug "Render state: %p" % rs - - # Escape meta-characters - text = escape_special_chars( text ) - @log.debug "Escaped special characters: %p" % text - - # Transform block-level constructs - text = apply_block_transforms( text, rs ) - @log.debug "After block-level transforms: %p" % text - - # Now swap back in all the escaped characters - text = unescape_special_chars( text ) - @log.debug "After unescaping special characters: %p" % text - - return text - end - - - ### Convert tabs in +str+ to spaces. - def detab( tabwidth=TabWidth ) - copy = self.dup - copy.detab!( tabwidth ) - return copy - end - - - ### Convert tabs to spaces in place and return self if any were converted. - def detab!( tabwidth=TabWidth ) - newstr = self.split( /\n/ ).collect {|line| - line.gsub( /(.*?)\t/ ) do - $1 + ' ' * (tabwidth - $1.length % tabwidth) - end - }.join("\n") - self.replace( newstr ) - end - - - ####### - #private - ####### - - ### Do block-level transforms on a copy of +str+ using the specified render - ### state +rs+ and return the results. - def apply_block_transforms( str, rs ) - # Port: This was called '_runBlockGamut' in the original - - @log.debug "Applying block transforms to:\n %p" % str - text = transform_headers( str, rs ) - text = transform_hrules( text, rs ) - text = transform_lists( text, rs ) - text = transform_code_blocks( text, rs ) - text = transform_block_quotes( text, rs ) - text = transform_auto_links( text, rs ) - text = hide_html_blocks( text, rs ) - - text = form_paragraphs( text, rs ) - - @log.debug "Done with block transforms:\n %p" % text - return text - end - - - ### Apply Markdown span transforms to a copy of the specified +str+ with the - ### given render state +rs+ and return it. - def apply_span_transforms( str, rs ) - @log.debug "Applying span transforms to:\n %p" % str - - str = transform_code_spans( str, rs ) - str = encode_html( str ) - str = transform_images( str, rs ) - str = transform_anchors( str, rs ) - str = transform_italic_and_bold( str, rs ) - - # Hard breaks - str.gsub!( / {2,}\n/, " - #
- # tags for inner block must be indented. - #
- # - StrictBlockRegex = %r{ - ^ # Start of line - <(#{BlockTagPattern}) # Start tag: \2 - \b # word break - (.*\n)*? # Any number of lines, minimal match - # Matching end tag - [ ]* # trailing spaces - (?=\n+|\Z) # End of line or document - }ix - - # More-liberal block-matching - LooseBlockRegex = %r{ - ^ # Start of line - <(#{BlockTagPattern}) # start tag: \2 - \b # word break - (.*\n)*? # Any number of lines, minimal match - .* # Anything + Matching end tag - [ ]* # trailing spaces - (?=\n+|\Z) # End of line or document - }ix - - # Special case for
. - HruleBlockRegex = %r{ - ( # $1 - \A\n? # Start of doc + optional \n - | # or - .*\n\n # anything + blank line - ) - ( # save in $2 - [ ]* # Any spaces -
])*? # Attributes - /?> # Tag close - (?=\n\n|\Z) # followed by a blank line or end of document - ) - }ix - - ### Replace all blocks of HTML in +str+ that start in the left margin with - ### tokens. - def hide_html_blocks( str, rs ) - @log.debug "Hiding HTML blocks in %p" % str - - # Tokenizer proc to pass to gsub - tokenize = lambda {|match| - key = Digest::MD5::hexdigest( match ) - rs.html_blocks[ key ] = match - @log.debug "Replacing %p with %p" % - [ match, key ] - "\n\n#{key}\n\n" - } - - rval = str.dup - - @log.debug "Finding blocks with the strict regex..." - rval.gsub!( StrictBlockRegex, &tokenize ) - - @log.debug "Finding blocks with the loose regex..." - rval.gsub!( LooseBlockRegex, &tokenize ) - - @log.debug "Finding hrules..." - rval.gsub!( HruleBlockRegex ) {|match| $1 + tokenize[$2] } - - return rval - end - - - # Link defs are in the form: ^[id]: url "optional title" - LinkRegex = %r{ - ^[ ]*\[(.+)\]: # id = $1 - [ ]* - \n? # maybe *one* newline - [ ]* - (\S+) # url = $2 - [ ]* - \n? # maybe one newline - [ ]* - (?: - # Titles are delimited by "quotes" or (parens). - ["(] - (.+?) # title = $3 - [")] # Matching ) or " - [ ]* - )? # title is optional - (?:\n+|\Z) - }x - - ### Strip link definitions from +str+, storing them in the given RenderState - ### +rs+. - def strip_link_definitions( str, rs ) - str.gsub( LinkRegex ) {|match| - id, url, title = $1, $2, $3 - - rs.urls[ id.downcase ] = encode_html( url ) - unless title.nil? - rs.titles[ id.downcase ] = title.gsub( /"/, """ ) - end - "" - } - end - - - ### Escape special characters in the given +str+ - def escape_special_chars( str ) - @log.debug " Escaping special characters" - text = '' - - tokenize_html( str ) {|token, str| - @log.debug " Adding %p token %p" % [ token, str ] - case token - - # Within tags, encode * and _ - when :tag - text += str. - gsub( /\*/, EscapeTable['*'][:md5] ). - gsub( /_/, EscapeTable['_'][:md5] ) - - # Encode backslashed stuff in regular text - when :text - text += encode_backslash_escapes( str ) - else - raise TypeError, "Unknown token type %p" % token - end - } - - @log.debug " Text with escapes is now: %p" % text - return text - end - - - ### Swap escaped special characters in a copy of the given +str+ and return - ### it. - def unescape_special_chars( str ) - EscapeTable.each {|char, hash| - @log.debug "Unescaping escaped %p with %p" % - [ char, hash[:md5re] ] - str.gsub!( hash[:md5re], char ) - } - - return str - end - - - ### Return a copy of the given +str+ with any backslashed special character - ### in it replaced with MD5 placeholders. - def encode_backslash_escapes( str ) - # Make a copy with any double-escaped backslashes encoded - text = str.gsub( /\\\\/, EscapeTable['\\'][:md5] ) - - EscapeTable.each_pair {|char, esc| - next if char == '\\' - text.gsub!( esc[:re], esc[:md5] ) - } - - return text - end - - - ### Transform any Markdown-style horizontal rules in a copy of the specified - ### +str+ and return it. - def transform_hrules( str, rs ) - @log.debug " Transforming horizontal rules" - str.gsub( /^( ?[\-\*] ?){3,}$/, "\n\n%s\n} % [ - list_type, - transform_list_items( list, rs ), - list_type, - ] - } - end - - - # Pattern for transforming list items - ListItemRegexp = %r{ - (\n)? # leading line = $1 - (^[ ]*) # leading whitespace = $2 - (\*|\d+\.) [ ]+ # list marker = $3 - ((?m:.+?) # list item text = $4 - (\n{1,2})) - (?= \n* (\z | \2 (\*|\d+\.) [ ]+)) - }x - - ### Transform list items in a copy of the given +str+ and return it. - def transform_list_items( str, rs ) - @log.debug " Transforming list items" - - # Trim trailing blank lines - str = str.sub( /\n{2,}\z/, "\n" ) - - str.gsub( ListItemRegexp ) {|line| - @log.debug " Found item line %p" % line - leading_line, item = $1, $4 - - if leading_line or /\n{2,}/.match( item ) - @log.debug " Found leading line or item has a blank" - item = apply_block_transforms( outdent(item), rs ) - else - # Recursion for sub-lists - @log.debug " Recursing for sublist" - item = transform_lists( outdent(item), rs ).chomp - item = apply_span_transforms( item, rs ) - end - - %{
  • %s
  • \n} % item - } - end - - - # Pattern for matching codeblocks - CodeBlockRegexp = %r{ - (.?) # $1 = preceding character - :\n+ # colon + NL delimiter - ( # $2 = the code block - (?: - (?:[ ]{#{TabWidth}} | \t) # a tab or tab-width of spaces - .*\n+ - )+ - ) - ((?=^[ ]{0,#{TabWidth}}\S)|\Z) # Lookahead for non-space at - # line-start, or end of doc - }x - - ### Transform Markdown-style codeblocks in a copy of the specified +str+ and - ### return it. - def transform_code_blocks( str, rs ) - @log.debug " Transforming code blocks" - - str.gsub( CodeBlockRegexp ) {|block| - prevchar, codeblock = $1, $2 - - @log.debug " prevchar = %p" % prevchar - - # Generated the codeblock - %{%s\n\n
    %s\n
    \n\n} % [ - (prevchar.empty? || /\s/ =~ prevchar) ? "" : "#{prevchar}:", - encode_code( outdent(codeblock), rs ).rstrip, - ] - } - end - - - # Pattern for matching Markdown blockquote blocks - BlockQuoteRegexp = %r{ - (?: - ^[ ]*>[ ]? # '>' at the start of a line - .+\n # rest of the first line - (?:.+\n)* # subsequent consecutive lines - \n* # blanks - )+ - }x - - ### Transform Markdown-style blockquotes in a copy of the specified +str+ - ### and return it. - def transform_block_quotes( str, rs ) - @log.debug " Transforming block quotes" - - str.gsub( BlockQuoteRegexp ) {|quote| - @log.debug "Making blockquote from %p" % quote - quote.gsub!( /^[ ]*>[ ]?/, '' ) - %{
    \n%s\n
    \n\n} % - apply_block_transforms( quote, rs ). - gsub( /^/, " " * TabWidth ) - } - end - - - AutoAnchorURLRegexp = /<((https?|ftp):[^'">\s]+)>/ - AutoAnchorEmailRegexp = %r{ - < - ( - [-.\w]+ - \@ - [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ - ) - > - }x - - ### Transform URLs in a copy of the specified +str+ into links and return - ### it. - def transform_auto_links( str, rs ) - @log.debug " Transforming auto-links" - str.gsub( AutoAnchorURLRegexp, %{\\1}). - gsub( AutoAnchorEmailRegexp ) {|addr| - encode_email_address( unescape_special_chars($1) ) - } - end - - - # Encoder functions to turn characters of an email address into encoded - # entities. - Encoders = [ - lambda {|char| "&#%03d;" % char}, - lambda {|char| "&#x%X;" % char}, - lambda {|char| char.chr }, - ] - - ### Transform a copy of the given email +addr+ into an escaped version safer - ### for posting publicly. - def encode_email_address( addr ) - - rval = '' - ("mailto:" + addr).each_byte {|b| - case b - when ?: - rval += ":" - when ?@ - rval += Encoders[ rand(2) ][ b ] - else - r = rand(100) - rval += ( - r > 90 ? Encoders[2][ b ] : - r < 45 ? Encoders[1][ b ] : - Encoders[0][ b ] - ) - end - } - - return %{%s} % [ rval, rval.sub(/.+?:/, '') ] - end - - - # Regex for matching Setext-style headers - SetextHeaderRegexp = %r{ - (.+) # The title text ($1) - \n - ([\-=])+ # Match a line of = or -. Save only one in $2. - [ ]*\n+ - }x - - # Regexp for matching ATX-style headers - AtxHeaderRegexp = %r{ - ^(\#{1,6}) # $1 = string of #'s - [ ]* - (.+?) # $2 = Header text - [ ]* - \#* # optional closing #'s (not counted) - \n+ - }x - - ### Apply Markdown header transforms to a copy of the given +str+ amd render - ### state +rs+ and return the result. - def transform_headers( str, rs ) - @log.debug " Transforming headers" - - # Setext-style headers: - # Header 1 - # ======== - # - # Header 2 - # -------- - # - str. - gsub( SetextHeaderRegexp ) {|m| - @log.debug "Found setext-style header" - title, hdrchar = $1, $2 - title = apply_span_transforms( title, rs ) - - case hdrchar - when '=' - %[

    #{title}

    \n\n] - when '-' - %[

    #{title}

    \n\n] - else - title - end - }. - - gsub( AtxHeaderRegexp ) {|m| - @log.debug "Found ATX-style header" - hdrchars, title = $1, $2 - title = apply_span_transforms( title, rs ) - - level = hdrchars.length - %{%s\n\n} % [ level, title, level ] - } - end - - - ### Wrap all remaining paragraph-looking text in a copy of +str+ inside

    - ### tags and return it. - def form_paragraphs( str, rs ) - @log.debug " Forming paragraphs" - grafs = str. - sub( /\A\n+/, '' ). - sub( /\n+\z/, '' ). - split( /\n{2,}/ ) - - rval = grafs.collect {|graf| - - # Unhashify HTML blocks if this is a placeholder - if rs.html_blocks.key?( graf ) - rs.html_blocks[ graf ] - - # Otherwise, wrap in

    tags - else - apply_span_transforms(graf, rs). - sub( /^[ ]*/, '

    ' ) + '

    ' - end - }.join( "\n\n" ) - - @log.debug " Formed paragraphs: %p" % rval - return rval - end - - - # Pattern to match the linkid part of an anchor tag for reference-style - # links. - RefLinkIdRegex = %r{ - [ ]? # Optional leading space - (?:\n[ ]*)? # Optional newline + spaces - \[ - (.*?) # Id = $1 - \] - }x - - InlineLinkRegex = %r{ - \( # Literal paren - [ ]* # Zero or more spaces - (.*?) # URI = $1 - [ ]* # Zero or more spaces - (?: # - ([\"\']) # Opening quote char = $2 - (.*?) # Title = $3 - \2 # Matching quote char - )? # Title is optional - \) - }x - - ### Apply Markdown anchor transforms to a copy of the specified +str+ with - ### the given render state +rs+ and return it. - def transform_anchors( str, rs ) - @log.debug " Transforming anchors" - @scanner.string = str.dup - text = '' - - # Scan the whole string - until @scanner.empty? - - if @scanner.scan( /\[/ ) - link = ''; linkid = '' - depth = 1 - startpos = @scanner.pos - @log.debug " Found a bracket-open at %d" % startpos - - # Scan the rest of the tag, allowing unlimited nested []s. If - # the scanner runs out of text before the opening bracket is - # closed, append the text and return (wasn't a valid anchor). - while depth.nonzero? - linktext = @scanner.scan_until( /\]|\[/ ) - - if linktext - @log.debug " Found a bracket at depth %d: %p" % - [ depth, linktext ] - link += linktext - - # Decrement depth for each closing bracket - depth += ( linktext[-1, 1] == ']' ? -1 : 1 ) - @log.debug " Depth is now #{depth}" - - # If there's no more brackets, it must not be an anchor, so - # just abort. - else - @log.debug " Missing closing brace, assuming non-link." - link += @scanner.rest - @scanner.terminate - return text + '[' + link - end - end - link.slice!( -1 ) # Trim final ']' - @log.debug " Found leading link %p" % link - - # Look for a reference-style second part - if @scanner.scan( RefLinkIdRegex ) - linkid = @scanner[1] - linkid = link.dup if linkid.empty? - linkid.downcase! - @log.debug " Found a linkid: %p" % linkid - - # If there's a matching link in the link table, build an - # anchor tag for it. - if rs.urls.key?( linkid ) - @log.debug " Found link key in the link table: %p" % - rs.urls[linkid] - url = escape_md( rs.urls[linkid] ) - - text += %{#{link}} - - # If the link referred to doesn't exist, just append the raw - # source to the result - else - @log.debug " Linkid %p not found in link table" % linkid - @log.debug " Appending original string instead: %p" % - @scanner.string[ startpos-1 .. @scanner.pos ] - text += @scanner.string[ startpos-1 .. @scanner.pos ] - end - - # ...or for an inline style second part - elsif @scanner.scan( InlineLinkRegex ) - url = @scanner[1] - title = @scanner[3] - @log.debug " Found an inline link to %p" % url - - text += %{#{link}} - - # No linkid part: just append the first part as-is. - else - @log.debug "No linkid, so no anchor. Appending literal text." - text += @scanner.string[ startpos-1 .. @scanner.pos-1 ] - end # if linkid - - # Plain text - else - @log.debug " Scanning to the next link from %p" % @scanner.rest - text += @scanner.scan( /[^\[]+/ ) - end - - end # until @scanner.empty? - - return text - end - - # Pattern to match strong emphasis in Markdown text - BoldRegexp = %r{ (\*\*|__) (?=\S) (.+?\S) \1 }x - - # Pattern to match normal emphasis in Markdown text - ItalicRegexp = %r{ (\*|_) (?=\S) (.+?\S) \1 }x - - ### Transform italic- and bold-encoded text in a copy of the specified +str+ - ### and return it. - def transform_italic_and_bold( str, rs ) - @log.debug " Transforming italic and bold" - - str. - gsub( BoldRegexp, %{\\2} ). - gsub( ItalicRegexp, %{\\2} ) - end - - - ### Transform backticked spans into spans. - def transform_code_spans( str, rs ) - @log.debug " Transforming code spans" - - # Set up the string scanner and just return the string unless there's at - # least one backtick. - @scanner.string = str.dup - unless @scanner.exist?( /`/ ) - @scanner.terminate - @log.debug "No backticks found for code span in %p" % str - return str - end - - @log.debug "Transforming code spans in %p" % str - - # Build the transformed text anew - text = '' - - # Scan to the end of the string - until @scanner.empty? - - # Scan up to an opening backtick - if pre = @scanner.scan_until( /.?(?=`)/m ) - text += pre - @log.debug "Found backtick at %d after '...%s'" % - [ @scanner.pos, text[-10, 10] ] - - # Make a pattern to find the end of the span - opener = @scanner.scan( /`+/ ) - len = opener.length - closer = Regexp::new( opener ) - @log.debug "Scanning for end of code span with %p" % closer - - # Scan until the end of the closing backtick sequence. Chop the - # backticks off the resultant string, strip leading and trailing - # whitespace, and encode any enitites contained in it. - codespan = @scanner.scan_until( closer ) or - raise FormatError::new( @scanner.rest[0,20], - "No %p found before end" % opener ) - - @log.debug "Found close of code span at %d: %p" % - [ @scanner.pos - len, codespan ] - codespan.slice!( -len, len ) - text += "%s" % - encode_code( codespan.strip, rs ) - - # If there's no more backticks, just append the rest of the string - # and move the scan pointer to the end - else - text += @scanner.rest - @scanner.terminate - end - end - - return text - end - - - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - InlineImageRegexp = %r{ - ( # Whole match = $1 - !\[ (.*?) \] # alt text = $2 - \([ ]* (\S+) [ ]* # source url = $3 - ( # title = $4 - (["']) # quote char = $5 - .*? - \5 # matching quote - [ ]* - )? # title is optional - \) - ) - }xs #" - - - # Reference-style images - ReferenceImageRegexp = %r{ - ( # Whole match = $1 - !\[ (.*?) \] # Alt text = $2 - [ ]? # Optional space - (?:\n[ ]*)? # One optional newline + spaces - \[ (.*?) \] # id = $3 - ) - }xs - - ### Turn image markup into image tags. - def transform_images( str, rs ) - @log.debug " Transforming images" % str - - # Handle reference-style labeled images: ![alt text][id] - str. - gsub( ReferenceImageRegexp ) {|match| - whole, alt, linkid = $1, $2, $3.downcase - @log.debug "Matched %p" % match - res = nil - - # for shortcut links like ![this][]. - linkid = alt.downcase if linkid.empty? - - if rs.urls.key?( linkid ) - url = escape_md( rs.urls[linkid] ) - @log.debug "Found url '%s' for linkid '%s' " % - [ url, linkid ] - - # Build the tag - result = %{%s}, '>' ). - gsub( CodeEscapeRegexp ) {|match| EscapeTable[match][:md5]} - end - - - - ################################################################# - ### U T I L I T Y F U N C T I O N S - ################################################################# - - ### Escape any markdown characters in a copy of the given +str+ and return - ### it. - def escape_md( str ) - str. - gsub( /\*/, '*' ). - gsub( /_/, '_' ) - end - - - # Matching constructs for tokenizing X/HTML - HTMLCommentRegexp = %r{ }mx - XMLProcInstRegexp = %r{ <\? .*? \?> }mx - MetaTag = Regexp::union( HTMLCommentRegexp, XMLProcInstRegexp ) - - HTMLTagOpenRegexp = %r{ < [a-z/!$] [^<>]* }mx - HTMLTagCloseRegexp = %r{ > }x - HTMLTagPart = Regexp::union( HTMLTagOpenRegexp, HTMLTagCloseRegexp ) - - ### Break the HTML source in +str+ into a series of tokens and return - ### them. The tokens are just 2-element Array tuples with a type and the - ### actual content. If this function is called with a block, the type and - ### text parts of each token will be yielded to it one at a time as they are - ### extracted. - def tokenize_html( str ) - depth = 0 - tokens = [] - @scanner.string = str.dup - type, token = nil, nil - - until @scanner.empty? - @log.debug "Scanning from %p" % @scanner.rest - - # Match comments and PIs without nesting - if (( token = @scanner.scan(MetaTag) )) - type = :tag - - # Do nested matching for HTML tags - elsif (( token = @scanner.scan(HTMLTagOpenRegexp) )) - tagstart = @scanner.pos - @log.debug " Found the start of a plain tag at %d" % tagstart - - # Start the token with the opening angle - depth = 1 - type = :tag - - # Scan the rest of the tag, allowing unlimited nested <>s. If - # the scanner runs out of text before the tag is closed, raise - # an error. - while depth.nonzero? - - # Scan either an opener or a closer - chunk = @scanner.scan( HTMLTagPart ) or - raise "Malformed tag at character %d: %p" % - [ tagstart, token + @scanner.rest ] - - @log.debug " Found another part of the tag at depth %d: %p" % - [ depth, chunk ] - - token += chunk - - # If the last character of the token so far is a closing - # angle bracket, decrement the depth. Otherwise increment - # it for a nested tag. - depth += ( token[-1, 1] == '>' ? -1 : 1 ) - @log.debug " Depth is now #{depth}" - end - - # Match text segments - else - @log.debug " Looking for a chunk of text" - type = :text - - # Scan forward, always matching at least one character to move - # the pointer beyond any non-tag '<'. - token = @scanner.scan_until( /[^<]+/m ) - end - - @log.debug " type: %p, token: %p" % [ type, token ] - - # If a block is given, feed it one token at a time. Add the token to - # the token list to be returned regardless. - if block_given? - yield( type, token ) - end - tokens << [ type, token ] - end - - return tokens - end - - - ### Return a copy of +str+ with angle brackets and ampersands HTML-encoded. - def encode_html( str ) - str.gsub( /&(?!#?[x]?(?:[0-9a-f]+|\w+);)/i, "&" ). - gsub( %r{<(?![a-z/?\$!])}i, "<" ) - end - - - ### Return one level of line-leading tabs or spaces from a copy of +str+ and - ### return it. - def outdent( str ) - str.gsub( /^(\t|[ ]{1,#{TabWidth}})/, '') - end - -end # class BlueCloth - diff --git a/lib/chunks/engines.rb b/lib/chunks/engines.rb index 82808123..436047d3 100644 --- a/lib/chunks/engines.rb +++ b/lib/chunks/engines.rb @@ -35,8 +35,8 @@ module Engines class Markdown < AbstractEngine def mask - require_dependency 'bluecloth_tweaked' - BlueCloth.new(@content, @content.options[:engine_opts]).to_html + require_dependency 'maruku' + Maruku.new(@content.delete("\r"), {:math_enabled => false}).to_html end end @@ -44,7 +44,7 @@ module Engines def mask require_dependency 'maruku' require_dependency 'maruku/ext/math' - Maruku.new(@content.delete("\r")).to_html + Maruku.new(@content.delete("\r"), {:math_enabled => true}).to_html end end diff --git a/vendor/plugins/maruku/lib/maruku/attributes.rb b/vendor/plugins/maruku/lib/maruku/attributes.rb index 840554e2..74d7fe90 100644 --- a/vendor/plugins/maruku/lib/maruku/attributes.rb +++ b/vendor/plugins/maruku/lib/maruku/attributes.rb @@ -192,9 +192,10 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser end + # We need a helper + def is_ial(e); e.kind_of? MDElement and e.node_type == :ial end + def merge_ial(elements, src, con) - # We need a helper - def is_ial(e); e.kind_of? MDElement and e.node_type == :ial end # Apply each IAL to the element before elements.each_with_index do |e, i| diff --git a/vendor/plugins/maruku/lib/maruku/ext/math.rb b/vendor/plugins/maruku/lib/maruku/ext/math.rb index 759deb1f..06b296b3 100644 --- a/vendor/plugins/maruku/lib/maruku/ext/math.rb +++ b/vendor/plugins/maruku/lib/maruku/ext/math.rb @@ -9,3 +9,33 @@ 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] = [] diff --git a/vendor/plugins/maruku/lib/maruku/ext/math/elements.rb b/vendor/plugins/maruku/lib/maruku/ext/math/elements.rb index 5f9c4dfa..f0ba3c08 100644 --- a/vendor/plugins/maruku/lib/maruku/ext/math/elements.rb +++ b/vendor/plugins/maruku/lib/maruku/ext/math/elements.rb @@ -4,7 +4,7 @@ module MaRuKu; class MDElement self.md_el(:inline_math, [], meta={:math=>math}) end - def md_equation(math, label=nil) + def md_equation(math, label, numerate) reglabel= /\\label\{(\w+)\}/ if math =~ reglabel label = $1 @@ -12,9 +12,10 @@ module MaRuKu; class MDElement end # puts "Found label = #{label} math #{math.inspect} " num = nil - if label && @doc #take number + if (label || numerate) && @doc #take number @doc.eqid2eq ||= {} num = @doc.eqid2eq.size + 1 + label = "eq#{num}" if not label # FIXME do id for document end e = self.md_el(:equation, [], meta={:math=>math, :label=>label,:num=>num}) if label && @doc #take number diff --git a/vendor/plugins/maruku/lib/maruku/ext/math/parsing.rb b/vendor/plugins/maruku/lib/maruku/ext/math/parsing.rb index ff317afb..20000ab2 100644 --- a/vendor/plugins/maruku/lib/maruku/ext/math/parsing.rb +++ b/vendor/plugins/maruku/lib/maruku/ext/math/parsing.rb @@ -1,70 +1,90 @@ module MaRuKu + class MDDocument # Hash equation id (String) to equation element (MDElement) attr_accessor :eqid2eq + + def is_math_enabled? + get_setting :math_enabled + end end end - # At least one slash inside - #RegInlineMath1 = /\$([^\$]*[\\][^\$]*)\$/ - # No spaces around the delimiters - #RegInlineMath2 = /\$([^\s\$](?:[^\$]*[^\s\$])?)\$/ - #RegInlineMath = Regexp::union(RegInlineMath1,RegInlineMath2) - # Everything goes; takes care of escaping the "\$" inside the expression RegInlineMath = /\${1}((?:[^\$]|\\\$)+)\$/ - MaRuKu::In::Markdown:: - register_span_extension(:chars => ?$, :regexp => RegInlineMath) do - |doc, src, con| - if m = src.read_regexp(RegInlineMath) - math = m.captures.compact.first - con.push doc.md_inline_math(math) - true - else - #puts "not math: #{src.cur_chars 10}" - false - end - end + MaRuKu::In::Markdown::register_span_extension( + :chars => ?$, + :regexp => RegInlineMath, + :handler => lambda { |doc, src, con| + return false if not doc.is_math_enabled? + + if m = src.read_regexp(RegInlineMath) + math = m.captures.compact.first + con.push doc.md_inline_math(math) + true + else + #puts "not math: #{src.cur_chars 10}" + false + end + } + ) - EquationStart = /^[ ]{0,3}(?:\\\[|\$\$)(.*)$/ + + MathOpen1 = Regexp.escape('\\begin{equation}') + MathClose1 = Regexp.escape('\\end{equation}') + MathOpen2 = Regexp.escape('\\[') + MathClose2 = Regexp.escape('\\]') + MathOpen3 = Regexp.escape('$$') + MathClose3 = Regexp.escape('$$') EqLabel = /(?:\((\w+)\))/ - OneLineEquation = /^[ ]{0,3}(?:\\\[|\$\$)(.*)(?:\\\]|\$\$)\s*#{EqLabel}?\s*$/ - EquationEnd = /^(.*)(?:\\\]|\$\$)\s*#{EqLabel}?\s*$/ + 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) do |doc, src, con| -# puts "Equation :#{self}" - first = src.shift_line - if first =~ OneLineEquation - math = $1 - label = $2 - con.push doc.md_equation($1, $2) - else - first =~ EquationStart - math = $1 - label = nil - while true - if not src.cur_line - maruku_error "Stream finished while reading equation\n\n"+ - add_tabs(math,1,'$> '), src, con - break - end - line = src.shift_line - if line =~ EquationEnd - math += $1 + "\n" - label = $2 if $2 - break - else - math += line + "\n" + MaRuKu::In::Markdown::register_block_extension( + :regexp => EquationStart, + :handler => lambda { |doc, src, con| + return false if not 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) + else + first =~ EquationStart + opening, tex = $1, $2 + + numerate = doc.get_setting(:math_numbered).include?(opening) + label = nil + while true + if not src.cur_line + doc.maruku_error("Stream finished while reading equation\n\n"+ + doc.add_tabs(tex,1,'$> '), 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 + else + tex += line + "\n" + end end + con.push doc.md_equation(tex, label, numerate) end - con.push doc.md_equation(math, label) - end - true - end + true + }) # This adds support for \eqref @@ -72,11 +92,14 @@ end RegEqPar = /\(eq:(\w+)\)/ RegEqref = Regexp::union(RegEqrefLatex, RegEqPar) - MaRuKu::In::Markdown:: - register_span_extension(:chars => [?\\, ?(], :regexp => RegEqref) do - |doc, src, con| - eqid = src.read_regexp(RegEqref).captures.compact.first - r = doc.md_el(:eqref, [], meta={:eqid=>eqid}) - con.push r - true - end + MaRuKu::In::Markdown::register_span_extension( + :chars => [?\\, ?(], + :regexp => RegEqref, + :handler => lambda { |doc, src, con| + return false if not doc.is_math_enabled? + eqid = src.read_regexp(RegEqref).captures.compact.first + r = doc.md_el(:eqref, [], meta={:eqid=>eqid}) + con.push r + true + } + ) diff --git a/vendor/plugins/maruku/lib/maruku/ext/math/to_html.rb b/vendor/plugins/maruku/lib/maruku/ext/math/to_html.rb index 7e4fff33..b12f90fa 100644 --- a/vendor/plugins/maruku/lib/maruku/ext/math/to_html.rb +++ b/vendor/plugins/maruku/lib/maruku/ext/math/to_html.rb @@ -121,7 +121,7 @@ module MaRuKu; module Out; module HTML div = create_html_element 'div' add_class_to(div, 'maruku-equation') - if self.label # then numerate + if self.label # then numerate span = Element.new 'span' span.attributes['class'] = 'maruku-eq-number' num = self.num diff --git a/vendor/plugins/maruku/lib/maruku/helpers.rb b/vendor/plugins/maruku/lib/maruku/helpers.rb index 63defabb..3b382182 100644 --- a/vendor/plugins/maruku/lib/maruku/helpers.rb +++ b/vendor/plugins/maruku/lib/maruku/helpers.rb @@ -92,6 +92,8 @@ module Helpers e.instance_variable_set :@parsed_html, REXML::Document.new(raw_html) rescue + e.instance_variable_set :@parsed_html, nil + # tell_user "Malformed block of HTML:\n"+ # add_tabs(raw_html,1,'|') # " #{raw_html.inspect}\n\n"+ex.inspect diff --git a/vendor/plugins/maruku/lib/maruku/input/charsource.rb b/vendor/plugins/maruku/lib/maruku/input/charsource.rb index fd9b562e..15339787 100644 --- a/vendor/plugins/maruku/lib/maruku/input/charsource.rb +++ b/vendor/plugins/maruku/lib/maruku/input/charsource.rb @@ -262,7 +262,7 @@ class CharSourceStrscan end def consume_whitespace - @s.scan /\s+/ + @s.scan(/\s+/) nil end diff --git a/vendor/plugins/maruku/lib/maruku/input/extensions.rb b/vendor/plugins/maruku/lib/maruku/input/extensions.rb index b8110b00..d0a8de06 100644 --- a/vendor/plugins/maruku/lib/maruku/input/extensions.rb +++ b/vendor/plugins/maruku/lib/maruku/input/extensions.rb @@ -29,19 +29,19 @@ module MaRuKu; module In; module Markdown return false # not special end - def self.register_span_extension(args, &block) + def self.register_span_extension(args) e = SpanExtension.new e.chars = [*args[:chars]] e.regexp = args[:regexp] - e.block = block + e.block = args[:handler] || raise("No blocks passed") e.chars.each do |c| (SpanExtensionsTrigger[c] ||= []).push e end end - def self.register_block_extension(args, &block) + def self.register_block_extension(args) regexp = args[:regexp] - BlockExtensions[regexp] = block + BlockExtensions[regexp] = (args[:handler] || raise("No blocks passed")) end # Hash Regexp -> Block @@ -50,8 +50,10 @@ module MaRuKu; module In; module Markdown def check_block_extensions(src, con, line) BlockExtensions.each do |reg, block| if m = reg.match(line) + p m block = BlockExtensions[reg] - return true if block.call(doc, src, con) + accepted = block.call(doc, src, con) + return true if accepted end end return false # not special diff --git a/vendor/plugins/maruku/lib/maruku/input/parse_block.rb b/vendor/plugins/maruku/lib/maruku/input/parse_block.rb index bf7ec4d1..f722be79 100644 --- a/vendor/plugins/maruku/lib/maruku/input/parse_block.rb +++ b/vendor/plugins/maruku/lib/maruku/input/parse_block.rb @@ -215,7 +215,7 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser if result.kind_of? String raise "Not expected" else - output.push *result + output.push(*result) end end else @@ -242,7 +242,7 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser end def read_paragraph(src) - lines = [] + lines = [src.shift_line] while src.cur_line # :olist does not break case t = src.cur_line.md_type @@ -253,7 +253,7 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser end break if src.cur_line.strip.size == 0 break if [:header1,:header2].include? src.next_line.md_type - break if any_matching_block_extension?(src.cur_line) + break if any_matching_block_extension?(src.cur_line) lines << src.shift_line end @@ -491,12 +491,11 @@ module MaRuKu; module In; module Markdown; module BlockLevelParser out.push md_ref_def(id, url, meta={:title=>title}) end + def split_cells(s) + s.strip.split('|').select{|x|x.strip.size>0}.map{|x|x.strip} + end + def read_table(src) - - def split_cells(s) - s.strip.split('|').select{|x|x.strip.size>0}.map{|x|x.strip} - end - head = split_cells(src.shift_line).map{|s| md_el(:head_cell, parse_lines_as_span([s])) } separator=split_cells(src.shift_line) diff --git a/vendor/plugins/maruku/lib/maruku/input/parse_span_better.rb b/vendor/plugins/maruku/lib/maruku/input/parse_span_better.rb index c382c66b..b0230658 100644 --- a/vendor/plugins/maruku/lib/maruku/input/parse_span_better.rb +++ b/vendor/plugins/maruku/lib/maruku/input/parse_span_better.rb @@ -196,10 +196,10 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser interpret_extension(src, con, [?}]) src.ignore_char # } when nil - maruku_error ("Unclosed span (waiting for %s"+ + maruku_error( ("Unclosed span (waiting for %s"+ "#{exit_on_strings.inspect})") % [ exit_on_chars ? "#{exit_on_chars.inspect} or" : ""], - src,con + src,con) break else # normal text con.push_char src.shift_char @@ -618,8 +618,8 @@ module MaRuKu; module In; module Markdown; module SpanLevelParser src.consume_whitespace closing = src.shift_char # closing ) if closing != ?) - error ("Unclosed link: '"<|\<\>|\=)? + # 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 + + # ignore empty line + if l.t2_empty? then + src.shift_line + next + end + + l = src.shift_line + # 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 + +end \ No newline at end of file diff --git a/vendor/plugins/maruku/lib/maruku/maruku.rb b/vendor/plugins/maruku/lib/maruku/maruku.rb index 0ce5545c..6be6bfa8 100644 --- a/vendor/plugins/maruku/lib/maruku/maruku.rb +++ b/vendor/plugins/maruku/lib/maruku/maruku.rb @@ -20,9 +20,9 @@ # The Maruku class is the public interface +# class Maruku - def initialize(s=nil, meta={}) super(nil) self.attributes.merge! meta diff --git a/vendor/plugins/maruku/lib/maruku/output/to_html.rb b/vendor/plugins/maruku/lib/maruku/output/to_html.rb index f59e6056..f6689dba 100644 --- a/vendor/plugins/maruku/lib/maruku/output/to_html.rb +++ b/vendor/plugins/maruku/lib/maruku/output/to_html.rb @@ -316,11 +316,55 @@ Output: HTML It is copied as a standard HTML attribute. =end - StandardAttributes = [:id, :style, :class] + + + + + HTML4Attributes = {} + + coreattrs = [:id, :class, :style, :title] + i18n = [:lang, 'xml:lang'.to_sym] + events = [ + :onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover, + :onmousemove, :onmouseout, + :onkeypress, :onkeydown, :onkeyup] + attrs = coreattrs + i18n + events + cellhalign = [:align, :char, :charoff] + cellvalign = [:valign] + [ + ['body', attrs + [:onload, :onunload]], + ['address', attrs], + ['div', attrs], + ['a', attrs+[:charset, :type, :name, :rel, :rev, :accesskey, :shape, :coords, :tabindex, + :onfocus,:onblur]], + ['img', attrs + [:longdesc, :name, :height, :width, :alt] ], + ['p', attrs], + [['h1','h2','h3','h4','h5','h6'], attrs], + [['pre'], attrs], + [['q', 'blockquote'], attrs+[:cite]], + [['ins','del'], attrs+[:cite,:datetime]], + [['ol','ul','li'], attrs], + ['table',attrs+[:summary, :width, :frame, :rules, :border, :cellspacing, :cellpadding]], + ['caption',attrs], + [['colgroup','col'],attrs+[:span, :width]+cellhalign+cellvalign], + [['thead','tbody','tfoot'], attrs+cellhalign+cellvalign], + [['td','td','th'], attrs+[:abbr, :axis, :headers, :scope, :rowspan, :colspan, :cellvalign, :cellhalign]], + + # altri + [['em','code','strong','hr','span','dl','dd','dt'], attrs] + ].each do |el, a| [*el].each do |e| HTML4Attributes[e] = a end end + + def create_html_element(name, attributes_to_copy=[]) m = Element.new name - (StandardAttributes+attributes_to_copy).each do |a| - if v = @attributes[a] then m.attributes[a.to_s] = v.to_s end + if atts = HTML4Attributes[name] then + atts.each do |att| + if v = @attributes[att] then + m.attributes[att.to_s] = v.to_s + end + end + else + # puts "not atts for #{name.inspect}" end m end @@ -337,11 +381,11 @@ It is copied as a standard HTML attribute. end - def to_html_paragraph; add_ws wrap_as_element('p', [:'xml:lang']) 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_li_span; add_ws wrap_as_element('li') end - def to_html_quote; add_ws wrap_as_element('blockquote', [:cite, :'xml:lang']) 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 @@ -383,7 +427,7 @@ by Maruku, to have the same results in both HTML and LaTeX. def to_html_header element_name = "h#{self.level}" - h = wrap_as_element(element_name, [:title, :'xml:lang']) + h = wrap_as_element element_name if span = render_section_number h.insert_before(h.children.first, span) @@ -432,6 +476,7 @@ and =end + $syntax_loaded = false def to_html_code; source = self.raw_code @@ -547,7 +592,7 @@ of the form `#ff00ff`. color = get_setting(:code_background_color) if color != Globals[:code_background_color] - pre.attributes['style'] = "background-color: #{color};" + pre.attributes['style'] = "background-color: #{color};"+(pre.attributes['style']||"") end pre @@ -565,17 +610,17 @@ of the form `#ff00ff`. def add_class_to_link(a) return # not ready yet - url = a.attributes['href'] - return if not url - - if url =~ /^#/ - add_class_to(a, 'maruku-link-samedoc') - elsif url =~ /^http:/ - add_class_to(a, 'maruku-link-external') - else - add_class_to(a, 'maruku-link-local') - end - + # url = a.attributes['href'] + # return if not url + # + # if url =~ /^#/ + # add_class_to(a, 'maruku-link-samedoc') + # elsif url =~ /^http:/ + # add_class_to(a, 'maruku-link-external') + # else + # add_class_to(a, 'maruku-link-local') + # end + # # puts a.attributes['class'] end @@ -659,10 +704,7 @@ of the form `#ff00ff`. url = ref[:url] title = ref[:title] a.attributes['src'] = url.to_s - a.attributes['alt'] = title.to_s - [:title, :class, :style].each do |s| - a.attributes[s.to_s] = ref[s] if ref[s] - end + a.attributes['alt'] = title.to_s if not a.attributes['alt'] else maruku_error"Could not find id = #{id.inspect} for\n #{self.inspect}" tell_user "Could not create image with ref_id = #{id.inspect};"+ @@ -674,15 +716,15 @@ of the form `#ff00ff`. def to_html_im_image if not url = self.url - maruku_error"Image with no url: #{self.inspect}" + maruku_error "Image with no url: #{self.inspect}" tell_user "Could not create image with ref_id = #{id.inspect};"+ - +" Using SPAN element as replacement." + " Using SPAN element as replacement." return wrap_as_element('span') end title = self.title a = create_html_element 'img' - a.attributes['src'] = url - a.attributes['alt'] = title.to_s + a.attributes['src'] = url.to_s + a.attributes['alt'] = title.to_s if not a.attributes['alt'] return a end @@ -762,8 +804,7 @@ of the form `#ff00ff`. i += num_columns end - table = create_html_element 'table', - [:summary, :width, :frame, :rules, :border, :cellspacing, :cellpadding] + table = create_html_element 'table' thead = Element.new 'thead' tr = Element.new 'tr' array_to_html(head).each do |x| tr< 'iso-8859-1'}], +# ["#{AccIta1}", [AccIta8], "Converting ISO-8859-1 to UTF-8", +# {:encoding => 'iso-8859-1'}], ] @@ -294,6 +294,7 @@ module MaRuKu; module Tests m.attributes[:on_error] = :raise Globals[:debug_keep_ials] = true + num_ok = 0 good_cases.each do |input, expected, comment| output = nil begin @@ -309,6 +310,7 @@ module MaRuKu; module Tests raise e if @break_on_first_error else quiet || print_status(comment,'OK') + num_ok += 1 end end @@ -318,6 +320,7 @@ module MaRuKu; module Tests print_status(comment, 'FAILED', s) break if break_on_first_error else + num_ok += 1 quiet || print_status(comment, 'OK') end else # I expected a raise @@ -327,8 +330,12 @@ module MaRuKu; module Tests print_status(comment, 'FAILED (no throw)', s) break if break_on_first_error end - end - + end + end # do + if num_ok != good_cases.size + return false + else + return true end end @@ -358,6 +365,6 @@ end verbose = ARGV.include? 'v' break_on_first = ARGV.include? 'b' quiet = ARGV.include? 'q' -Maruku.new.test_span_parser(verbose, break_on_first, quiet) - +ok = Maruku.new.test_span_parser(verbose, break_on_first, quiet) +exit (ok ? 0 : 1) diff --git a/vendor/plugins/maruku/lib/maruku/version.rb b/vendor/plugins/maruku/lib/maruku/version.rb index 2f212835..7e5b5b63 100644 --- a/vendor/plugins/maruku/lib/maruku/version.rb +++ b/vendor/plugins/maruku/lib/maruku/version.rb @@ -19,7 +19,7 @@ #++ module MaRuKu - Version = '0.5.2' + Version = '0.5.3' MarukuURL = 'http://maruku.rubyforge.org/'