Module: Carve
- Defined in:
- lib/carve.rb,
lib/carve/version.rb
Constant Summary collapse
- EXTENSIONS =
Extension names the native binding understands (snake_case or hyphenated).
%i[ autolink details list_table math_block heading_permalinks citations code_callouts tab_normalize wikilinks external_links fenced_render fenced_render_graphviz fenced_render_chart spoiler table_of_contents ].freeze
- MODES =
Render modes the native binding understands.
:interactive(default) emits live HTML with client-script hooks (e.g.<pre class="mermaid">,<details>).:staticemits self-contained HTML for print / PDF / archival: it forces disclosure (<details open>) and pre-renders client-script constructs through therenderers:callables, degrading to (escaped) source when a renderer is absent or fails. %i[interactive static].freeze
- RENDERER_KEYS =
Renderer keys accepted by the
renderers:Hash (see .to_html). Each maps a construct's source to a self-contained HTML string emitted on the static path.mermaid/chart/graphvizare callables(String) -> String;mathis(String, display_bool) -> String. %i[mermaid chart graphviz math].freeze
- VERSION =
"0.1.0"
Class Method Summary collapse
-
.parse(source) ⇒ Object
Parse Carve
sourceinto an AST: a tree of Ruby Hashes and Arrays. -
.to_html(source, extensions: nil, mode: nil, renderers: nil) ⇒ Object
Render Carve
sourceto an HTML string.
Class Method Details
.parse(source) ⇒ Object
Parse Carve source into an AST: a tree of Ruby Hashes and Arrays.
Carve.parse("# Hi")
# => {type: "document", frontmatter: {}, footnote_defs: {},
# children: [{type: "heading", level: 1,
# children: [{type: "text", value: "Hi"}], attrs: nil}],
# source_len: 4}
Every node is a Hash with a :type key plus its fields; child collections
are Arrays; :attrs is nil or a Hash of {id:, classes:, key_values:}.
Keys are symbols. This is the raw parse tree (default profile, no
extensions), suitable for a custom renderer (e.g. Carve -> PDF).
112 113 114 115 116 117 118 |
# File 'lib/carve.rb', line 112 def parse(source) # max_nesting: false - the engine already bounds nesting (its own # MAX_NESTING_DEPTH cap), and that cap exceeds Ruby JSON's default # max_nesting of 100. Without this, deeply-nested-but-valid documents # that Carve.to_html renders fine would raise JSON::NestingError here. JSON.parse(_to_ast_json(source.to_s), symbolize_names: true, max_nesting: false) end |
.to_html(source, extensions: nil, mode: nil, renderers: nil) ⇒ Object
Render Carve source to an HTML string.
With no extensions:
Carve.to_html("# Hello") # => "<section ...>\n <h1>Hello</h1>..."
With extensions (Array of names as Symbols or Strings):
Carve.to_html(src, extensions: [:math_block])
Carve.to_html(src, extensions: %w[math-block list-table])
Recognized extension names: see Carve::EXTENSIONS. Names may be given snake_case (:math_block) or hyphenated ("math-block").
An unknown extension name raises ArgumentError (from the native layer).
Static render mode
Pass mode: :static (or "static") to emit self-contained HTML for print /
PDF / archival. In static mode disclosure is forced (<details open>) and
client-script constructs are pre-rendered through the renderers: Hash:
Carve.to_html(src, extensions: [:fenced_render], mode: :static,
renderers: { mermaid: ->(s) { "<svg>#{s}</svg>" } })
Renderer callables (Symbol or String keys, see Carve::RENDERER_KEYS):
* +:mermaid+ / +:chart+ / +:graphviz+ -> callable `(String) -> String`
* +:math+ -> callable `(String, display) -> String`
When a needed renderer is absent, or a renderer raises / returns a
non-String, the construct degrades to its HTML-ESCAPED source (never blank,
never raw HTML). Omitting mode: defaults to interactive (non-breaking).
An unknown mode or renderer key raises ArgumentError (from the native layer).
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/carve.rb', line 84 def to_html(source, extensions: nil, mode: nil, renderers: nil) list = Array(extensions) # Fast path: interactive (default), no extensions, no renderers. if list.empty? && (mode.nil? || mode.to_s == "interactive") && (renderers.nil? || renderers.empty?) return _to_html(source.to_s) end to_html_full( source.to_s, list.map(&:to_s), (mode || :interactive).to_s, renderers || {}, ) end |