Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ameba-version: [v1.6.4]
ameba-version: [v1.7.0]
name: Ameba ${{ matrix.ameba-version }} linter check
steps:
- name: Install latest Crystal
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
crystal: ${{ matrix.crystal }}

- name: Install dependencies
run: shards install --without-development
run: shards install

- name: Run specs
run: crystal spec --error-on-warnings --error-trace
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
/.shards/
/src/main.cr

# Compiled spec binary
/markd_spec

# Libraries don't need dependency lock
# Dependencies will be locked in application that uses them
/shard.lock

# vscode
/.history/
/.vscode/settings.json
/.vscode/


# claude
CLAUDE.md
/.claude/
13 changes: 0 additions & 13 deletions .vscode/launch.json

This file was deleted.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ Markd.to_html(markdown, options)
| source_pos | `Bool` | false | if **true**, source position information for block-level elements<br />will be rendered in the data-sourcepos attribute (for HTML) |
| safe | `Bool` | false | if **true**, raw HTML will not be passed through to HTML output (it will be replaced by comments) |
| prettyprint | `Bool` | false | if **true**, code tags generated by code blocks will have a `prettyprint` class added to them, to be used by [Google code-prettify](https://github.com/google/code-prettify). |
| gfm | `Bool` | false | **Partial support** |
| autolink | `Bool` | false | if **true**, more autolinks are detected, like bare email addresses or http links |
| gfm | `Bool` | false | **Partial support** |
| autolink | `Bool` | false | if **true**, more autolinks are detected, like bare email addresses or http links |
| toc | `Bool` | false | **Not supported for now** |
| emoji | `Bool` | false | if **true**, convert Github style emoji chars. |
| tagfilter | `Bool` | false | if **true**, escape certain HTML tags. |
Expand Down
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: markd
version: 0.6.0

development_dependencies:
tartrazine :
tartrazine:
github: ralsina/tartrazine

authors:
Expand Down
51 changes: 48 additions & 3 deletions spec/fixtures/gfm-extensions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ Even with {"x":"y"} or 1 > 2 or whatever. Even **markdown**.

## Footnotes

```````````````````````````````` example pending
```````````````````````````````` example
This is some text![^1]. Other text.[^footnote].

Here's a thing[^other-note].
Expand Down Expand Up @@ -762,9 +762,54 @@ Hi!
</section>
````````````````````````````````

Multibyte characters before a reference must not shift its label:
the parser tracks byte offsets but the label used to be cut with
character-based slicing.

```````````````````````````````` example
Emoji ✅[^emoji] and accented é[^accent].

| Tables | Cells |
| ------ | ----- |
| emoji | ✅[^t-emoji] |

[^emoji]: emoji note
[^accent]: accent note
[^t-emoji]: table note
.
<p>Emoji ✅<sup class="footnote-ref"><a href="#fn-emoji" id="fnref-emoji" data-footnote-ref>1</a></sup> and accented é<sup class="footnote-ref"><a href="#fn-accent" id="fnref-accent" data-footnote-ref>2</a></sup>.</p>
<table>
<thead>
<tr>
<th>Tables</th>
<th>Cells</th>
</tr>
</thead>
<tbody>
<tr>
<td>emoji</td>
<td>✅<sup class="footnote-ref"><a href="#fn-t-emoji" id="fnref-t-emoji" data-footnote-ref>3</a></sup></td>
</tr>
</tbody>
</table>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-emoji">
<p>emoji note <a href="#fnref-emoji" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-accent">
<p>accent note <a href="#fnref-accent" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-t-emoji">
<p>table note <a href="#fnref-t-emoji" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
</ol>
</section>
````````````````````````````````

## When a footnote is used multiple times, we insert multiple backrefs.

```````````````````````````````` example pending
```````````````````````````````` example
This is some text. It has a footnote[^a-footnote].

This footnote is referenced[^a-footnote] multiple times, in lots of different places.[^a-footnote]
Expand All @@ -784,7 +829,7 @@ This footnote is referenced[^a-footnote] multiple times, in lots of different pl

## Footnote reference labels are href escaped

```````````````````````````````` example pending
```````````````````````````````` example
Hello[^"><script>alert(1)</script>]

[^"><script>alert(1)</script>]: pwned
Expand Down
63 changes: 57 additions & 6 deletions spec/fixtures/gfm-regression.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ This ~text~ ~~is~~ ~~~curious~~~.

Footnotes in tables

```````````````````````````````` example table footnotes pending
```````````````````````````````` example table footnotes
A footnote in a paragraph[^1]

| Column1 | Column2 |
Expand Down Expand Up @@ -273,7 +273,7 @@ Pull request #128 - Buffer overread in tables extension

Footnotes may be nested inside other footnotes.

```````````````````````````````` example footnotes pending
```````````````````````````````` example footnotes
This is some text. It has a citation.[^citation]

[^another-citation]: My second citation.
Expand All @@ -295,7 +295,7 @@ This is some text. It has a citation.[^citation]

Footnotes are similar to, but should not be confused with, link references

```````````````````````````````` example footnotes pending
```````````````````````````````` example footnotes
This is some text. It has two footnotes references, side-by-side without any spaces,[^footnote1][^footnote2] which are definitely not link references.

[^footnote1]: Hello.
Expand All @@ -317,7 +317,7 @@ This is some text. It has two footnotes references, side-by-side without any spa

Footnotes may begin with or have a 'w' or a '_' in their reference label.

```````````````````````````````` example footnotes autolink pending
```````````````````````````````` example footnotes autolink
This is some text. Sometimes the autolinker splits up text into multiple nodes, hoping it will find a hyperlink, so this text has a footnote whose reference label begins with a `w`.[^widely-cited]

It has another footnote that contains many different characters (the autolinker was also breaking on `_`).[^sphinx-of-black-quartz_judge-my-vow-0123456789]
Expand All @@ -342,15 +342,17 @@ It has another footnote that contains many different characters (the autolinker

Footnotes interacting with strikethrough should not lead to a use-after-free

```````````````````````````````` example footnotes autolink strikethrough table pending

```````````````````````````````` example footnotes autolink strikethrough table
|Tot.....[^_a_]|
.
<p>|Tot.....[^_a_]|</p>
````````````````````````````````

Footnotes interacting with strikethrough should not lead to a use-after-free pt2

```````````````````````````````` example footnotes autolink strikethrough table pending

```````````````````````````````` example footnotes autolink strikethrough table
[^~~is~~1]
.
<p>[^~~is~~1]</p>
Expand All @@ -374,3 +376,52 @@ Issue #424 - emphasis before links
.
<p><em>text</em> <a href="#section">link</a></p>
````````````````````````````````

A footnote reference followed by (parentheses) is not parsed as a link

```````````````````````````````` example footnotes
Text with a footnote[^a], and [^a](url) with a link-ish suffix.

[^a]: note one
.
<p>Text with a footnote<sup class="footnote-ref"><a href="#fn-a" id="fnref-a" data-footnote-ref>1</a></sup>, and <sup class="footnote-ref"><a href="#fn-a" id="fnref-a-2" data-footnote-ref>1</a></sup>(url) with a link-ish suffix.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-a">
<p>note one <a href="#fnref-a" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a> <a href="#fnref-a-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1-2" aria-label="Back to reference 1-2">↩<sup class="footnote-ref">2</sup></a></p>
</li>
</ol>
</section>
````````````````````````````````

Footnote definitions must start at the beginning of the line

```````````````````````````````` example footnotes
foo [^b]: this is mid-line, so not a definition

[^b]: real note
.
<p>foo [^b]: this is mid-line, so not a definition</p>
````````````````````````````````

Nested footnote references may contain arbitrary characters

```````````````````````````````` example footnotes
See[^one].

[^one]: outer [^"><script>x</script>]

[^"><script>x</script>]: inner note
.
<p>See<sup class="footnote-ref"><a href="#fn-one" id="fnref-one" data-footnote-ref>1</a></sup>.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-one">
<p>outer <sup class="footnote-ref"><a href="#fn-%22%3E%3Cscript%3Ex%3C/script%3E" id="fnref-%22%3E%3Cscript%3Ex%3C/script%3E" data-footnote-ref>2</a></sup> <a href="#fnref-one" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-%22%3E%3Cscript%3Ex%3C/script%3E">
<p>inner note <a href="#fnref-%22%3E%3Cscript%3Ex%3C/script%3E" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
</ol>
</section>
````````````````````````````````
8 changes: 4 additions & 4 deletions spec/fixtures/tartrazine.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ require "tartrazine"
require "../../src/markd"

markdown = <<-MD
# Hello Markd
# Hello Markd

> Yet another markdown parser built for speed, written in Crystal, Compliant to CommonMark specification.
MD
> Yet another markdown parser built for speed, written in Crystal, Compliant to CommonMark specification.
MD

html = Markd.to_html(markdown)
Markd.to_html(markdown)
54 changes: 28 additions & 26 deletions src/markd/node.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,58 @@ module Markd
class Node
# Node Type
enum Type
Document
Paragraph
Text
Strong
Emphasis
Strikethrough
Link
Image
Heading
List
Item
BlockQuote
Alert
ThematicBreak
Code
CodeBlock
CustomBlock
CustomInLine
Document
Emphasis
Footnote
FootnoteDefinition
Heading
HTMLBlock
HTMLInline
Image
Item
LineBreak
Link
List
Paragraph
SoftBreak

CustomInLine
CustomBlock
Strikethrough
Strong
Table
TableCell
TableRow
Text

def container?
CONTAINER_TYPES.includes?(self)
end
end

CONTAINER_TYPES = {
Type::BlockQuote,
Type::Alert,
Type::CustomBlock,
Type::CustomInLine,
Type::Document,
Type::Paragraph,
Type::Strong,
Type::Emphasis,
Type::Strikethrough,
Type::Link,
Type::Image,
Type::FootnoteDefinition,
Type::Heading,
Type::List,
Type::Image,
Type::Item,
Type::BlockQuote,
Type::Alert,
Type::CustomInLine,
Type::CustomBlock,
Type::Link,
Type::List,
Type::Paragraph,
Type::Strikethrough,
Type::Strong,
Type::Table,
Type::TableRow,
Type::TableCell,
Type::TableRow,
}

alias DataValue = String | Int32 | Bool
Expand Down Expand Up @@ -132,7 +134,7 @@ module Markd
end

def to_s(io : IO)
io << "#<" << {{@type.name.id.stringify}} << ":0x"
io << "#<" << {{ @type.name.id.stringify }} << ":0x"
object_id.to_s(16, io)
io << " @type=" << @type
io << " @parent=" << @parent if @parent
Expand Down
Loading
Loading