Add bin and edit workflow
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 9s

This commit is contained in:
2026-09-16 13:11:16 -06:00
parent c8ac4fcae5
commit 4cee170d66
17576 changed files with 895740 additions and 2 deletions
@@ -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 &nbsp;&auml;&nbsp;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 --- &lt;&lt; typographic &gt;&gt; ... 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 />
&gt; 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.