Module: Papercraft
- Extended by:
- Papercraft
- Included in:
- Papercraft
- Defined in:
- lib/papercraft.rb,
lib/papercraft/proc.rb,
lib/papercraft/version.rb,
lib/papercraft/compiler.rb,
lib/papercraft/proc_ext.rb,
lib/papercraft/template.rb,
lib/papercraft/compiler/tag_translator.rb,
lib/papercraft/compiler/nodes.rb
Overview
Papercraft is a functional templating library. In Papercraft, templates are expressed as plain Ruby procs.
Defined Under Namespace
Modules: ProcAPI, ProcExtensions Classes: BlockInvocationNode, BuiltinNode, Compiler, ConstTagNode, DeferNode, Error, ExtensionTagNode, RawNode, RenderNode, TagNode, TagTranslator, Template, TextNode
Constant Summary collapse
- Extensions =
Registry of Papercraft extensions
{ link_stylesheet: ->(href, **atts) { link(rel: "stylesheet", href:, **atts) } }
- VERSION =
'3.2.0'
Instance Method Summary collapse
-
#__clear_extensions__ ⇒ self
Clears all registered extensions.
-
#apply(template, *pos1, **kw1, &block1) ⇒ Proc
Returns a proc that applies the given arguments to the original proc.
-
#ast(proc) ⇒ Prism::Node
Returns the AST for the given proc.
-
#cache_html(template, key) ⇒ String
Caches and returns the rendered HTML for the template with the given arguments.
-
#cache_xml(template, key) ⇒ String
Caches and returns the rendered XML for the template with the given arguments.
-
#compile(proc, mode: :html) ⇒ Proc
Compiles the given template.
-
#compiled_code(proc) ⇒ String
Returns the compiled form code for the given proc.
-
#compute_backtrace_entry(entry, cache) ⇒ Object
Computes a backtrace entry with caching.
-
#default_kramdown_options ⇒ Hash
Returns the default Kramdown options used for rendering Markdown.
-
#default_kramdown_options=(opts) ⇒ Hash
Sets the default Kramdown options used for rendering Markdown.
-
#extension(spec) ⇒ self
Registers extensions to the Papercraft syntax.
-
#format_tag_attrs(attrs) ⇒ String
Formats the given hash as tag attributes.
-
#html(template = nil, *pos, **kw, &block) ⇒ String
Renders the given template to HTML with the given arguments.
- #make_argument_error(err, backtrace) ⇒ Object
-
#markdown(markdown, **opts) ⇒ String
Renders Markdown into HTML.
-
#markdown_doc(markdown, **opts) ⇒ Kramdown::Document
Returns a Kramdown doc for the given markdown.
-
#source_map(proc) ⇒ Array<String>
Returns the source map for the given proc.
-
#translate_backtrace(err) ⇒ Exception
Translates entries in exception’s backtrace to point to original source code.
-
#underscores_to_dashes(tag) ⇒ String
Formats the given string, converting underscores to dashes.
-
#xml(template = nil, *pos, **kw, &block) ⇒ String
Renders the given template to XML with the given arguments.
Instance Method Details
#__clear_extensions__ ⇒ self
Clears all registered extensions.
34 35 36 37 |
# File 'lib/papercraft.rb', line 34 def __clear_extensions__ Extensions.clear self end |
#apply(template, *pos1, **kw1, &block1) ⇒ Proc
Returns a proc that applies the given arguments to the original proc. The returned proc calls the compiled form of the proc, merging the positional and keywords parameters passed to #apply with parameters passed to the applied proc. If a block is given, it is wrapped in a proc that passed merged parameters to the block.
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/papercraft.rb', line 244 def apply(template, *pos1, **kw1, &block1) template = template.proc if template.is_a?(Template) compiled = template.__papercraft_compiled_proc block1_compiled = block1&.__papercraft_compiled_proc ->(__buffer__, *pos2, **kw2, &block2) { if block2 block2_compiled = block1_compiled ? ->(__buffer__, *pos3, **kw3) { block1_compiled.(__buffer__, *pos3, **kw3, &block2) }.__papercraft_compiled! : block2.__papercraft_compiled_proc compiled.(__buffer__, *pos1, *pos2, **kw1, **kw2, &block2_compiled) else compiled.(__buffer__, *pos1, *pos2, **kw1, **kw2, &block1_compiled) end }.__papercraft_compiled! end |
#ast(proc) ⇒ Prism::Node
Returns the AST for the given proc.
180 181 182 |
# File 'lib/papercraft.rb', line 180 def ast(proc) Sirop.to_ast(proc) end |
#cache_html(template, key) ⇒ String
Caches and returns the rendered HTML for the template with the given arguments.
269 270 271 |
# File 'lib/papercraft.rb', line 269 def cache_html(template, key, *, **, &) template.__papercraft_render_cache[key] ||= html(template, *, **, &) end |
#cache_xml(template, key) ⇒ String
Caches and returns the rendered XML for the template with the given arguments.
279 280 281 |
# File 'lib/papercraft.rb', line 279 def cache_xml(template, key, *, **, &) template.__papercraft_render_cache[key] ||= xml(template, *, **, &) end |
#compile(proc, mode: :html) ⇒ Proc
Compiles the given template.
189 190 191 192 193 |
# File 'lib/papercraft.rb', line 189 def compile(proc, mode: :html) Papercraft::Compiler.compile(proc, mode:).__papercraft_compiled! rescue Sirop::Error raise Papercraft::Error, "Can't compile eval'd template" end |
#compiled_code(proc) ⇒ String
Returns the compiled form code for the given proc.
162 163 164 |
# File 'lib/papercraft.rb', line 162 def compiled_code(proc) Papercraft::Compiler.compile_to_code(proc).last end |
#compute_backtrace_entry(entry, cache) ⇒ Object
Computes a backtrace entry with caching.
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/papercraft.rb', line 85 def compute_backtrace_entry(entry, cache) m = entry.match(/^((\:\:\(.+\:.+\))\:(\d+))/) return entry if !m fn = m[2] line = m[3].to_i source_map = cache[fn] ||= Compiler.source_map_store[fn] return entry if !source_map ref = source_map[line] || "?(#{line})" entry.sub(m[1], ref) end |
#default_kramdown_options ⇒ Hash
Returns the default Kramdown options used for rendering Markdown.
141 142 143 144 145 146 147 148 |
# File 'lib/papercraft.rb', line 141 def ||= { entity_output: :numeric, syntax_highlighter: :rouge, input: 'GFM', hard_wrap: false } end |
#default_kramdown_options=(opts) ⇒ Hash
Sets the default Kramdown options used for rendering Markdown.
154 155 156 |
# File 'lib/papercraft.rb', line 154 def (opts) = opts end |
#extension(spec) ⇒ self
Registers extensions to the Papercraft syntax.
26 27 28 29 |
# File 'lib/papercraft.rb', line 26 def extension(spec) Extensions.merge!(spec) self end |
#format_tag_attrs(attrs) ⇒ String
Formats the given hash as tag attributes.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/papercraft.rb', line 51 def format_tag_attrs(attrs) attrs.each_with_object(+'') do |(k, v), html| case v when nil, false when true html << ' ' if !html.empty? html << underscores_to_dashes(k) else html << ' ' if !html.empty? v = v.join(' ') if v.is_a?(Array) html << "#{underscores_to_dashes(k)}=\"#{v}\"" end end end |
#html(template = nil, *pos, **kw, &block) ⇒ String
Renders the given template to HTML with the given arguments. The template can be passed either as the first parameter, or as a block, if no parameter is given.
201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/papercraft.rb', line 201 def html(template = nil, *pos, **kw, &block) if !template template = block elsif template.is_a?(Template) template = template.proc end raise ArgumentError, "No template given" if !template template.__papercraft_compiled_proc.(+'', *pos, **kw, &block) rescue Exception => e e.is_a?(Papercraft::Error) ? raise : raise(Papercraft.translate_backtrace(e)) end |
#make_argument_error(err, backtrace) ⇒ Object
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/papercraft.rb', line 98 def make_argument_error(err, backtrace) m = err..match(/(given (\d+), expected (\d+))/) if m rectified = format('given %d, expected %d', m[2].to_i - 1, m[3].to_i - 1) = err..gsub(m[1], rectified) else = err. end ArgumentError.new().tap { it.set_backtrace(backtrace) } end |
#markdown(markdown, **opts) ⇒ String
Renders Markdown into HTML. The opts argument will be merged with the default Kramdown options in order to change the rendering behaviour.
134 135 136 |
# File 'lib/papercraft.rb', line 134 def markdown(markdown, **opts) markdown_doc(markdown, **opts).to_html end |
#markdown_doc(markdown, **opts) ⇒ Kramdown::Document
Returns a Kramdown doc for the given markdown. The opts argument will be merged with the default Kramdown options in order to change the rendering behaviour.
116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/papercraft.rb', line 116 def markdown_doc(markdown, **opts) @markdown_deps_loaded ||= begin require 'kramdown' require 'rouge' require 'kramdown-parser-gfm' true end opts = .merge(opts) Kramdown::Document.new(markdown, **opts) end |
#source_map(proc) ⇒ Array<String>
Returns the source map for the given proc.
170 171 172 173 174 |
# File 'lib/papercraft.rb', line 170 def source_map(proc) loc = proc.source_location fn = proc.__papercraft_compiled? ? loc.first : Papercraft::Compiler.source_location_to_fn(loc) Papercraft::Compiler.source_map_store[fn] end |
#translate_backtrace(err) ⇒ Exception
Translates entries in exception’s backtrace to point to original source code.
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/papercraft.rb', line 70 def translate_backtrace(err) cache = {} is_argument_error = err.is_a?(ArgumentError) && err.backtrace[0] =~ /^\:\:/ backtrace = err.backtrace.map { |e| compute_backtrace_entry(e, cache) } return make_argument_error(err, backtrace) if is_argument_error err.set_backtrace(backtrace) err end |
#underscores_to_dashes(tag) ⇒ String
Formats the given string, converting underscores to dashes.
43 44 45 |
# File 'lib/papercraft.rb', line 43 def underscores_to_dashes(tag) tag.to_s.gsub('_', '-') end |
#xml(template = nil, *pos, **kw, &block) ⇒ String
Renders the given template to XML with the given arguments. The template can be passed either as the first parameter, or as a block, if no parameter is given.
220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/papercraft.rb', line 220 def xml(template = nil, *pos, **kw, &block) if !template template = block elsif template.is_a?(Template) template = template.proc end raise ArgumentError, "No template given" if !template template = template.proc if template.is_a?(Template) template.__papercraft_compiled_proc(mode: :xml).(+'', *pos, **kw, &block) rescue Exception => e e.is_a?(Papercraft::Error) ? raise : raise(Papercraft.translate_backtrace(e)) end |