Class: Asciidoctor::Ldl::Renderer
- Inherits:
-
Object
- Object
- Asciidoctor::Ldl::Renderer
- Defined in:
- lib/asciidoctor/ldl/renderer.rb
Overview
Renders LDL source into an image file by shelling out to the bundled Node helper. Handles output-directory resolution and content-hash caching so an unchanged diagram is only rendered once.
Kept intentionally free of Asciidoctor-specific types so it is trivial to unit test in isolation.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- SCRIPT =
File.('js/ldl_render.mjs', __dir__)
- FORMATS =
%w[svg png].freeze
- DEFAULT_FONT_FAMILY =
The renderer labels diagram text font-family="sans-serif". Some consumers (notably prawn-svg in asciidoctor-pdf) map that generic family to a glyph-poor built-in font that lacks − (U+2212) and ≥ (U+2265). This default names real, glyph-complete sans-serif fonts first, ending in the generic so browsers/resvg still resolve it. It deliberately omits the PDF built-ins (Helvetica/Arial-AFM) so prawn-svg only uses one of these when it is actually registered in the theme — otherwise it falls through to sans-serif. Set the
font-family/ldl-font-familyattribute to override, or to an empty value to keep the renderer's "sans-serif". 'DejaVu Sans, Bitstream Vera Sans, Liberation Sans, Arial, sans-serif'
Instance Attribute Summary collapse
-
#format ⇒ Object
readonly
Returns the value of attribute format.
-
#out_dir ⇒ Object
readonly
Returns the value of attribute out_dir.
-
#scale ⇒ Object
readonly
Returns the value of attribute scale.
-
#theme ⇒ Object
readonly
Returns the value of attribute theme.
Instance Method Summary collapse
-
#command_for(out_path) ⇒ Object
Assemble the node command line (exposed for testing).
-
#initialize(opts = {}) ⇒ Renderer
constructor
opts is a plain Hash with symbol keys: :format, :scale, :theme, :show_ids, :show_labels, :font_family, :node, :package_dir, :out_dir, :cache.
-
#render(source, basename = nil) ⇒ Object
Render
sourceand return the basename of the generated file (which lives inout_dir). -
#target_filename(source, basename = nil) ⇒ Object
The file name for
sourceunder the current options.
Constructor Details
#initialize(opts = {}) ⇒ Renderer
opts is a plain Hash with symbol keys:
:format, :scale, :theme, :show_ids, :show_labels, :font_family,
:node, :package_dir, :out_dir, :cache
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 37 def initialize(opts = {}) @format = normalize_format(opts[:format]) @scale = normalize_scale(opts[:scale]) @theme = (opts[:theme] || 'light').to_s.downcase @show_ids = truthy(opts[:show_ids], false) @show_labels = truthy(opts[:show_labels], true) @font_family = normalize_font_family(opts[:font_family]) @node = opts[:node] || 'node' @package_dir = opts[:package_dir] @out_dir = opts[:out_dir] || Dir.pwd @cache = opts.key?(:cache) ? opts[:cache] : true end |
Instance Attribute Details
#format ⇒ Object (readonly)
Returns the value of attribute format.
50 51 52 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 50 def format @format end |
#out_dir ⇒ Object (readonly)
Returns the value of attribute out_dir.
50 51 52 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 50 def out_dir @out_dir end |
#scale ⇒ Object (readonly)
Returns the value of attribute scale.
50 51 52 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 50 def scale @scale end |
#theme ⇒ Object (readonly)
Returns the value of attribute theme.
50 51 52 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 50 def theme @theme end |
Instance Method Details
#command_for(out_path) ⇒ Object
Assemble the node command line (exposed for testing).
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 90 def command_for(out_path) cmd = [@node, SCRIPT, '--format', @format, '--scale', sprintf('%g', @scale), '--theme', @theme, '--out', out_path] cmd << (@show_ids ? '--show-ids' : '--no-show-ids') cmd << (@show_labels ? '--show-labels' : '--no-show-labels') cmd.push('--font-family', @font_family) if @font_family cmd.push('--package-dir', @package_dir) if @package_dir cmd end |
#render(source, basename = nil) ⇒ Object
Render source and return the basename of the generated file (which
lives in out_dir). Pass basename (without extension) to get a
stable, human-chosen file name instead of a content hash.
Raises Renderer::Error on failure.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 56 def render(source, basename = nil) FileUtils.mkdir_p(@out_dir) filename = target_filename(source, basename) path = File.join(@out_dir, filename) key = digest(source) return filename if @cache && cache_valid?(path, key) cmd = command_for(path) stdout, stderr, status = Open3.capture3(*cmd, stdin_data: source, binmode: true) unless status.success? detail = stderr.to_s.strip detail = stdout.to_s.strip if detail.empty? raise Error, "LDL rendering failed (#{@format}): #{detail}" end unless File.file?(path) raise Error, "LDL renderer produced no output at #{path}: #{stderr.to_s.strip}" end write_cache_key(path, key) if @cache filename end |
#target_filename(source, basename = nil) ⇒ Object
The file name for source under the current options. Uses basename
verbatim when given, otherwise a content-addressed name.
81 82 83 84 85 86 87 |
# File 'lib/asciidoctor/ldl/renderer.rb', line 81 def target_filename(source, basename = nil) if basename && !basename.to_s.strip.empty? "#{sanitize_basename(basename)}.#{@format}" else "ldl-#{digest(source)}.#{@format}" end end |