raindown 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/elements.rb +25 -0
- data/lib/nodes/component_nodes.rb +38 -0
- data/lib/nodes/endpoint_node.rb +4 -2
- data/lib/raindown/fragments.rb +35 -0
- data/lib/raindown/heading_ids.rb +25 -0
- data/lib/raindown/page.rb +8 -3
- data/lib/raindown/pages.rb +9 -3
- data/lib/raindown/pre_renderer.rb +7 -16
- data/lib/raindown/rewriter.rb +1 -1
- data/lib/raindown/toc.rb +16 -4
- data/lib/raindown.rb +22 -24
- data/lib/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0e77b47d4bdedcda5ace520aff8dabc470b3d49a9d7f2dac83b43d23d0928c2
|
|
4
|
+
data.tar.gz: 0e26371c232241abfcfbaec62a09eb89445299fdd5e4d67273a9c0839bb1982a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 917089b01769a65e0b96d645613f182fdbd7212760823293ed87dd1581071751f53548bdc84d363c40e5a50d4c4941c10f6a409ded7dd2c5687708581dcd9213
|
|
7
|
+
data.tar.gz: 1ae3a21d68f7bb6fd7042e371cec3352eb7e1781855dcf3a5c92b80c1024a628481c2a3f159be9ee6fb1769592169640f5d767989aadf29bfbadba76ab610849
|
data/lib/elements.rb
CHANGED
|
@@ -6,6 +6,31 @@ module Raindown
|
|
|
6
6
|
class Elements
|
|
7
7
|
include Plugs
|
|
8
8
|
|
|
9
|
+
# Antlers' prop and slot directives, rendered as components in the template pass.
|
|
10
|
+
plug(:prop_component) do
|
|
11
|
+
plug(:lexeme) do
|
|
12
|
+
require 'lexemes/prop_lexeme'
|
|
13
|
+
Antlers::PropLexeme
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
plug(:node) do
|
|
17
|
+
require_relative 'nodes/component_nodes'
|
|
18
|
+
PropComponentNode
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
plug(:slot_component) do
|
|
23
|
+
plug(:lexeme) do
|
|
24
|
+
require 'lexemes/slot_lexeme'
|
|
25
|
+
Antlers::SlotLexeme
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
plug(:node) do
|
|
29
|
+
require_relative 'nodes/component_nodes'
|
|
30
|
+
SlotComponentNode
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
9
34
|
plug(:endpoint) do
|
|
10
35
|
plug(:lexeme) do
|
|
11
36
|
require_relative 'lexemes/endpoint_lexeme'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'antlers/api'
|
|
4
|
+
require 'nodes/html_node'
|
|
5
|
+
require 'nodes/prop_node'
|
|
6
|
+
require 'nodes/slot_node'
|
|
7
|
+
require_relative '../raindown/fragments'
|
|
8
|
+
|
|
9
|
+
module Raindown
|
|
10
|
+
# <{ Card name=p.name }>, rendered by Antlers where it is in the template, so its props see loop variables.
|
|
11
|
+
# Its HTML is kept as a fragment, so Commonmarker doesn't read it as Markdown.
|
|
12
|
+
class PropComponentNode < Antlers::PropNode
|
|
13
|
+
def render(**)
|
|
14
|
+
Fragments.add(super)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# <{ Card: }>...<{ :Card }>, whose slot is its own Markdown, rendered to HTML in its scope first.
|
|
19
|
+
#
|
|
20
|
+
# Markdown children -> rendered to a Markdown string -> Commonmarker -> HTML
|
|
21
|
+
# -> wrapped as a single Antlers::HTMLNode (replaces @children for the super call)
|
|
22
|
+
# -> Antlers::SlotNode#render's "without a template" branch -> slot: receives that HTML
|
|
23
|
+
# -> Card#render(slot:, **props)
|
|
24
|
+
#
|
|
25
|
+
# This only reaches Card#render directly when Card has no class-level template (see SlotNode#render);
|
|
26
|
+
# otherwise Antlers renders Card's own template instead, with this HTML passed to it as the slot_node.
|
|
27
|
+
class SlotComponentNode < Antlers::SlotNode
|
|
28
|
+
def render(current_binding: nil, parent_binding: nil, slot_node: nil, metadata: {})
|
|
29
|
+
markdown = @children.map { |child| child.render(current_binding:, parent_binding:, slot_node:, metadata:) || '' }.join
|
|
30
|
+
children = @children
|
|
31
|
+
@children = [Antlers::HTMLNode.new(html: Raindown.commonmark(markdown))]
|
|
32
|
+
|
|
33
|
+
Fragments.add(super)
|
|
34
|
+
ensure
|
|
35
|
+
@children = children if children
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/nodes/endpoint_node.rb
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
require 'antlers/api'
|
|
4
4
|
require_relative '../raindown/directives'
|
|
5
|
+
require_relative '../raindown/fragments'
|
|
5
6
|
|
|
6
7
|
module Raindown
|
|
7
8
|
# Holds an endpoint's curl snippet and response, which render as the code blocks they are,
|
|
8
|
-
# between Directives markers for its directive and end tag.
|
|
9
|
+
# between Directives markers for its directive and end tag, kept as a fragment.
|
|
9
10
|
class EndpointNode < Antlers::BranchNode
|
|
10
11
|
DEF_KEY = :endpoint_def
|
|
11
12
|
END_KEY = :endpoint_end
|
|
@@ -17,7 +18,8 @@ module Raindown
|
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def render(**)
|
|
20
|
-
|
|
21
|
+
html = Raindown.commonmark(super)
|
|
22
|
+
Fragments.add("#{Directives.marker(@directive)}\n#{html}#{Directives.marker(':endpoint')}")
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
class << self
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Raindown
|
|
4
|
+
# The HTML of components rendered while a document renders, kept out of its Markdown as placeholders
|
|
5
|
+
# so Commonmarker doesn't read it as Markdown, then filled in once the document is HTML.
|
|
6
|
+
module Fragments
|
|
7
|
+
PLACEHOLDER = /<!-- raindown:fragment (\d+) -->/
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
# Collects the fragments added while the block runs, like one document's render.
|
|
12
|
+
def collect
|
|
13
|
+
outer = Thread.current[:raindown_fragments]
|
|
14
|
+
Thread.current[:raindown_fragments] = []
|
|
15
|
+
yield
|
|
16
|
+
ensure
|
|
17
|
+
Thread.current[:raindown_fragments] = outer
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add(html)
|
|
21
|
+
list << html
|
|
22
|
+
"<!-- raindown:fragment #{list.length - 1} -->"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Fills each placeholder, again and again, since a fragment can hold others, like a component in a slot.
|
|
26
|
+
def fill(html)
|
|
27
|
+
html = html.gsub(PLACEHOLDER) { list[::Regexp.last_match(1).to_i] } while html.match?(PLACEHOLDER)
|
|
28
|
+
html
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def list
|
|
32
|
+
Thread.current[:raindown_fragments] ||= []
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Raindown
|
|
4
|
+
# Commonmarker gives each heading a unique id within what it renders, but a document's components render
|
|
5
|
+
# on their own, so two can have a heading with the same id. Later ones get -1, -2 and so on, like Commonmarker.
|
|
6
|
+
module HeadingIds
|
|
7
|
+
HEADING = %r{<h([1-6]) id="([^"]*)"(.*?)</h\1>}m
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def unique(html)
|
|
12
|
+
seen = Hash.new(0)
|
|
13
|
+
|
|
14
|
+
html.gsub(HEADING) do
|
|
15
|
+
level, id, rest = ::Regexp.last_match.captures
|
|
16
|
+
count = seen[id]
|
|
17
|
+
seen[id] += 1
|
|
18
|
+
next ::Regexp.last_match(0) if count.zero?
|
|
19
|
+
|
|
20
|
+
unique_id = "#{id}-#{count}"
|
|
21
|
+
"<h#{level} id=\"#{unique_id}\"#{rest.gsub("href=\"##{id}\"", "href=\"##{unique_id}\"")}</h#{level}>"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/raindown/page.rb
CHANGED
|
@@ -6,16 +6,21 @@ module Raindown
|
|
|
6
6
|
class Page
|
|
7
7
|
attr_reader :file_path, :metadata
|
|
8
8
|
|
|
9
|
-
def initialize(file_path:, metadata:)
|
|
9
|
+
def initialize(file_path:, metadata:, render_options: {})
|
|
10
10
|
@file_path = file_path
|
|
11
11
|
@metadata = metadata
|
|
12
|
+
@render_options = render_options
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
# Rendered when asked for, so a file that lists itself doesn't render forever.
|
|
16
|
+
# The front matter is rendered with it, so its variables work, and a Raindown file's bare directives too.
|
|
15
17
|
def content
|
|
16
18
|
@content ||= begin
|
|
17
|
-
markdown =
|
|
18
|
-
|
|
19
|
+
markdown = File.read(file_path, encoding: Encoding::UTF_8)
|
|
20
|
+
|
|
21
|
+
if FrontMatter.parse(markdown).last.strip.empty? then ''
|
|
22
|
+
else Raindown.render(markdown:, bare: BareDirectives.file?(file_path), **@render_options)
|
|
23
|
+
end
|
|
19
24
|
end
|
|
20
25
|
end
|
|
21
26
|
|
data/lib/raindown/pages.rb
CHANGED
|
@@ -31,8 +31,10 @@ module Raindown
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
# Render options, like hide_directives: true, are for rendering each listed file's content.
|
|
35
|
+
def initialize(metadata:, root:, render_options: {})
|
|
35
36
|
@root = root
|
|
37
|
+
@render_options = render_options
|
|
36
38
|
@file_paths = metadata.file_types.values_at(*EXTENSIONS).flatten.compact
|
|
37
39
|
@metadata = {}
|
|
38
40
|
@tags = {}
|
|
@@ -44,7 +46,7 @@ module Raindown
|
|
|
44
46
|
# Without tags, every file.
|
|
45
47
|
def list(**tags)
|
|
46
48
|
file_paths = tags.empty? ? @file_paths : tagged(**tags)
|
|
47
|
-
file_paths.sort_by { |file_path| sort_key(file_path) }.map { |file_path|
|
|
49
|
+
file_paths.sort_by { |file_path| sort_key(file_path) }.map { |file_path| listed_page(file_path) }
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
def tagged(**tags)
|
|
@@ -53,8 +55,12 @@ module Raindown
|
|
|
53
55
|
|
|
54
56
|
private
|
|
55
57
|
|
|
58
|
+
def listed_page(file_path)
|
|
59
|
+
Page.new(file_path:, metadata: @metadata[file_path], render_options: @render_options)
|
|
60
|
+
end
|
|
61
|
+
|
|
56
62
|
def process(file_path:)
|
|
57
|
-
metadata = implicit_metadata(file_path:).merge(FrontMatter.parse(File.read(file_path)).first)
|
|
63
|
+
metadata = implicit_metadata(file_path:).merge(FrontMatter.parse(File.read(file_path, encoding: Encoding::UTF_8)).first)
|
|
58
64
|
@metadata[file_path] = metadata
|
|
59
65
|
metadata.each { |type, tag| Array(tag).each { |item| tag(type:, tag: item, file_path:) } }
|
|
60
66
|
end
|
|
@@ -10,14 +10,12 @@ module Raindown
|
|
|
10
10
|
# Renders the directives whose output is Markdown, before Commonmarker reads it: variables, loops, conditions and lists.
|
|
11
11
|
# So a loop's items become one Markdown list or table, and a heading's id and its entry in a table of contents
|
|
12
12
|
# come from its text, like "# Notes for {name}" becoming "Notes for Mark" with the id "notes-for-mark".
|
|
13
|
-
# Nodes like toc: and files: render before this
|
|
13
|
+
# Nodes like toc: and files: render before this. Components and endpoints render here too, as fragments of HTML
|
|
14
|
+
# that Raindown puts back once the document is HTML.
|
|
14
15
|
module PreRenderer
|
|
15
16
|
BLOCK_DIRECTIVES = %w[for if list].freeze
|
|
16
|
-
# A variable like <{ title }> or a for, if or list directive, which render here.
|
|
17
|
-
DIRECTIVE = /<\{\s*(?:(?:#{BLOCK_DIRECTIVES.join('|')}):[^}]*|:(?:#{BLOCK_DIRECTIVES.join('|')})|[@\w.]+)\s*\}>/
|
|
18
17
|
# A for, if or list directive alone on its line, which leaves no line behind, so a loop's list items stay together.
|
|
19
18
|
BLOCK_LINE = /^[ \t]*(<\{\s*:?(?:#{BLOCK_DIRECTIVES.join('|')})\b[^}]*\}>)[ \t]*\n/
|
|
20
|
-
HIDDEN = /\u{E002}(\d+)\u{E003}/
|
|
21
19
|
|
|
22
20
|
module_function
|
|
23
21
|
|
|
@@ -31,24 +29,17 @@ module Raindown
|
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def render_body(body, variables, metadata)
|
|
34
|
-
|
|
35
|
-
# Other directives are hidden, but not the Markdown between their tags.
|
|
36
|
-
template = body.gsub(/<\{.*?\}>|<\{/) { |directive| directive.match?(/\A#{DIRECTIVE}\z/) ? directive : hide(directive, hidden) }
|
|
37
|
-
template = template.gsub(BLOCK_LINE, '\1')
|
|
32
|
+
template = body.gsub(BLOCK_LINE, '\1')
|
|
38
33
|
return body unless template.include?('{')
|
|
39
34
|
|
|
40
35
|
# Antlers strips the whitespace around a template, which can be Markdown, like an indented code block.
|
|
41
36
|
leading = template[/\A\s*/]
|
|
42
37
|
trailing = template[/\s*\z/]
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
# Components and endpoints render here too, where loop variables are in scope, and keep their HTML as fragments.
|
|
39
|
+
elements = Antlers::Elements[:html, :var, :if, :for] + Elements[:list, :endpoint, :prop_component, :slot_component]
|
|
40
|
+
rendered = Antlers.render(ast: Antlers.ast(template:, elements:), current_binding: variables.binding, metadata:)
|
|
45
41
|
|
|
46
|
-
"#{leading}#{rendered}#{trailing}"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def hide(directive, hidden)
|
|
50
|
-
hidden << directive
|
|
51
|
-
"\u{E002}#{hidden.length - 1}\u{E003}"
|
|
42
|
+
"#{leading}#{rendered}#{trailing}"
|
|
52
43
|
end
|
|
53
44
|
end
|
|
54
45
|
end
|
data/lib/raindown/rewriter.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Raindown
|
|
|
21
21
|
|
|
22
22
|
# Returns true when the file changed.
|
|
23
23
|
def update(path:, bare: false, execute: false, metadata: NoMetadata)
|
|
24
|
-
content = File.read(path)
|
|
24
|
+
content = File.read(path, encoding: Encoding::UTF_8)
|
|
25
25
|
rewritten = rewrite(content:, path:, bare:, execute:, metadata:)
|
|
26
26
|
return false if rewritten == content
|
|
27
27
|
|
data/lib/raindown/toc.rb
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'erb'
|
|
4
|
+
require 'nokogiri'
|
|
5
|
+
|
|
4
6
|
require_relative 'node'
|
|
5
7
|
|
|
6
8
|
module Raindown
|
|
7
9
|
# The node behind toc: and :toc, a table of contents of the document's headings.
|
|
8
10
|
# A project can replace it with its own TOC node in .raindown, like "class TOC < Raindown::TOC".
|
|
9
11
|
class TOC < Node
|
|
10
|
-
def replace(document:, metadata:
|
|
11
|
-
headings =
|
|
12
|
+
def replace(document:, metadata: nil, bare: false)
|
|
13
|
+
headings = headings(markdown: document, metadata:, bare:)
|
|
12
14
|
return '' if headings.empty?
|
|
13
15
|
|
|
14
16
|
min_level = headings.map { |heading| heading[:level] }.min
|
|
@@ -18,8 +20,9 @@ module Raindown
|
|
|
18
20
|
end.join("\n")
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
# With the document's final HTML, the headings include ones its components render.
|
|
24
|
+
def render(document:, html: nil, metadata: nil, bare: false)
|
|
25
|
+
items = headings(markdown: document, html:, metadata:, bare:).map do |heading|
|
|
23
26
|
"<li class='h#{heading[:level]}'><a href='##{heading[:id]}'>#{ERB::Util.html_escape(heading[:text])}</a></li>"
|
|
24
27
|
end
|
|
25
28
|
|
|
@@ -34,5 +37,14 @@ module Raindown
|
|
|
34
37
|
</div>
|
|
35
38
|
HTML
|
|
36
39
|
end
|
|
40
|
+
|
|
41
|
+
# The document's headings, from its final HTML, or else by rendering it with its components.
|
|
42
|
+
def headings(markdown:, html: nil, metadata: nil, bare: false)
|
|
43
|
+
html ||= Fragments.collect { Raindown.assembled(markdown:, metadata: metadata || NoMetadata, bare:) }
|
|
44
|
+
|
|
45
|
+
Nokogiri::HTML(html).css(HEADINGS).map do |heading|
|
|
46
|
+
{ level: heading.name[1].to_i, text: heading.text.strip, id: heading['id'] }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
37
49
|
end
|
|
38
50
|
end
|
data/lib/raindown.rb
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
require 'commonmarker'
|
|
4
4
|
require 'antlers'
|
|
5
5
|
require 'antlers/api'
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
require_relative 'elements'
|
|
8
8
|
require_relative 'raindown/bare_directives'
|
|
9
9
|
require_relative 'raindown/code'
|
|
10
10
|
require_relative 'raindown/config'
|
|
11
11
|
require_relative 'raindown/directives'
|
|
12
|
+
require_relative 'raindown/fragments'
|
|
12
13
|
require_relative 'raindown/front_matter'
|
|
14
|
+
require_relative 'raindown/heading_ids'
|
|
13
15
|
require_relative 'raindown/node_blocks'
|
|
14
16
|
require_relative 'raindown/pages'
|
|
15
17
|
require_relative 'raindown/pre_renderer'
|
|
@@ -36,40 +38,36 @@ module Raindown
|
|
|
36
38
|
|
|
37
39
|
module_function
|
|
38
40
|
|
|
39
|
-
def headings(markdown:, metadata: NoMetadata, bare: false)
|
|
40
|
-
html = html(markdown:, variables: variables(markdown:), metadata:, bare:)
|
|
41
|
-
|
|
42
|
-
Nokogiri::HTML(html).css(HEADINGS).map do |heading|
|
|
43
|
-
{ level: heading.name[1].to_i, text: heading.text.strip, id: heading['id'] }
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
41
|
# Directives show in bold, unless the file's project hides them in .raindown/config.yml.
|
|
48
42
|
def render_file(path:, metadata: NoMetadata, bare: false, hide_directives: Config.for(path)[:hide_directives])
|
|
49
|
-
render(markdown: File.read(path), metadata:, bare: bare || BareDirectives.file?(path), hide_directives:)
|
|
43
|
+
render(markdown: File.read(path, encoding: Encoding::UTF_8), metadata:, bare: bare || BareDirectives.file?(path), hide_directives:)
|
|
50
44
|
end
|
|
51
45
|
|
|
52
46
|
# Front matter keys are variables, like {title} or <{ title }>.
|
|
53
|
-
# Directives like
|
|
47
|
+
# Directives like "toc:" export to HTML as bold or comments depending on hide_directives config.
|
|
54
48
|
def render(markdown:, metadata: NoMetadata, bare: false, hide_directives: false)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
ast = Antlers.ast(template:, elements: Antlers::Elements[:html, :prop, :slot] + Elements[:endpoint])
|
|
62
|
-
template = "#{Antlers.render(ast:, current_binding: variables.binding, metadata:).chomp}\n"
|
|
49
|
+
Fragments.collect do
|
|
50
|
+
# Components' HTML goes back in, then their headings get unique ids, before nodes like the TOC see it.
|
|
51
|
+
html = assembled(markdown:, metadata:, bare:)
|
|
52
|
+
html = Nodes.render_placeholders(html, document: markdown, metadata:, bare:, html:)
|
|
53
|
+
|
|
54
|
+
Directives.render("#{html.chomp}\n", hide: hide_directives)
|
|
63
55
|
end
|
|
56
|
+
end
|
|
64
57
|
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
# The document's HTML with its components' HTML put back, and unique heading ids.
|
|
59
|
+
def assembled(markdown:, metadata: NoMetadata, bare: false)
|
|
60
|
+
HeadingIds.unique(Fragments.fill(html(markdown:, variables: variables(markdown:), metadata:, bare:)))
|
|
67
61
|
end
|
|
68
62
|
|
|
69
|
-
# The HTML from Commonmarker, after
|
|
70
|
-
def html(markdown:, variables:, metadata
|
|
63
|
+
# The document's HTML from Commonmarker, after nodes and the template pass, with components as fragments.
|
|
64
|
+
def html(markdown:, variables:, metadata: NoMetadata, bare: false)
|
|
71
65
|
markdown = NodeBlocks.to_rendered(markdown.dup.force_encoding('UTF-8'), metadata:, bare:)
|
|
72
|
-
|
|
66
|
+
commonmark(PreRenderer.render(markdown, variables:, metadata:, bare:))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Markdown to HTML, like a document's or a component's slot.
|
|
70
|
+
def commonmark(markdown)
|
|
73
71
|
doc = Commonmarker.parse(hide_directives(markdown:), options: MARKDOWN_OPTIONS)
|
|
74
72
|
preserve_code(doc:)
|
|
75
73
|
|
data/lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: raindown
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- maedi
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-19 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: antlers
|
|
@@ -149,6 +149,7 @@ files:
|
|
|
149
149
|
- lib/elements.rb
|
|
150
150
|
- lib/lexemes/endpoint_lexeme.rb
|
|
151
151
|
- lib/lexemes/list_lexeme.rb
|
|
152
|
+
- lib/nodes/component_nodes.rb
|
|
152
153
|
- lib/nodes/endpoint_node.rb
|
|
153
154
|
- lib/nodes/list_node.rb
|
|
154
155
|
- lib/raindown.rb
|
|
@@ -161,7 +162,9 @@ files:
|
|
|
161
162
|
- lib/raindown/endpoint/curl.rb
|
|
162
163
|
- lib/raindown/endpoint/endpoint_runner.rb
|
|
163
164
|
- lib/raindown/files.rb
|
|
165
|
+
- lib/raindown/fragments.rb
|
|
164
166
|
- lib/raindown/front_matter.rb
|
|
167
|
+
- lib/raindown/heading_ids.rb
|
|
165
168
|
- lib/raindown/node.rb
|
|
166
169
|
- lib/raindown/node_blocks.rb
|
|
167
170
|
- lib/raindown/node_injector.rb
|