asciidoctor 0.1.4 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of asciidoctor might be problematic. Click here for more details.

Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +209 -25
  3. data/{LICENSE → LICENSE.adoc} +4 -3
  4. data/README.adoc +392 -395
  5. data/Rakefile +94 -137
  6. data/benchmark/benchmark.rb +127 -0
  7. data/benchmark/sample-data/mdbasics.adoc +334 -0
  8. data/bin/asciidoctor +5 -8
  9. data/bin/asciidoctor-safe +4 -8
  10. data/compat/asciidoc.conf +78 -11
  11. data/compat/font-awesome-3-compat.css +397 -0
  12. data/data/stylesheets/asciidoctor-default.css +399 -0
  13. data/data/stylesheets/coderay-asciidoctor.css +89 -0
  14. data/features/open_block.feature +92 -0
  15. data/features/pass_block.feature +66 -0
  16. data/features/step_definitions.rb +42 -0
  17. data/features/text_formatting.feature +55 -0
  18. data/features/xref.feature +116 -0
  19. data/lib/asciidoctor.rb +1155 -605
  20. data/lib/asciidoctor/abstract_block.rb +157 -71
  21. data/lib/asciidoctor/abstract_node.rb +150 -93
  22. data/lib/asciidoctor/attribute_list.rb +85 -90
  23. data/lib/asciidoctor/block.rb +51 -24
  24. data/lib/asciidoctor/callouts.rb +4 -7
  25. data/lib/asciidoctor/cli.rb +3 -0
  26. data/lib/asciidoctor/cli/invoker.rb +86 -76
  27. data/lib/asciidoctor/cli/options.rb +111 -61
  28. data/lib/asciidoctor/converter.rb +232 -0
  29. data/lib/asciidoctor/converter/base.rb +58 -0
  30. data/lib/asciidoctor/converter/composite.rb +66 -0
  31. data/lib/asciidoctor/converter/docbook45.rb +94 -0
  32. data/lib/asciidoctor/converter/docbook5.rb +684 -0
  33. data/lib/asciidoctor/converter/factory.rb +225 -0
  34. data/lib/asciidoctor/converter/html5.rb +1081 -0
  35. data/lib/asciidoctor/converter/template.rb +296 -0
  36. data/lib/asciidoctor/core_ext.rb +7 -0
  37. data/lib/asciidoctor/core_ext/object/nil_or_empty.rb +23 -0
  38. data/lib/asciidoctor/core_ext/string/chr.rb +6 -0
  39. data/lib/asciidoctor/core_ext/symbol/length.rb +6 -0
  40. data/lib/asciidoctor/document.rb +590 -304
  41. data/lib/asciidoctor/extensions.rb +1100 -308
  42. data/lib/asciidoctor/helpers.rb +109 -46
  43. data/lib/asciidoctor/inline.rb +16 -9
  44. data/lib/asciidoctor/list.rb +23 -15
  45. data/lib/asciidoctor/opal_ext.rb +4 -0
  46. data/lib/asciidoctor/opal_ext/comparable.rb +38 -0
  47. data/lib/asciidoctor/opal_ext/dir.rb +13 -0
  48. data/lib/asciidoctor/opal_ext/error.rb +2 -0
  49. data/lib/asciidoctor/opal_ext/file.rb +125 -0
  50. data/lib/asciidoctor/{lexer.rb → parser.rb} +646 -455
  51. data/lib/asciidoctor/path_resolver.rb +141 -77
  52. data/lib/asciidoctor/reader.rb +257 -187
  53. data/lib/asciidoctor/section.rb +12 -16
  54. data/lib/asciidoctor/stylesheets.rb +91 -0
  55. data/lib/asciidoctor/substitutors.rb +1548 -0
  56. data/lib/asciidoctor/table.rb +73 -57
  57. data/lib/asciidoctor/timings.rb +39 -0
  58. data/lib/asciidoctor/version.rb +1 -1
  59. data/man/asciidoctor.1 +22 -14
  60. data/man/asciidoctor.adoc +18 -10
  61. data/test/attributes_test.rb +314 -14
  62. data/test/blocks_test.rb +763 -118
  63. data/test/converter_test.rb +352 -0
  64. data/test/document_test.rb +518 -199
  65. data/test/extensions_test.rb +273 -103
  66. data/test/fixtures/asciidoc_index.txt +27 -13
  67. data/test/fixtures/basic-docinfo.xml +1 -1
  68. data/test/fixtures/chapter-a.adoc +3 -0
  69. data/test/fixtures/custom-backends/erb/html5/block_paragraph.html.erb +6 -0
  70. data/test/fixtures/docinfo.xml +1 -1
  71. data/test/fixtures/include-file.asciidoc +2 -0
  72. data/test/fixtures/master.adoc +5 -0
  73. data/test/invoker_test.rb +173 -61
  74. data/test/links_test.rb +97 -21
  75. data/test/lists_test.rb +181 -22
  76. data/test/options_test.rb +86 -2
  77. data/test/paragraphs_test.rb +47 -5
  78. data/test/{lexer_test.rb → parser_test.rb} +128 -57
  79. data/test/paths_test.rb +36 -1
  80. data/test/preamble_test.rb +25 -17
  81. data/test/reader_test.rb +404 -249
  82. data/test/sections_test.rb +623 -58
  83. data/test/substitutions_test.rb +609 -132
  84. data/test/tables_test.rb +198 -24
  85. data/test/test_helper.rb +101 -31
  86. data/test/text_test.rb +88 -31
  87. metadata +160 -64
  88. data/Gemfile +0 -12
  89. data/Guardfile +0 -18
  90. data/asciidoctor.gemspec +0 -143
  91. data/lib/asciidoctor/backends/_stylesheets.rb +0 -466
  92. data/lib/asciidoctor/backends/base_template.rb +0 -114
  93. data/lib/asciidoctor/backends/docbook45.rb +0 -774
  94. data/lib/asciidoctor/backends/docbook5.rb +0 -103
  95. data/lib/asciidoctor/backends/html5.rb +0 -1214
  96. data/lib/asciidoctor/renderer.rb +0 -259
  97. data/lib/asciidoctor/substituters.rb +0 -1083
  98. data/test/fixtures/asciidoc.txt +0 -105
  99. data/test/fixtures/ascshort.txt +0 -32
  100. data/test/fixtures/list_elements.asciidoc +0 -10
  101. data/test/renderer_test.rb +0 -162
data/Rakefile CHANGED
@@ -1,165 +1,122 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'date'
4
-
5
- #############################################################################
6
- #
7
- # Helper functions
8
- #
9
- #############################################################################
10
-
11
- def name
12
- @name ||= Dir['*.gemspec'].first.split('.').first
13
- end
14
-
15
- def version
16
- line = File.read("lib/#{name}/version.rb")[/^\s*VERSION\s*=\s*.*/]
17
- line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
- end
19
-
20
- def date
21
- Date.today.to_s
22
- end
23
-
24
- def rubyforge_project
25
- name
26
- end
27
-
28
- def gemspec_file
29
- "#{name}.gemspec"
30
- end
31
-
32
- def gem_file
33
- "#{name}-#{version}.gem"
1
+ require File.expand_path '../lib/asciidoctor/version', __FILE__
2
+
3
+ def prepare_test_env
4
+ # rather than hardcoding gc settings in test task,
5
+ # could use https://gist.github.com/benders/788695
6
+ ENV['RUBY_GC_MALLOC_LIMIT'] = 128_000_000.to_s
7
+ ENV['RUBY_GC_OLDMALLOC_LIMIT'] = 128_000_000.to_s
8
+ if RUBY_VERSION >= '2.1'
9
+ ENV['RUBY_GC_HEAP_INIT_SLOTS'] = 800_000.to_s
10
+ ENV['RUBY_GC_HEAP_FREE_SLOTS'] = 800_000.to_s
11
+ ENV['RUBY_GC_HEAP_GROWTH_MAX_SLOTS'] = 250_000.to_s
12
+ ENV['RUBY_GC_HEAP_GROWTH_FACTOR'] = 1.25.to_s
13
+ else
14
+ ENV['RUBY_FREE_MIN'] = 800_000.to_s
15
+ end
34
16
  end
35
17
 
36
- def replace_header(head, header_name)
37
- head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
18
+ begin
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ prepare_test_env
22
+ puts "LANG: #{ENV['LANG']}"
23
+ test.libs << 'test'
24
+ test.pattern = 'test/**/*_test.rb'
25
+ test.verbose = true
26
+ test.warning = true
27
+ end
28
+ task :default => :test
29
+ rescue LoadError
38
30
  end
39
31
 
40
- #############################################################################
41
- #
42
- # Standard tasks
43
- #
44
- #############################################################################
45
-
46
- task :default => :test
47
-
48
- require 'rake/testtask'
49
- Rake::TestTask.new(:test) do |test|
50
- puts "LANG: #{ENV['LANG']}"
51
- test.libs << 'lib' << 'test'
52
- test.pattern = 'test/**/*_test.rb'
53
- test.warning = true
54
- test.verbose = true
32
+ =begin
33
+ # Run tests with Encoding.default_external set to US-ASCII
34
+ begin
35
+ Rake::TestTask.new(:test_us_ascii) do |test|
36
+ prepare_test_env
37
+ puts "LANG: #{ENV['LANG']}"
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/*_test.rb'
40
+ test.ruby_opts << '-EUS-ASCII' if RUBY_VERSION >= '1.9'
41
+ test.verbose = true
42
+ test.warning = true
43
+ end
44
+ rescue LoadError
55
45
  end
46
+ =end
56
47
 
57
- # Run tests with Encoding::default_external set to US-ASCII
58
- Rake::TestTask.new(:test_us_ascii) do |test|
59
- test.libs << 'lib' << 'test'
60
- test.pattern = 'test/**/*_test.rb'
61
- test.warning = true
62
- test.verbose = true
63
- test.ruby_opts << '-EUS-ASCII' if RUBY_VERSION >= '1.9'
48
+ begin
49
+ require 'cucumber/rake/task'
50
+ Cucumber::Rake::Task.new(:features) do |t|
51
+ end
52
+ rescue LoadError
64
53
  end
65
54
 
66
- desc "Generate RCov test coverage and open in your browser"
67
- task :coverage do
68
- require 'rcov'
69
- sh "rm -fr coverage"
70
- sh "rcov test/test_*.rb"
71
- sh "open coverage/index.html"
55
+ namespace :test do
56
+ desc 'Run unit and feature tests'
57
+ task :all => [:test,:features]
72
58
  end
73
59
 
60
+ =begin
74
61
  begin
75
62
  require 'rdoc/task'
76
63
  RDoc::Task.new do |rdoc|
77
64
  rdoc.rdoc_dir = 'rdoc'
78
- rdoc.title = "#{name} #{version}"
65
+ rdoc.title = "Asciidoctor #{Asciidoctor::VERSION}"
79
66
  rdoc.markup = 'tomdoc' if rdoc.respond_to?(:markup)
80
- rdoc.rdoc_files.include('README*')
81
- rdoc.rdoc_files.include('lib/**/*.rb')
67
+ rdoc.rdoc_files.include('LICENSE.adoc', 'lib/**/*.rb')
82
68
  end
83
69
  rescue LoadError
84
70
  end
71
+ =end
85
72
 
86
- desc "Open an irb session preloaded with this library"
87
- task :console do
88
- sh "irb -rubygems -r ./lib/#{name}.rb"
89
- end
90
-
91
- #############################################################################
92
- #
93
- # Custom tasks (add your own tasks here)
94
- #
95
- #############################################################################
96
-
97
-
98
-
99
- #############################################################################
100
- #
101
- # Packaging tasks
102
- #
103
- #############################################################################
104
-
105
- desc "Create tag v#{version} and build and push #{gem_file} to Rubygems"
106
- task :release => :build do
107
- unless `git branch` =~ /^\* master$/
108
- puts "You must be on the master branch to release!"
109
- exit!
73
+ begin
74
+ require 'yard'
75
+ require 'yard-tomdoc'
76
+ require './lib/asciidoctor'
77
+ require './lib/asciidoctor/extensions'
78
+
79
+ # Prevent YARD from breaking command statements in literal paragraphs
80
+ class CommandBlockPostprocessor < Asciidoctor::Extensions::Postprocessor
81
+ def process document, output
82
+ output.gsub(/<pre>\$ (.+?)<\/pre>/m, '<pre class="command code"><span class="const">$</span> \1</pre>')
83
+ end
84
+ end
85
+ Asciidoctor::Extensions.register do
86
+ postprocessor CommandBlockPostprocessor
110
87
  end
111
- sh "git commit --allow-empty -a -m 'Release #{version}'"
112
- sh "git tag v#{version}"
113
- sh "git push origin master"
114
- sh "git push origin v#{version}"
115
- sh "gem push pkg/#{name}-#{version}.gem"
116
- end
117
88
 
118
- desc "Build #{gem_file} into the pkg directory"
119
- task :build => :gemspec do
120
- sh "mkdir -p pkg"
121
- sh "gem build #{gemspec_file}"
122
- sh "mv #{gem_file} pkg"
89
+ # register .adoc extension for AsciiDoc markup helper
90
+ YARD::Templates::Helpers::MarkupHelper::MARKUP_EXTENSIONS[:asciidoc] = %w(adoc)
91
+ YARD::Rake::YardocTask.new do |yard|
92
+ yard.files = %w(
93
+ lib/**/*.rb
94
+ -
95
+ CHANGELOG.adoc
96
+ LICENSE.adoc
97
+ )
98
+ # --no-highlight enabled to prevent verbatim blocks in AsciiDoc that begin with $ from being dropped
99
+ # need to patch htmlify method to not attempt to syntax highlight blocks (or fix what's wrong)
100
+ yard.options = (IO.readlines '.yardopts').map {|l| l.chomp.delete('"').split ' ', 2 }.flatten
101
+ end
102
+ rescue LoadError
123
103
  end
124
104
 
125
- desc "Generate #{gemspec_file}"
126
- task :gemspec => :validate do
127
- # read spec file and split out manifest section
128
- spec = File.read(gemspec_file)
129
- head, manifest, tail = spec.split(" # = MANIFEST =\n")
130
-
131
- # replace name version and date
132
- replace_header(head, :name)
133
- replace_header(head, :version)
134
- replace_header(head, :date)
135
- #comment this out if your rubyforge_project has a different name
136
- replace_header(head, :rubyforge_project)
105
+ begin
106
+ require 'bundler/gem_tasks'
137
107
 
138
- # determine file list from git ls-files
139
- files = `git ls-files`.
140
- split("\n").
141
- sort.
142
- reject { |file| file =~ /^\./ }.
143
- reject { |file| file =~ /^(rdoc|pkg)/ }.
144
- map { |file| " #{file}" }.
145
- join("\n")
108
+ # Enhance the release task to create an explicit commit for the release
109
+ Rake::Task[:release].enhance [:commit_release]
146
110
 
147
- # piece file back together and write
148
- manifest = " s.files = %w[\n#{files}\n ]\n"
149
- spec = [head, manifest, tail].join(" # = MANIFEST =\n")
150
- File.open(gemspec_file, 'w') { |io| io.write(spec) }
151
- puts "Updated #{gemspec_file}"
111
+ # NOTE you don't need to push after updating version and committing locally
112
+ task :commit_release do
113
+ Bundler::GemHelper.new.send(:guard_clean)
114
+ sh "git commit --allow-empty -a -m 'Release #{Asciidoctor::VERSION}'"
115
+ end
116
+ rescue LoadError
152
117
  end
153
118
 
154
- desc "Validate #{gemspec_file}"
155
- task :validate do
156
- libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}"]
157
- unless libfiles.empty?
158
- puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
159
- exit!
160
- end
161
- unless Dir['VERSION*'].empty?
162
- puts "A `VERSION` file at root level violates Gem best practices."
163
- exit!
164
- end
119
+ desc 'Open an irb session preloaded with this library'
120
+ task :console do
121
+ sh 'bundle console', :verbose => false
165
122
  end
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+
5
+ Use this script to monitor changes in performance when making code changes to Asciidoctor.
6
+
7
+ $ ruby benchmark.rb <benchmark-name> <repeat>
8
+
9
+ The most common benchmark is the userguide-loop.
10
+ It will download the AsciiDoc User Guide automatically the first time, then convert it in memory.
11
+ Running it 10 times provides a good picture.
12
+
13
+ $ ruby benchmark.rb userguide-loop 10
14
+
15
+ Only worry about the relative change to the numbers before and after the code change.
16
+ Absolute times are highly dependent on the capabilities of the machine the the version of Ruby.
17
+
18
+ To get the best results under MRI, tune Ruby using environment variables as follows:
19
+
20
+ .Ruby < 2.1
21
+ $ RUBY_GC_MALLOC_LIMIT=90000000 RUBY_FREE_MIN=650000 ruby benchmark.rb userguide-loop 10
22
+
23
+ .Ruby >= 2.1
24
+ $ RUBY_GC_MALLOC_LIMIT=128000000 RUBY_GC_OLDMALLOC_LIMIT=128000000 RUBY_GC_HEAP_INIT_SLOTS=800000 RUBY_GC_HEAP_FREE_SLOTS=800000 RUBY_GC_HEAP_GROWTH_MAX_SLOTS=250000 RUBY_GC_HEAP_GROWTH_FACTOR=1.5 ruby benchmark.rb userguide-loop 10
25
+
26
+ Asciidoctor starts with ~ 12,500 objects, adds ~ 300,000 each run, so tune RUBY_GC_HEAP_* accordingly
27
+
28
+ Execute Ruby using the `--disable=gems` flag to speed up the initial load time, as shown below:
29
+
30
+ $ ruby --disable=gems ...
31
+
32
+ =end
33
+
34
+ require 'benchmark'
35
+ include Benchmark
36
+
37
+ bench = ARGV[0]
38
+ $repeat = ARGV[1].to_i || 10000
39
+
40
+ if bench.nil?
41
+ raise 'You must specify a benchmark to run.'
42
+ end
43
+
44
+ def fetch_userguide
45
+ require 'open-uri'
46
+ userguide_uri = 'https://raw.githubusercontent.com/asciidoc/asciidoc/d43faae38c4a8bf366dcba545971da99f2b2d625/doc/asciidoc.txt'
47
+ customers_uri = 'https://raw.githubusercontent.com/asciidoc/asciidoc/d43faae38c4a8bf366dcba545971da99f2b2d625/doc/customers.csv'
48
+ userguide_content = open(userguide_uri) {|fd2| fd2.read }
49
+ customers_content = open(customers_uri) {|fd2| fd2.read }
50
+ File.open('sample-data/userguide.adoc', 'w') {|fd1| fd1.write userguide_content }
51
+ File.open('sample-data/customers.csv', 'w') {|fd1| fd1.write customers_content }
52
+ end
53
+
54
+ case bench
55
+
56
+ =begin
57
+ # benchmark template
58
+
59
+ when 'name'
60
+
61
+ sample = 'value'
62
+
63
+ Benchmark.bmbm(12) {|bm|
64
+ bm.report('operation a') { $repeat.times { call_a_on sample } }
65
+ bm.report('operation b') { $repeat.times { call_b_on sample } }
66
+ }
67
+ =end
68
+
69
+ when 'userguide'
70
+ require '../lib/asciidoctor.rb'
71
+ Asciidoctor::Compliance.markdown_syntax = false
72
+ Asciidoctor::Compliance.shorthand_property_syntax = false if Asciidoctor::VERSION > '0.1.4'
73
+ sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc'
74
+ backend = ENV['BENCH_BACKEND'] || 'html5'
75
+ fetch_userguide if sample_file == 'sample-data/userguide.adoc' && !(File.exist? sample_file)
76
+ result = Benchmark.bmbm {|bm|
77
+ bm.report(%(Convert #{sample_file} (x#{$repeat}))) {
78
+ $repeat.times {
79
+ Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :eruby => 'erubis', :header_footer => true, :to_file => false, :attributes => {'linkcss' => '', 'toc' => nil, 'numbered' => nil, 'icons' => nil, 'compat-mode' => 'legacy'}
80
+ }
81
+ }
82
+ }
83
+ # prints average for real run
84
+ puts %(>avg: #{result.first.real / $repeat})
85
+
86
+ when 'userguide-loop'
87
+ require '../lib/asciidoctor.rb'
88
+ GC.start
89
+ Asciidoctor::Compliance.markdown_syntax = false
90
+ Asciidoctor::Compliance.shorthand_property_syntax = false if Asciidoctor::VERSION > '0.1.4'
91
+ sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc'
92
+ backend = ENV['BENCH_BACKEND'] || 'html5'
93
+ fetch_userguide if sample_file == 'sample-data/userguide.adoc' && !(File.exist? sample_file)
94
+
95
+ best = nil
96
+ 2.times.each do
97
+ outer_start = Time.now
98
+ (1..$repeat).each do
99
+ inner_start = Time.now
100
+ Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :eruby => 'erubis', :header_footer => true, :to_file => false, :attributes => {'linkcss' => '', 'toc' => nil, 'numbered' => nil, 'icons' => nil, 'compat-mode' => 'legacy'}
101
+ puts (elapsed = Time.now - inner_start)
102
+ best = (best ? [best, elapsed].min : elapsed)
103
+ end
104
+ puts %(Run Total: #{Time.now - outer_start})
105
+ end
106
+ puts %(Best Time: #{best})
107
+
108
+ when 'mdbasics-loop'
109
+ require '../lib/asciidoctor.rb'
110
+ GC.start
111
+ sample_file = ENV['BENCH_TEST_FILE'] || 'sample-data/userguide.adoc'
112
+ backend = ENV['BENCH_BACKEND'] || 'html5'
113
+
114
+ best = nil
115
+ 2.times do
116
+ outer_start = Time.now
117
+ (1..$repeat).each do
118
+ inner_start = Time.now
119
+ Asciidoctor.render_file sample_file, :backend => backend, :safe => Asciidoctor::SafeMode::SAFE, :header_footer => false, :to_file => false, :attributes => {'linkcss' => '', 'idprefix' => '', 'idseparator' => '-', 'showtitle' => ''}
120
+ puts (elapsed = Time.now - inner_start)
121
+ best = (best ? [best, elapsed].min : elapsed)
122
+ end
123
+ puts %(Run Total: #{Time.now - outer_start})
124
+ end
125
+ puts %(Best Time: #{best})
126
+
127
+ end
@@ -0,0 +1,334 @@
1
+ // converted to AsciiDoc from https://github.com/gettalong/kramdown/blob/master/benchmark/mdbasics.text
2
+ # Markdown: Basics
3
+ John Gruber
4
+ :s: link:/projects/markdown/syntax
5
+ :d: link:/projects/markdown/dingus
6
+ :src: link:/projects/markdown/basics.text
7
+
8
+ ++++
9
+ <ul id="ProjectSubmenu">
10
+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
11
+ <li><a class="selected" title="Markdown Basics">Basics</a></li>
12
+ <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
13
+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
14
+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
15
+ </ul>
16
+ ++++
17
+
18
+ ## Getting the Gist of Markdown's Formatting Syntax
19
+
20
+ This page offers a brief overview of what it's like to use Markdown.
21
+ The {s}[syntax page] provides complete, detailed documentation for
22
+ every feature, but Markdown should be very easy to pick up simply by
23
+ looking at a few examples of it in action. The examples on this page
24
+ are written in a before/after style, showing example syntax and the
25
+ HTML output produced by Markdown.
26
+
27
+ It's also helpful to simply try Markdown out; the {d}[Dingus] is a
28
+ web application that allows you type your own Markdown-formatted text
29
+ and translate it to XHTML.
30
+
31
+ NOTE: This document is itself written using Markdown; you
32
+ can {src}[see the source for it by adding \'.text' to the URL].
33
+
34
+ ### Paragraphs, Headers, Blockquotes
35
+
36
+ A paragraph is simply one or more consecutive lines of text, separated
37
+ by one or more blank lines. (A blank line is any line that looks like a
38
+ blank line -- a line containing nothing spaces or tabs is considered
39
+ blank.) Normal paragraphs should not be intended with spaces or tabs.
40
+
41
+ Markdown offers two styles of headers: _Setext_ and _atx_.
42
+ Setext-style headers for +<h1>+ and +<h2>+ are created by
43
+ "underlining" with equal signs (+=+) and hyphens (+-+), respectively.
44
+ To create an atx-style header, you put 1-6 hash marks (+#+) at the
45
+ beginning of the line -- the number of hashes equals the resulting
46
+ HTML header level.
47
+
48
+ Blockquotes are indicated using email-style \'+>+' angle brackets.
49
+
50
+ .Markdown:
51
+ [listing]
52
+ ....
53
+ A First Level Header
54
+ ====================
55
+
56
+ A Second Level Header
57
+ ---------------------
58
+
59
+ Now is the time for all good men to come to
60
+ the aid of their country. This is just a
61
+ regular paragraph.
62
+
63
+ The quick brown fox jumped over the lazy
64
+ dog's back.
65
+
66
+ ### Header 3
67
+
68
+ > This is a blockquote.
69
+ >
70
+ > This is the second paragraph in the blockquote.
71
+ >
72
+ > ## This is an H2 in a blockquote
73
+ ....
74
+
75
+ .Output:
76
+ ....
77
+ <h1>A First Level Header</h1>
78
+
79
+ <h2>A Second Level Header</h2>
80
+
81
+ <p>Now is the time for all good men to come to
82
+ the aid of their country. This is just a
83
+ regular paragraph.</p>
84
+
85
+ <p>The quick brown fox jumped over the lazy
86
+ dog's back.</p>
87
+
88
+ <h3>Header 3</h3>
89
+
90
+ <blockquote>
91
+ <p>This is a blockquote.</p>
92
+
93
+ <p>This is the second paragraph in the blockquote.</p>
94
+
95
+ <h2>This is an H2 in a blockquote</h2>
96
+ </blockquote>
97
+ ....
98
+
99
+ ### Phrase Emphasis
100
+
101
+ Markdown uses asterisks and underscores to indicate spans of emphasis.
102
+
103
+ .Markdown:
104
+ ----
105
+ Some of these words *are emphasized*.
106
+ Some of these words _are emphasized also_.
107
+
108
+ Use two asterisks for **strong emphasis**.
109
+ Or, if you prefer, __use two underscores instead__.
110
+ ----
111
+
112
+ .Output:
113
+ ....
114
+ <p>Some of these words <em>are emphasized</em>.
115
+ Some of these words <em>are emphasized also</em>.</p>
116
+
117
+ <p>Use two asterisks for <strong>strong emphasis</strong>.
118
+ Or, if you prefer, <strong>use two underscores instead</strong>.</p>
119
+ ....
120
+
121
+ ### Lists
122
+
123
+ Unordered (bulleted) lists use asterisks, pluses, and hyphens (+*+,
124
+ +++, and +-+) as list markers. These three markers are
125
+ interchangable; this:
126
+
127
+ ----
128
+ * Candy.
129
+ * Gum.
130
+ * Booze.
131
+ ----
132
+
133
+ this:
134
+
135
+ ----
136
+ + Candy.
137
+ + Gum.
138
+ + Booze.
139
+ ----
140
+
141
+ and this:
142
+
143
+ ----
144
+ - Candy.
145
+ - Gum.
146
+ - Booze.
147
+ ----
148
+
149
+ all produce the same output:
150
+
151
+ ....
152
+ <ul>
153
+ <li>Candy.</li>
154
+ <li>Gum.</li>
155
+ <li>Booze.</li>
156
+ </ul>
157
+ ....
158
+
159
+ Ordered (numbered) lists use regular numbers, followed by periods, as
160
+ list markers:
161
+
162
+ ----
163
+ 1. Red
164
+ 2. Green
165
+ 3. Blue
166
+ ----
167
+
168
+ .Output:
169
+ ....
170
+ <ol>
171
+ <li>Red</li>
172
+ <li>Green</li>
173
+ <li>Blue</li>
174
+ </ol>
175
+ ....
176
+
177
+ If you put blank lines between items, you'll get +<p>+ tags for the
178
+ list item text. You can create multi-paragraph list items by indenting
179
+ the paragraphs by 4 spaces or 1 tab:
180
+
181
+ ----
182
+ * A list item.
183
+
184
+ With multiple paragraphs.
185
+
186
+ * Another item in the list.
187
+ ----
188
+
189
+ .Output:
190
+ ....
191
+ <ul>
192
+ <li><p>A list item.</p>
193
+ <p>With multiple paragraphs.</p></li>
194
+ <li><p>Another item in the list.</p></li>
195
+ </ul>
196
+ ....
197
+
198
+ ### Links
199
+
200
+ Markdown supports two styles for creating links: _inline_ and
201
+ _reference_. With both styles, you use square brackets to delimit the
202
+ text you want to turn into a link.
203
+
204
+ Inline-style links use parentheses immediately after the link text.
205
+ For example:
206
+
207
+ ----
208
+ This is an [example link](http://example.com/).
209
+ ----
210
+
211
+ .Output:
212
+ ....
213
+ <p>This is an <a href="http://example.com/">
214
+ example link</a>.</p>
215
+ ....
216
+
217
+ Optionally, you may include a title attribute in the parentheses:
218
+
219
+ ----
220
+ This is an [example link](http://example.com/ "With a Title").
221
+ ----
222
+
223
+ .Output:
224
+ ....
225
+ <p>This is an <a href="http://example.com/" title="With a Title">
226
+ example link</a>.</p>
227
+ ....
228
+
229
+ Reference-style links allow you to refer to your links by names, which
230
+ you define elsewhere in your document:
231
+
232
+ ----
233
+ I get 10 times more traffic from [Google][1] than from
234
+ [Yahoo][2] or [MSN][3].
235
+
236
+ [1]: http://google.com/ "Google"
237
+ [2]: http://search.yahoo.com/ "Yahoo Search"
238
+ [3]: http://search.msn.com/ "MSN Search"
239
+ ----
240
+
241
+ .Output:
242
+ ....
243
+ <p>I get 10 times more traffic from <a href="http://google.com/"
244
+ title="Google">Google</a> than from <a href="http://search.yahoo.com/"
245
+ title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
246
+ title="MSN Search">MSN</a>.</p>
247
+ ....
248
+
249
+ The title attribute is optional. Link names may contain letters,
250
+ numbers and spaces, but are _not_ case sensitive:
251
+
252
+ ----
253
+ I start my morning with a cup of coffee and
254
+ [The New York Times][NY Times].
255
+
256
+ [ny times]: http://www.nytimes.com/
257
+ ----
258
+
259
+ .Output:
260
+ ....
261
+ <p>I start my morning with a cup of coffee and
262
+ <a href="http://www.nytimes.com/">The New York Times</a>.</p>
263
+ ....
264
+
265
+ ### Images
266
+
267
+ Image syntax is very much like link syntax.
268
+
269
+ .Inline (titles are optional):
270
+ ----
271
+ ![alt text](/path/to/img.jpg "Title")
272
+ ----
273
+
274
+ .Reference-style:
275
+ ----
276
+ ![alt text][id]
277
+
278
+ [id]: /path/to/img.jpg "Title"
279
+ ----
280
+
281
+ Both of the above examples produce the same output:
282
+
283
+ ....
284
+ <img src="/path/to/img.jpg" alt="alt text" title="Title" />
285
+ ....
286
+
287
+ ### Code
288
+
289
+ In a regular paragraph, you can create code span by wrapping text in
290
+ backtick quotes. Any ampersands (+&+) and angle brackets (+<+ or
291
+ +>+) will automatically be translated into HTML entities. This makes
292
+ it easy to use Markdown to write about HTML example code:
293
+
294
+ ----
295
+ I strongly recommend against using any `<blink>` tags.
296
+
297
+ I wish SmartyPants used named entities like `&mdash;`
298
+ instead of decimal-encoded entites like `&#8212;`.
299
+ ----
300
+
301
+ .Output:
302
+ ....
303
+ <p>I strongly recommend against using any
304
+ <code>&lt;blink&gt;</code> tags.</p>
305
+
306
+ <p>I wish SmartyPants used named entities like
307
+ <code>&amp;mdash;</code> instead of decimal-encoded
308
+ entites like <code>&amp;#8212;</code>.</p>
309
+ ....
310
+
311
+ To specify an entire block of pre-formatted code, indent every line of
312
+ the block by 4 spaces or 1 tab. Just like with code spans, +&+, +<+,
313
+ and +>+ characters will be escaped automatically.
314
+
315
+ .Markdown:
316
+ ----
317
+ If you want your page to validate under XHTML 1.0 Strict,
318
+ you've got to put paragraph tags in your blockquotes:
319
+
320
+ <blockquote>
321
+ <p>For example.</p>
322
+ </blockquote>
323
+ ----
324
+
325
+ .Output:
326
+ ....
327
+ <p>If you want your page to validate under XHTML 1.0 Strict,
328
+ you've got to put paragraph tags in your blockquotes:</p>
329
+
330
+ <pre><code>&lt;blockquote&gt;
331
+ &lt;p&gt;For example.&lt;/p&gt;
332
+ &lt;/blockquote&gt;
333
+ </code></pre>
334
+ ....