This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
Count Name
|
||||
======= ====
|
||||
15 Ashwin Maroli <ashmaroli@gmail.com>
|
||||
5 Thomas Leitner <t_leitner@gmx.at>
|
||||
@@ -0,0 +1,21 @@
|
||||
kramdown-parser-gfm
|
||||
Copyright (C) 2019 Thomas Leitner <t_leitner@gmx.at>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1 @@
|
||||
1.1.0
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8; frozen_string_literal: true -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2019 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown-parser-gfm which is licensed under the MIT.
|
||||
#++
|
||||
#
|
||||
|
||||
require_relative 'kramdown/parser/gfm'
|
||||
@@ -0,0 +1,220 @@
|
||||
# -*- coding: utf-8; frozen_string_literal: true -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2019 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown-parser-gfm which is licensed under the MIT.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'kramdown/options'
|
||||
require 'kramdown/parser/kramdown'
|
||||
|
||||
require_relative 'gfm/options'
|
||||
|
||||
module Kramdown
|
||||
module Parser
|
||||
|
||||
# This class provides a parser implementation for the GFM dialect of Markdown.
|
||||
class GFM < Kramdown::Parser::Kramdown
|
||||
|
||||
VERSION = '1.1.0'
|
||||
|
||||
attr_reader :paragraph_end
|
||||
|
||||
def initialize(source, options)
|
||||
super
|
||||
@options[:auto_id_stripping] = true
|
||||
@id_counter = Hash.new(-1)
|
||||
|
||||
@span_parsers.delete(:line_break) if @options[:hard_wrap]
|
||||
@span_parsers.delete(:typographic_syms) if @options[:gfm_quirks].include?(:no_auto_typographic)
|
||||
|
||||
if @options[:gfm_quirks].include?(:paragraph_end)
|
||||
atx_header_parser = :atx_header_gfm_quirk
|
||||
@paragraph_end = self.class::PARAGRAPH_END_GFM
|
||||
else
|
||||
atx_header_parser = :atx_header_gfm
|
||||
@paragraph_end = self.class::PARAGRAPH_END
|
||||
end
|
||||
|
||||
{codeblock_fenced: :codeblock_fenced_gfm,
|
||||
atx_header: atx_header_parser}.each do |current, replacement|
|
||||
i = @block_parsers.index(current)
|
||||
@block_parsers.delete(current)
|
||||
@block_parsers.insert(i, replacement)
|
||||
end
|
||||
|
||||
i = @span_parsers.index(:escaped_chars)
|
||||
@span_parsers[i] = :escaped_chars_gfm if i
|
||||
@span_parsers << :strikethrough_gfm
|
||||
|
||||
@hard_line_break = "#{@options[:hard_wrap] ? '' : '\\'}\n"
|
||||
end
|
||||
|
||||
def parse
|
||||
super
|
||||
update_elements(@root)
|
||||
end
|
||||
|
||||
def update_elements(element)
|
||||
element.children.map! do |child|
|
||||
if child.type == :text && child.value.include?(@hard_line_break)
|
||||
update_text_type(element, child)
|
||||
elsif child.type == :html_element
|
||||
child
|
||||
elsif child.type == :header && @options[:auto_ids] && !child.attr.key?('id')
|
||||
child.attr['id'] = generate_gfm_header_id(child.options[:raw_text])
|
||||
child
|
||||
else
|
||||
update_elements(child)
|
||||
child
|
||||
end
|
||||
end.flatten!
|
||||
end
|
||||
|
||||
# Update the raw text for automatic ID generation.
|
||||
def update_raw_text(item)
|
||||
raw_text = +''
|
||||
|
||||
append_text = lambda do |child|
|
||||
case child.type
|
||||
when :text, :codespan, :math
|
||||
raw_text << child.value
|
||||
when :entity
|
||||
raw_text << child.value.char
|
||||
when :smart_quote
|
||||
raw_text << ::Kramdown::Utils::Entities.entity(child.value.to_s).char
|
||||
when :typographic_sym
|
||||
raw_text << case child.value
|
||||
when :laquo_space
|
||||
"« "
|
||||
when :raquo_space
|
||||
" »"
|
||||
else
|
||||
::Kramdown::Utils::Entities.entity(child.value.to_s).char
|
||||
end
|
||||
else
|
||||
child.children.each { |c| append_text.call(c) }
|
||||
end
|
||||
end
|
||||
|
||||
append_text.call(item)
|
||||
item.options[:raw_text] = raw_text
|
||||
end
|
||||
|
||||
NON_WORD_RE = /[^\p{Word}\- \t]/.freeze
|
||||
|
||||
def generate_gfm_header_id(text)
|
||||
result = text.downcase
|
||||
result.gsub!(NON_WORD_RE, '')
|
||||
result.tr!(" \t", '-')
|
||||
|
||||
@id_counter[result] += 1
|
||||
counter_result = @id_counter[result]
|
||||
result << "-#{counter_result}" if counter_result > 0
|
||||
|
||||
@options[:auto_id_prefix] + result
|
||||
end
|
||||
|
||||
ATX_HEADER_START = /^(?<level>\#{1,6})[\t ]+(?<contents>.*)\n/.freeze
|
||||
define_parser(:atx_header_gfm, ATX_HEADER_START, nil, 'parse_atx_header')
|
||||
define_parser(:atx_header_gfm_quirk, ATX_HEADER_START)
|
||||
|
||||
# Copied from kramdown/parser/kramdown/header.rb, removed the first line
|
||||
def parse_atx_header_gfm_quirk
|
||||
text, id = parse_header_contents
|
||||
text.sub!(/[\t ]#+\z/, '') && text.rstrip!
|
||||
return false if text.empty?
|
||||
|
||||
add_header(@src["level"].length, text, id)
|
||||
true
|
||||
end
|
||||
|
||||
FENCED_CODEBLOCK_START = /^[ ]{0,3}[~`]{3,}/.freeze
|
||||
FENCED_CODEBLOCK_MATCH = /^[ ]{0,3}(([~`]){3,})\s*?((\S+?)(?:\?\S*)?)?\s*?\n(.*?)^[ ]{0,3}\1\2*\s*?\n/m.freeze
|
||||
define_parser(:codeblock_fenced_gfm, FENCED_CODEBLOCK_START, nil, 'parse_codeblock_fenced')
|
||||
|
||||
STRIKETHROUGH_DELIM = /~~/.freeze
|
||||
STRIKETHROUGH_MATCH = /#{STRIKETHROUGH_DELIM}(?!\s|~).*?[^\s~]#{STRIKETHROUGH_DELIM}/m.freeze
|
||||
define_parser(:strikethrough_gfm, STRIKETHROUGH_MATCH, '~~')
|
||||
|
||||
def parse_strikethrough_gfm
|
||||
line_number = @src.current_line_number
|
||||
|
||||
@src.pos += @src.matched_size
|
||||
el = Element.new(:html_element, 'del', {}, category: :span, line: line_number)
|
||||
@tree.children << el
|
||||
|
||||
env = save_env
|
||||
reset_env(src: Kramdown::Utils::StringScanner.new(@src.matched[2..-3], line_number),
|
||||
text_type: :text)
|
||||
parse_spans(el)
|
||||
restore_env(env)
|
||||
|
||||
el
|
||||
end
|
||||
|
||||
LIST_TYPES = [:ul, :ol].freeze
|
||||
|
||||
# To handle task-lists we override the parse method for lists, converting matching text into
|
||||
# checkbox input elements where necessary (as well as applying classes to the ul/ol and li
|
||||
# elements).
|
||||
def parse_list
|
||||
super
|
||||
current_list = @tree.children.select { |element| LIST_TYPES.include?(element.type) }.last
|
||||
|
||||
is_tasklist = false
|
||||
box_unchecked = '<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />'
|
||||
box_checked = '<input type="checkbox" class="task-list-item-checkbox" ' \
|
||||
'disabled="disabled" checked="checked" />'
|
||||
|
||||
current_list.children.each do |li|
|
||||
list_items = li.children
|
||||
next unless !list_items.empty? && list_items[0].type == :p
|
||||
|
||||
# li -> p -> raw_text
|
||||
descendant = list_items[0].children[0].value
|
||||
checked = descendant.gsub!(/\A\s*\[ \]\s+/, box_unchecked)
|
||||
unchecked = descendant.gsub!(/\A\s*\[x\]\s+/i, box_checked)
|
||||
is_tasklist ||= checked || unchecked
|
||||
|
||||
li.attr['class'] = 'task-list-item' if is_tasklist
|
||||
end
|
||||
|
||||
current_list.attr['class'] = 'task-list' if is_tasklist
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
ESCAPED_CHARS_GFM = /\\([\\.*_+`<>()\[\]{}#!:\|"'\$=\-~])/.freeze
|
||||
define_parser(:escaped_chars_gfm, ESCAPED_CHARS_GFM, '\\\\', :parse_escaped_chars)
|
||||
|
||||
PARAGRAPH_END_GFM = Regexp.union(
|
||||
LAZY_END, LIST_START, ATX_HEADER_START, DEFINITION_LIST_START,
|
||||
BLOCKQUOTE_START, FENCED_CODEBLOCK_START
|
||||
)
|
||||
|
||||
private
|
||||
|
||||
def update_text_type(element, child)
|
||||
children = []
|
||||
lines = child.value.split(@hard_line_break, -1)
|
||||
omit_trailing_br = (lines[-1].empty? && Kramdown::Element.category(element) == :block &&
|
||||
element.children[-1] == child)
|
||||
|
||||
lines.each_with_index do |line, index|
|
||||
new_element_options = {location: child.options[:location] + index}
|
||||
children << Element.new(:text, (index > 0 ? "\n#{line}" : line), nil, new_element_options)
|
||||
|
||||
if index < lines.size - 2 || (index == lines.size - 2 && !omit_trailing_br)
|
||||
children << Element.new(:br, nil, nil, new_element_options)
|
||||
end
|
||||
end
|
||||
|
||||
children
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8; frozen_string_literal: true -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2019 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown-parser-gfm which is licensed under the MIT.
|
||||
#++
|
||||
#
|
||||
|
||||
module Kramdown
|
||||
module Options
|
||||
|
||||
define(:hard_wrap, Boolean, true, <<~EOF)
|
||||
Interprets line breaks literally
|
||||
|
||||
Insert HTML `<br />` tags inside paragraphs where the original Markdown
|
||||
document had newlines (by default, Markdown ignores these newlines).
|
||||
|
||||
Default: true
|
||||
Used by: GFM parser
|
||||
EOF
|
||||
|
||||
define(:gfm_quirks, Object, [:paragraph_end], <<~EOF) do |val|
|
||||
Enables a set of GFM specific quirks
|
||||
|
||||
The way how GFM is transformed on Github often differs from the way
|
||||
kramdown does things. Many of these differences are negligible but
|
||||
others are not.
|
||||
|
||||
This option allows one to enable/disable certain GFM quirks, i.e. ways
|
||||
in which GFM parsing differs from kramdown parsing.
|
||||
|
||||
The value has to be a list of quirk names that should be enabled,
|
||||
separated by commas. Possible names are:
|
||||
|
||||
* paragraph_end
|
||||
|
||||
Disables the kramdown restriction that at least one blank line has to
|
||||
be used after a paragraph before a new block element can be started.
|
||||
|
||||
Note that if this quirk is used, lazy line wrapping does not fully
|
||||
work anymore!
|
||||
|
||||
* no_auto_typographic
|
||||
|
||||
Disables automatic conversion of some characters into their
|
||||
corresponding typographic symbols (like `--` to em-dash etc).
|
||||
This helps to achieve results closer to what GitHub Flavored
|
||||
Markdown produces.
|
||||
|
||||
Default: paragraph_end
|
||||
Used by: GFM parser
|
||||
EOF
|
||||
val = simple_array_validator(val, :gfm_quirks)
|
||||
val.map! { |v| str_to_sym(v.to_s) }
|
||||
val
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
#--
|
||||
# Copyright (C) 2019 Thomas Leitner <t_leitner@gmx.at>
|
||||
#
|
||||
# This file is part of kramdown-parser-gfm which is licensed under the MIT.
|
||||
#++
|
||||
#
|
||||
|
||||
require 'minitest/autorun'
|
||||
require 'kramdown'
|
||||
require 'kramdown/parser/gfm'
|
||||
require 'yaml'
|
||||
require 'tmpdir'
|
||||
|
||||
Encoding.default_external = 'utf-8'
|
||||
|
||||
class TestFiles < Minitest::Test
|
||||
|
||||
# Generate test methods for gfm-to-html conversion
|
||||
Dir[__dir__ + '/testcases/**/*.text'].each do |text_file|
|
||||
basename = text_file.sub(/\.text$/, '')
|
||||
|
||||
html_file = basename + '.html'
|
||||
next unless File.exist?(html_file)
|
||||
|
||||
define_method('test_gfm_' + File.basename(text_file, '.*') + '_to_html') do
|
||||
opts_file = basename + '.options'
|
||||
opts_file = File.join(File.dirname(html_file), 'options') if !File.exist?(opts_file)
|
||||
options = File.exist?(opts_file) ? YAML::load(File.read(opts_file)) : {auto_ids: false, footnote_nr: 1}
|
||||
doc = Kramdown::Document.new(File.read(text_file), options.merge(input: 'GFM'))
|
||||
assert_equal(File.read(html_file), doc.to_html)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
<h1>header</h1>
|
||||
|
||||
<p>#no header</p>
|
||||
@@ -0,0 +1,3 @@
|
||||
# header
|
||||
|
||||
#no header
|
||||
@@ -0,0 +1,14 @@
|
||||
<pre><code>Three backticks
|
||||
</code></pre>
|
||||
|
||||
<pre><code>Four backticks
|
||||
</code></pre>
|
||||
|
||||
<pre><code>Unbalanced bottom heavy
|
||||
</code></pre>
|
||||
|
||||
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">language</span> <span class="n">no</span> <span class="n">space</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">language</span> <span class="n">with</span> <span class="n">space</span>
|
||||
</code></pre></div></div>
|
||||
@@ -0,0 +1 @@
|
||||
:enable_coderay: false
|
||||
@@ -0,0 +1,19 @@
|
||||
```
|
||||
Three backticks
|
||||
```
|
||||
|
||||
````
|
||||
Four backticks
|
||||
````
|
||||
|
||||
```
|
||||
Unbalanced bottom heavy
|
||||
``````
|
||||
|
||||
````ruby
|
||||
language no space
|
||||
````
|
||||
|
||||
```` ruby
|
||||
language with space
|
||||
````
|
||||
@@ -0,0 +1,20 @@
|
||||
<p>normal</p>
|
||||
|
||||
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s1">'kramdown'</span>
|
||||
|
||||
<span class="no">Kramdown</span><span class="o">::</span><span class="no">Document</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">text</span><span class="p">).</span><span class="nf">to_html</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>indent with tab</p>
|
||||
|
||||
<pre><code>```ruby
|
||||
require 'kramdown'
|
||||
|
||||
Kramdown::Document.new(text).to_html
|
||||
```
|
||||
</code></pre>
|
||||
|
||||
<p>indent with 2 spaces</p>
|
||||
|
||||
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">);</span>
|
||||
</code></pre></div></div>
|
||||
@@ -0,0 +1 @@
|
||||
:enable_coderay: false
|
||||
@@ -0,0 +1,21 @@
|
||||
normal
|
||||
|
||||
```ruby
|
||||
require 'kramdown'
|
||||
|
||||
Kramdown::Document.new(text).to_html
|
||||
```
|
||||
|
||||
indent with tab
|
||||
|
||||
```ruby
|
||||
require 'kramdown'
|
||||
|
||||
Kramdown::Document.new(text).to_html
|
||||
```
|
||||
|
||||
indent with 2 spaces
|
||||
|
||||
```js
|
||||
console.log("hello");
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
<p>one<br />
|
||||
<em>two</em><br />
|
||||
three</p>
|
||||
@@ -0,0 +1,3 @@
|
||||
one
|
||||
_two_
|
||||
three
|
||||
@@ -0,0 +1,5 @@
|
||||
<p>This is just a normal paragraph.<br />
|
||||
Containing a manual line break above.</p>
|
||||
|
||||
<p>It was the best of times,<br />
|
||||
it was the worst of times.</p>
|
||||
@@ -0,0 +1 @@
|
||||
:hard_wrap: false
|
||||
@@ -0,0 +1,5 @@
|
||||
This is just a normal paragraph.
|
||||
Containing a manual line break above.
|
||||
|
||||
It was the best of times,\
|
||||
it was the worst of times.
|
||||
@@ -0,0 +1,27 @@
|
||||
<h3 id="myid">test</h3>
|
||||
|
||||
<h3 id="variable_name">variable_name</h3>
|
||||
|
||||
<h3 id="abc-def-öúß">abc def öúß</h3>
|
||||
|
||||
<h3 id="192-abc-192">192 abc 192</h3>
|
||||
|
||||
<h3>;.;;</h3>
|
||||
|
||||
<h3 id="variable_name-1">variable_name</h3>
|
||||
|
||||
<h3 id="variable_name-2">variable_name</h3>
|
||||
|
||||
<h3 id="-1">;;</h3>
|
||||
|
||||
<h3 id="before--after-tab">before after tab</h3>
|
||||
|
||||
<h3 id="with-code">with <code>code</code></h3>
|
||||
|
||||
<h3 id="with-äspace">with ä space</h3>
|
||||
|
||||
<h3 id="with-smart-quotes">With “smart” quotes</h3>
|
||||
|
||||
<h3 id="with--typographic--symbols">with — « typographic » … symbols</h3>
|
||||
|
||||
<h3 id="with-m5">with <script type="math/tex">m=5</script></h3>
|
||||
@@ -0,0 +1 @@
|
||||
:auto_ids: true
|
||||
@@ -0,0 +1,27 @@
|
||||
### test {#myid}
|
||||
|
||||
### variable_name
|
||||
|
||||
### abc def öúß
|
||||
|
||||
### 192 abc 192
|
||||
|
||||
### ;.;;
|
||||
|
||||
### variable_name
|
||||
|
||||
### variable_name
|
||||
|
||||
### ;;
|
||||
|
||||
### before after tab
|
||||
|
||||
### with `code`
|
||||
|
||||
### with ä space
|
||||
|
||||
### With "smart" quotes
|
||||
|
||||
### with --- << typographic >> ... symbols
|
||||
|
||||
### with $$m=5$$
|
||||
@@ -0,0 +1,3 @@
|
||||
<h1 id="hallo-header-1">Header 1</h1>
|
||||
|
||||
<h1 id="hallo-123">123</h1>
|
||||
@@ -0,0 +1,2 @@
|
||||
:auto_ids: true
|
||||
:auto_id_prefix: hallo-
|
||||
@@ -0,0 +1,3 @@
|
||||
# Header 1
|
||||
|
||||
# 123
|
||||
@@ -0,0 +1,3 @@
|
||||
<h3 id="header-with---ndash">Header with --ndash</h3>
|
||||
|
||||
<h3 id="with------typographic---symbols">with --- << typographic >> ... symbols</h3>
|
||||
@@ -0,0 +1 @@
|
||||
:gfm_quirks: [no_auto_typographic]
|
||||
@@ -0,0 +1,3 @@
|
||||
### Header with --ndash
|
||||
|
||||
### with --- << typographic >> ... symbols
|
||||
@@ -0,0 +1,31 @@
|
||||
<p>A<br />
|
||||
- b</p>
|
||||
|
||||
<p>This is a list<br />
|
||||
- or is it</p>
|
||||
|
||||
<p>blockquote<br />
|
||||
> text</p>
|
||||
|
||||
<p>header<br />
|
||||
# text</p>
|
||||
|
||||
<p>codeblock fenced<br />
|
||||
<code>
|
||||
puts hello world
|
||||
</code></p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>level 1<br />
|
||||
some text</p>
|
||||
|
||||
<p>begin level 2<br />
|
||||
* level 2<br />
|
||||
* level 2</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h1 id="h1">h1</h1>
|
||||
<p>## h2<br />
|
||||
### h3</p>
|
||||
@@ -0,0 +1 @@
|
||||
:gfm_quirks: []
|
||||
@@ -0,0 +1,27 @@
|
||||
A
|
||||
- b
|
||||
|
||||
This is a list
|
||||
- or is it
|
||||
|
||||
blockquote
|
||||
> text
|
||||
|
||||
header
|
||||
# text
|
||||
|
||||
codeblock fenced
|
||||
```
|
||||
puts hello world
|
||||
```
|
||||
|
||||
* level 1
|
||||
some text
|
||||
|
||||
begin level 2
|
||||
* level 2
|
||||
* level 2
|
||||
|
||||
# h1
|
||||
## h2
|
||||
### h3
|
||||
@@ -0,0 +1,38 @@
|
||||
<p>A</p>
|
||||
<ul>
|
||||
<li>b</li>
|
||||
</ul>
|
||||
|
||||
<p>This is a list</p>
|
||||
<ul>
|
||||
<li>or is it</li>
|
||||
</ul>
|
||||
|
||||
<p>blockquote</p>
|
||||
<blockquote>
|
||||
<p>text</p>
|
||||
</blockquote>
|
||||
|
||||
<p>header</p>
|
||||
<h1>text</h1>
|
||||
|
||||
<p>codeblock fenced</p>
|
||||
<pre><code>puts hello world
|
||||
</code></pre>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>level 1<br />
|
||||
some text</p>
|
||||
|
||||
<p>begin level 2</p>
|
||||
<ul>
|
||||
<li>level 2</li>
|
||||
<li>level 2</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h1>h1</h1>
|
||||
<h2>h2</h2>
|
||||
<h3>h3</h3>
|
||||
@@ -0,0 +1,27 @@
|
||||
A
|
||||
- b
|
||||
|
||||
This is a list
|
||||
- or is it
|
||||
|
||||
blockquote
|
||||
> text
|
||||
|
||||
header
|
||||
# text
|
||||
|
||||
codeblock fenced
|
||||
```
|
||||
puts hello world
|
||||
```
|
||||
|
||||
* level 1
|
||||
some text
|
||||
|
||||
begin level 2
|
||||
* level 2
|
||||
* level 2
|
||||
|
||||
# h1
|
||||
## h2
|
||||
### h3
|
||||
@@ -0,0 +1,33 @@
|
||||
<p><del>This is a test</del></p>
|
||||
|
||||
<p>~<del>This is another test</del>~</p>
|
||||
|
||||
<p><del>This is yet another test</del>~</p>
|
||||
|
||||
<p>~~ This is a test of it NOT working ~~</p>
|
||||
|
||||
<p>~~<br />
|
||||
This<br />
|
||||
is<br />
|
||||
a<br />
|
||||
<strong>multiline</strong><br />
|
||||
test<br />
|
||||
~~</p>
|
||||
|
||||
<p>This is an <del><em>inline</em> <strong>strikethrough</strong></del> test</p>
|
||||
|
||||
<p>This is an ~~escaped~~ strikethrough.</p>
|
||||
|
||||
<p>This is a <del>strikethrough with a ~ in the middle</del></p>
|
||||
|
||||
<p>I <del>don’t even</del>~ have an extra tilde.</p>
|
||||
|
||||
<p>This should ~~not be struck.</p>
|
||||
|
||||
<p>This <del>is a complex <em>strike</em> through *test ~~with nesting</del> involved* here~~.</p>
|
||||
|
||||
<p>This <del>is a complex <em>strike</em> through *test</del> with apparent nesting <del>involved* here</del>.</p>
|
||||
|
||||
<p><del>中文</del></p>
|
||||
|
||||
<p><del>a</del></p>
|
||||
@@ -0,0 +1,33 @@
|
||||
~~This is a test~~
|
||||
|
||||
~~~This is another test~~~
|
||||
|
||||
~~This is yet another test~~~
|
||||
|
||||
~~ This is a test of it NOT working ~~
|
||||
|
||||
~~
|
||||
This
|
||||
is
|
||||
a
|
||||
**multiline**
|
||||
test
|
||||
~~
|
||||
|
||||
This is an ~~_inline_ **strikethrough**~~ test
|
||||
|
||||
This is an \~~escaped~~ strikethrough.
|
||||
|
||||
This is a ~~strikethrough with a ~ in the middle~~
|
||||
|
||||
I ~~don't even~~~ have an extra tilde.
|
||||
|
||||
This should ~~not be struck.
|
||||
|
||||
This ~~is a complex *strike* through *test ~~with nesting~~ involved* here~~.
|
||||
|
||||
This ~~is a complex *strike* through *test~~ with apparent nesting ~~involved* here~~.
|
||||
|
||||
~~中文~~
|
||||
|
||||
~~a~~
|
||||
@@ -0,0 +1,40 @@
|
||||
<p>unordered task list</p>
|
||||
|
||||
<ul class="task-list">
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />first ul task item</li>
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />second ul task item</li>
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />third ul task item</li>
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />fourth ul task item [ ] next</li>
|
||||
</ul>
|
||||
|
||||
<p>unordered list</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<blockquote>
|
||||
<p>first ul item</p>
|
||||
</blockquote>
|
||||
</li>
|
||||
<li></li>
|
||||
<li>
|
||||
<pre><code>test
|
||||
</code></pre>
|
||||
</li>
|
||||
<li>second ul item</li>
|
||||
</ul>
|
||||
|
||||
<p>ordered list</p>
|
||||
|
||||
<ol>
|
||||
<li>first ol item</li>
|
||||
<li>second ol item</li>
|
||||
</ol>
|
||||
|
||||
<p>ordered task list</p>
|
||||
|
||||
<ol class="task-list">
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />first ol task item</li>
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />second ol task item</li>
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />third ol task item</li>
|
||||
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />fourth ol task item</li>
|
||||
</ol>
|
||||
@@ -0,0 +1,26 @@
|
||||
unordered task list
|
||||
|
||||
- [ ] first ul task item
|
||||
- [x] second ul task item
|
||||
- [X] third ul task item
|
||||
- [ ] fourth ul task item [ ] next
|
||||
|
||||
unordered list
|
||||
|
||||
- > first ul item
|
||||
-
|
||||
-
|
||||
test
|
||||
- second ul item
|
||||
|
||||
ordered list
|
||||
|
||||
1. first ol item
|
||||
2. second ol item
|
||||
|
||||
ordered task list
|
||||
|
||||
1. [ ] first ol task item
|
||||
2. [x] second ol task item
|
||||
3. [X] third ol task item
|
||||
4. [ ] fourth ol task item
|
||||
@@ -0,0 +1,4 @@
|
||||
<p>This is just a normal paragraph. <br />
|
||||
Containing a line break.</p>
|
||||
|
||||
<p>Another paragraph.</p>
|
||||
@@ -0,0 +1,4 @@
|
||||
This is just a normal paragraph.
|
||||
Containing a line break.
|
||||
|
||||
Another paragraph.
|
||||
Reference in New Issue
Block a user