Module: Yaml::Converter::Renderer::PdfPrawn
- Defined in:
- lib/yaml/converter/renderer/pdf_prawn.rb
Overview
Native PDF rendering using prawn.
Basic layout: title lines, YAML block in monospace, notes as italic paragraphs.
For PDF rendering via pandoc, see PandocShell.
Class Method Summary collapse
-
.extract_notes(markdown) ⇒ Array<String>
Extract note strings from Markdown blockquote lines.
-
.fenced_yaml(markdown) ⇒ Array<String>
Return the lines inside the first fenced ```yaml block.
-
.header_lines(markdown) ⇒ Array<String>
Extract leading
# Title lines. -
.render(markdown:, out_path:, options: {}) ⇒ Boolean
Render a PDF document from the given markdown string.
Class Method Details
.extract_notes(markdown) ⇒ Array<String>
Extract note strings from Markdown blockquote lines.
104 105 106 |
# File 'lib/yaml/converter/renderer/pdf_prawn.rb', line 104 def extract_notes(markdown) markdown.lines.grep(/^> NOTE:/).map { |l| l.sub(/^> NOTE:\s*/, "").strip } end |
.fenced_yaml(markdown) ⇒ Array<String>
Return the lines inside the first fenced ```yaml block.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/yaml/converter/renderer/pdf_prawn.rb', line 84 def fenced_yaml(markdown) inside = false lines = [] markdown.each_line do |l| if l.start_with?("```yaml") inside = true next elsif inside && l.strip == "```" inside = false break elsif inside lines << l.rstrip end end lines end |
.header_lines(markdown) ⇒ Array<String>
Extract leading # Title lines.
77 78 79 |
# File 'lib/yaml/converter/renderer/pdf_prawn.rb', line 77 def header_lines(markdown) markdown.lines.take_while { |l| l.start_with?("# ") }.map { |l| l.sub(/^# /, "").strip } end |
.render(markdown:, out_path:, options: {}) ⇒ Boolean
Render a PDF document from the given markdown string.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/yaml/converter/renderer/pdf_prawn.rb', line 25 def render(markdown:, out_path:, options: {}) require "prawn" notes = extract_notes(markdown) yaml_section = fenced_yaml(markdown) title_lines = header_lines(markdown) page_size = [:pdf_page_size] || "LETTER" margin = [:pdf_margin] || [36, 36, 36, 36] title_fs = [:pdf_title_font_size] || 14 body_fs = [:pdf_body_font_size] || 11 yaml_fs = [:pdf_yaml_font_size] || 9 two_col = !![:pdf_two_column_notes] Prawn::Document.generate(out_path, page_size: page_size, margin: margin) do |pdf| pdf.font_size(title_fs) title_lines.each { |l| pdf.text(l, style: :bold) } pdf.move_down(10) if title_lines.any? if two_col && notes.any? # Create two columns: left for YAML, right for notes col_gap = 16 col_width = (pdf.bounds.width - col_gap) / 2.0 pdf.bounding_box([pdf.bounds.left, pdf.cursor], width: col_width, height: pdf.cursor) do pdf.font_size(yaml_fs) pdf.font("Courier") { yaml_section.each { |l| pdf.text(l) } } end pdf.bounding_box([pdf.bounds.left + col_width + col_gap, pdf.cursor], width: col_width, height: pdf.cursor) do pdf.font_size(body_fs) notes.each { |n| pdf.text("NOTE: #{n}", style: :italic) } end else pdf.font_size(yaml_fs) pdf.font("Courier") { yaml_section.each { |l| pdf.text(l) } } pdf.move_down(10) unless notes.empty? pdf.font_size(body_fs) notes.each { |n| pdf.text("NOTE: #{n}", style: :italic) } end end pdf.number_pages("Page <page> of <total>", at: [pdf.bounds.right - 100, 0]) end true rescue StandardError => e warn("prawn pdf failed: #{e.class}: #{e.}") false end |