papercraft 2.24 → 3.0
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/CHANGELOG.md +10 -0
 - data/README.md +6 -4
 - data/lib/papercraft/compiler.rb +33 -13
 - data/lib/papercraft/proc_ext.rb +12 -54
 - data/lib/papercraft/template.rb +19 -6
 - data/lib/papercraft/version.rb +1 -1
 - data/lib/papercraft.rb +92 -3
 - metadata +1 -1
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: ac74fb8004af29f1b15e8ca36de8039d3e47c6642105032fa1a51ec46bda100a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 2b5fcf6bc6d472c33033381577b62e0875594a56e3a8f9f1d769b64d4a6ec2ce
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 390c81c371d17216134e931b26e1d6c9728c54e2c8db220b0d21761f9ed7d21b12f784b5642e7473e55c1f65f2bad4fe07f9afa09d78c04b7d54569ed7cc5ebf
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 9801c61a0a9788a563396bed4064b0b0f4aeacb82e43677c52bfc83ed1d25d7b001af4915c3bdb86b6191b1f5681bd1b54460fbaaa626bfde32e471cb12a830f
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # 3.0.0 2025-10-19
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            - Improve implementation of `Papercraft.apply`
         
     | 
| 
      
 4 
     | 
    
         
            +
            - Add support for rendering self-closing XML tags
         
     | 
| 
      
 5 
     | 
    
         
            +
            - Streamline Papercraft API
         
     | 
| 
      
 6 
     | 
    
         
            +
            - Add support for `Papercraft.render { ... }`
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Prefix internal Proc extensions with `__papercraft_`
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Change API to use `Papercraft.html` instead of `Proc#render`. Same for
         
     | 
| 
      
 9 
     | 
    
         
            +
              `apple`, `render_xml` etc.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       1 
11 
     | 
    
         
             
            # 2.24 2025-10-14
         
     | 
| 
       2 
12 
     | 
    
         | 
| 
       3 
13 
     | 
    
         
             
            - Update gem links
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -21,10 +21,12 @@ 
     | 
|
| 
       21 
21 
     | 
    
         
             
            ```ruby
         
     | 
| 
       22 
22 
     | 
    
         
             
            require 'papercraft'
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
               
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
            Papercraft.html {
         
     | 
| 
      
 25 
     | 
    
         
            +
              div {
         
     | 
| 
      
 26 
     | 
    
         
            +
                h1 "Hello from Papercraft!"
         
     | 
| 
      
 27 
     | 
    
         
            +
              }
         
     | 
| 
      
 28 
     | 
    
         
            +
            }
         
     | 
| 
      
 29 
     | 
    
         
            +
            #=> "<div><h1>Hello from Papercraft</h1></div>"
         
     | 
| 
       28 
30 
     | 
    
         
             
            ```
         
     | 
| 
       29 
31 
     | 
    
         | 
| 
       30 
32 
     | 
    
         
             
            Papercraft is a templating engine for dynamically producing HTML in Ruby apps.
         
     | 
    
        data/lib/papercraft/compiler.rb
    CHANGED
    
    | 
         @@ -164,12 +164,23 @@ module Papercraft 
     | 
|
| 
       164 
164 
     | 
    
         
             
                  # adjust_whitespace(node.location)
         
     | 
| 
       165 
165 
     | 
    
         
             
                  is_void = is_void_element?(tag)
         
     | 
| 
       166 
166 
     | 
    
         
             
                  is_raw_inner_text = is_raw_inner_text_element?(tag)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  is_empty = !node.block && !node.inner_text
         
     | 
| 
       167 
168 
     | 
    
         | 
| 
       168 
     | 
    
         
            -
                  if is_void &&  
     | 
| 
      
 169 
     | 
    
         
            +
                  if is_void && !is_empty
         
     | 
| 
       169 
170 
     | 
    
         
             
                    raise Papercraft::Error, "Void element #{tag} cannot contain child nodes or inner text"
         
     | 
| 
       170 
171 
     | 
    
         
             
                  end
         
     | 
| 
       171 
172 
     | 
    
         | 
| 
       172 
     | 
    
         
            -
                   
     | 
| 
      
 173 
     | 
    
         
            +
                  if @mode == :xml && is_empty
         
     | 
| 
      
 174 
     | 
    
         
            +
                    emit_html(
         
     | 
| 
      
 175 
     | 
    
         
            +
                      node.tag_location, 
         
     | 
| 
      
 176 
     | 
    
         
            +
                      format_xml_tag_self_closing(node.tag_location, tag, node.attributes)
         
     | 
| 
      
 177 
     | 
    
         
            +
                    )
         
     | 
| 
      
 178 
     | 
    
         
            +
                    return
         
     | 
| 
      
 179 
     | 
    
         
            +
                  end
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                  emit_html(
         
     | 
| 
      
 182 
     | 
    
         
            +
                    node.tag_location, format_html_tag_open(node.tag_location, tag, node.attributes)
         
     | 
| 
      
 183 
     | 
    
         
            +
                  )
         
     | 
| 
       173 
184 
     | 
    
         
             
                  return if is_void
         
     | 
| 
       174 
185 
     | 
    
         | 
| 
       175 
186 
     | 
    
         
             
                  case node.block
         
     | 
| 
         @@ -178,7 +189,7 @@ module Papercraft 
     | 
|
| 
       178 
189 
     | 
    
         
             
                  when Prism::BlockArgumentNode
         
     | 
| 
       179 
190 
     | 
    
         
             
                    flush_html_parts!
         
     | 
| 
       180 
191 
     | 
    
         
             
                    adjust_whitespace(node.block)
         
     | 
| 
       181 
     | 
    
         
            -
                    emit("; #{format_code(node.block.expression)}. 
     | 
| 
      
 192 
     | 
    
         
            +
                    emit("; #{format_code(node.block.expression)}.__papercraft_compiled_proc.(__buffer__)")
         
     | 
| 
       182 
193 
     | 
    
         
             
                  end
         
     | 
| 
       183 
194 
     | 
    
         | 
| 
       184 
195 
     | 
    
         
             
                  if node.inner_text
         
     | 
| 
         @@ -213,7 +224,7 @@ module Papercraft 
     | 
|
| 
       213 
224 
     | 
    
         
             
                    emit(format_code(node.call_node.receiver))
         
     | 
| 
       214 
225 
     | 
    
         
             
                    emit('::')
         
     | 
| 
       215 
226 
     | 
    
         
             
                  end
         
     | 
| 
       216 
     | 
    
         
            -
                  emit("#{node.call_node.name}. 
     | 
| 
      
 227 
     | 
    
         
            +
                  emit("#{node.call_node.name}.__papercraft_compiled_proc.(__buffer__")
         
     | 
| 
       217 
228 
     | 
    
         
             
                  if node.call_node.arguments
         
     | 
| 
       218 
229 
     | 
    
         
             
                    emit(', ')
         
     | 
| 
       219 
230 
     | 
    
         
             
                    visit(node.call_node.arguments)
         
     | 
| 
         @@ -229,17 +240,17 @@ module Papercraft 
     | 
|
| 
       229 
240 
     | 
    
         
             
                  args = node.call_node.arguments.arguments
         
     | 
| 
       230 
241 
     | 
    
         
             
                  first_arg = args.first
         
     | 
| 
       231 
242 
     | 
    
         | 
| 
       232 
     | 
    
         
            -
                  block_embed = node.block && "&(->(__buffer__) #{format_code(node.block)}. 
     | 
| 
      
 243 
     | 
    
         
            +
                  block_embed = node.block && "&(->(__buffer__) #{format_code(node.block)}.__papercraft_compiled!)"
         
     | 
| 
       233 
244 
     | 
    
         
             
                  block_embed = ", #{block_embed}" if block_embed && node.call_node.arguments
         
     | 
| 
       234 
245 
     | 
    
         | 
| 
       235 
246 
     | 
    
         
             
                  flush_html_parts!
         
     | 
| 
       236 
247 
     | 
    
         
             
                  adjust_whitespace(node.location)
         
     | 
| 
       237 
248 
     | 
    
         | 
| 
       238 
249 
     | 
    
         
             
                  if args.length == 1
         
     | 
| 
       239 
     | 
    
         
            -
                    emit("; #{format_code(first_arg)}. 
     | 
| 
      
 250 
     | 
    
         
            +
                    emit("; #{format_code(first_arg)}.__papercraft_compiled_proc.(__buffer__#{block_embed})")
         
     | 
| 
       240 
251 
     | 
    
         
             
                  else
         
     | 
| 
       241 
252 
     | 
    
         
             
                    args_code = format_code_comma_separated_nodes(args[1..])
         
     | 
| 
       242 
     | 
    
         
            -
                    emit("; #{format_code(first_arg)}. 
     | 
| 
      
 253 
     | 
    
         
            +
                    emit("; #{format_code(first_arg)}.__papercraft_compiled_proc.(__buffer__, #{args_code}#{block_embed})")
         
     | 
| 
       243 
254 
     | 
    
         
             
                  end
         
     | 
| 
       244 
255 
     | 
    
         
             
                end
         
     | 
| 
       245 
256 
     | 
    
         | 
| 
         @@ -336,7 +347,7 @@ module Papercraft 
     | 
|
| 
       336 
347 
     | 
    
         
             
                def visit_extension_tag_node(node)
         
     | 
| 
       337 
348 
     | 
    
         
             
                  flush_html_parts!
         
     | 
| 
       338 
349 
     | 
    
         
             
                  adjust_whitespace(node.location)
         
     | 
| 
       339 
     | 
    
         
            -
                  emit("; Papercraft::Extensions[#{node.tag.inspect}]. 
     | 
| 
      
 350 
     | 
    
         
            +
                  emit("; Papercraft::Extensions[#{node.tag.inspect}].__papercraft_compiled_proc.(__buffer__")
         
     | 
| 
       340 
351 
     | 
    
         
             
                  if node.call_node.arguments
         
     | 
| 
       341 
352 
     | 
    
         
             
                    emit(', ')
         
     | 
| 
       342 
353 
     | 
    
         
             
                    visit(node.call_node.arguments)
         
     | 
| 
         @@ -367,7 +378,7 @@ module Papercraft 
     | 
|
| 
       367 
378 
     | 
    
         
             
                    end
         
     | 
| 
       368 
379 
     | 
    
         
             
                    block_params = block_params.empty? ? '' : ", #{block_params.join(', ')}"
         
     | 
| 
       369 
380 
     | 
    
         | 
| 
       370 
     | 
    
         
            -
                    emit(", &(proc { |__buffer__#{block_params}| #{block_body} }). 
     | 
| 
      
 381 
     | 
    
         
            +
                    emit(", &(proc { |__buffer__#{block_params}| #{block_body} }).__papercraft_compiled!")
         
     | 
| 
       371 
382 
     | 
    
         
             
                  end
         
     | 
| 
       372 
383 
     | 
    
         
             
                  emit(")")
         
     | 
| 
       373 
384 
     | 
    
         
             
                end
         
     | 
| 
         @@ -382,7 +393,7 @@ module Papercraft 
     | 
|
| 
       382 
393 
     | 
    
         
             
                  guard = @render_yield_used ?
         
     | 
| 
       383 
394 
     | 
    
         
             
                    '' : "; raise(LocalJumpError, 'no block given (render_yield)') if !__block__"
         
     | 
| 
       384 
395 
     | 
    
         
             
                  @render_yield_used = true
         
     | 
| 
       385 
     | 
    
         
            -
                  emit("#{guard}; __block__. 
     | 
| 
      
 396 
     | 
    
         
            +
                  emit("#{guard}; __block__.__papercraft_compiled_proc.(__buffer__")
         
     | 
| 
       386 
397 
     | 
    
         
             
                  if node.call_node.arguments
         
     | 
| 
       387 
398 
     | 
    
         
             
                    emit(', ')
         
     | 
| 
       388 
399 
     | 
    
         
             
                    visit(node.call_node.arguments)
         
     | 
| 
         @@ -398,7 +409,7 @@ module Papercraft 
     | 
|
| 
       398 
409 
     | 
    
         
             
                  flush_html_parts!
         
     | 
| 
       399 
410 
     | 
    
         
             
                  adjust_whitespace(node.location)
         
     | 
| 
       400 
411 
     | 
    
         
             
                  @render_children_used = true
         
     | 
| 
       401 
     | 
    
         
            -
                  emit("; __block__&. 
     | 
| 
      
 412 
     | 
    
         
            +
                  emit("; __block__&.__papercraft_compiled_proc&.(__buffer__")
         
     | 
| 
       402 
413 
     | 
    
         
             
                  if node.call_node.arguments
         
     | 
| 
       403 
414 
     | 
    
         
             
                    emit(', ')
         
     | 
| 
       404 
415 
     | 
    
         
             
                    visit(node.call_node.arguments)
         
     | 
| 
         @@ -410,7 +421,7 @@ module Papercraft 
     | 
|
| 
       410 
421 
     | 
    
         
             
                  flush_html_parts!
         
     | 
| 
       411 
422 
     | 
    
         
             
                  adjust_whitespace(node.location)
         
     | 
| 
       412 
423 
     | 
    
         | 
| 
       413 
     | 
    
         
            -
                  emit("; #{node.call_node.receiver.name}. 
     | 
| 
      
 424 
     | 
    
         
            +
                  emit("; #{node.call_node.receiver.name}.__papercraft_compiled_proc.(__buffer__")
         
     | 
| 
       414 
425 
     | 
    
         
             
                  if node.call_node.arguments
         
     | 
| 
       415 
426 
     | 
    
         
             
                    emit(', ')
         
     | 
| 
       416 
427 
     | 
    
         
             
                    visit(node.call_node.arguments)
         
     | 
| 
         @@ -418,7 +429,7 @@ module Papercraft 
     | 
|
| 
       418 
429 
     | 
    
         
             
                  if node.call_node.block
         
     | 
| 
       419 
430 
     | 
    
         
             
                    emit(", &(->")
         
     | 
| 
       420 
431 
     | 
    
         
             
                    visit(node.call_node.block)
         
     | 
| 
       421 
     | 
    
         
            -
                    emit("). 
     | 
| 
      
 432 
     | 
    
         
            +
                    emit(").__papercraft_compiled_proc")
         
     | 
| 
       422 
433 
     | 
    
         
             
                  end
         
     | 
| 
       423 
434 
     | 
    
         
             
                  emit(")")
         
     | 
| 
       424 
435 
     | 
    
         
             
                end
         
     | 
| 
         @@ -489,6 +500,15 @@ module Papercraft 
     | 
|
| 
       489 
500 
     | 
    
         
             
                  RAW_INNER_TEXT_TAGS.include?(tag.to_s)
         
     | 
| 
       490 
501 
     | 
    
         
             
                end
         
     | 
| 
       491 
502 
     | 
    
         | 
| 
      
 503 
     | 
    
         
            +
                def format_xml_tag_self_closing(loc, tag, attributes)
         
     | 
| 
      
 504 
     | 
    
         
            +
                  tag = convert_tag(tag)
         
     | 
| 
      
 505 
     | 
    
         
            +
                  if attributes && attributes&.elements.size > 0 || @@html_debug_attribute_injector
         
     | 
| 
      
 506 
     | 
    
         
            +
                    "<#{tag} #{format_html_attributes(loc, attributes)}/>"
         
     | 
| 
      
 507 
     | 
    
         
            +
                  else
         
     | 
| 
      
 508 
     | 
    
         
            +
                    "<#{tag}/>"
         
     | 
| 
      
 509 
     | 
    
         
            +
                  end
         
     | 
| 
      
 510 
     | 
    
         
            +
                end
         
     | 
| 
      
 511 
     | 
    
         
            +
             
     | 
| 
       492 
512 
     | 
    
         
             
                # Formats an open tag with optional attributes.
         
     | 
| 
       493 
513 
     | 
    
         
             
                #
         
     | 
| 
       494 
514 
     | 
    
         
             
                # @param loc [Prism::Location] tag location
         
     | 
    
        data/lib/papercraft/proc_ext.rb
    CHANGED
    
    | 
         @@ -8,76 +8,34 @@ module Papercraft 
     | 
|
| 
       8 
8 
     | 
    
         
             
                # Returns true if proc is marked as compiled.
         
     | 
| 
       9 
9 
     | 
    
         
             
                #
         
     | 
| 
       10 
10 
     | 
    
         
             
                # @return [bool] is the proc marked as compiled
         
     | 
| 
       11 
     | 
    
         
            -
                def  
     | 
| 
       12 
     | 
    
         
            -
                  @ 
     | 
| 
      
 11 
     | 
    
         
            +
                def __papercraft_compiled?
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @__papercraft_compiled
         
     | 
| 
       13 
13 
     | 
    
         
             
                end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                # Marks the proc as compiled, i.e. can render directly and takes a string
         
     | 
| 
       16 
16 
     | 
    
         
             
                # buffer as first argument.
         
     | 
| 
       17 
17 
     | 
    
         
             
                #
         
     | 
| 
       18 
18 
     | 
    
         
             
                # @return [self]
         
     | 
| 
       19 
     | 
    
         
            -
                def  
     | 
| 
       20 
     | 
    
         
            -
                  @ 
     | 
| 
      
 19 
     | 
    
         
            +
                def __papercraft_compiled!
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @__papercraft_compiled = true
         
     | 
| 
       21 
21 
     | 
    
         
             
                  self
         
     | 
| 
       22 
22 
     | 
    
         
             
                end
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                # Returns the compiled proc for the  
     | 
| 
      
 24 
     | 
    
         
            +
                # Returns the compiled proc for the proc. If marked as compiled, returns
         
     | 
| 
       25 
25 
     | 
    
         
             
                # self.
         
     | 
| 
       26 
26 
     | 
    
         
             
                #
         
     | 
| 
       27 
27 
     | 
    
         
             
                # @param mode [Symbol] compilation mode (:html, :xml)
         
     | 
| 
       28 
28 
     | 
    
         
             
                # @return [Proc] compiled proc or self
         
     | 
| 
       29 
     | 
    
         
            -
                def  
     | 
| 
       30 
     | 
    
         
            -
                  @ 
     | 
| 
      
 29 
     | 
    
         
            +
                def __papercraft_compiled_proc(mode: :html)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @__papercraft_compiled_proc ||= @__papercraft_compiled ?
         
     | 
| 
      
 31 
     | 
    
         
            +
                    self : Papercraft.compile(self, mode:)
         
     | 
| 
       31 
32 
     | 
    
         
             
                end
         
     | 
| 
       32 
33 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                #  
     | 
| 
      
 34 
     | 
    
         
            +
                # Returns the render cache for the proc.
         
     | 
| 
       34 
35 
     | 
    
         
             
                #
         
     | 
| 
       35 
     | 
    
         
            -
                # @return [ 
     | 
| 
       36 
     | 
    
         
            -
                def  
     | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
       38 
     | 
    
         
            -
                rescue Exception => e
         
     | 
| 
       39 
     | 
    
         
            -
                  e.is_a?(Papercraft::Error) ? raise : raise(Papercraft.translate_backtrace(e))
         
     | 
| 
       40 
     | 
    
         
            -
                end
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                # Renders the proc to XML with the given arguments.
         
     | 
| 
       43 
     | 
    
         
            -
                #
         
     | 
| 
       44 
     | 
    
         
            -
                # @return [String] XML string
         
     | 
| 
       45 
     | 
    
         
            -
                def render_xml(*a, **b, &c)
         
     | 
| 
       46 
     | 
    
         
            -
                  __compiled_proc__(mode: :xml).(+'', *a, **b, &c)
         
     | 
| 
       47 
     | 
    
         
            -
                rescue Exception => e
         
     | 
| 
       48 
     | 
    
         
            -
                  e.is_a?(Papercraft::Error) ? raise : raise(Papercraft.translate_backtrace(e))
         
     | 
| 
       49 
     | 
    
         
            -
                end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                # Returns a proc that applies the given arguments to the original proc. The
         
     | 
| 
       52 
     | 
    
         
            -
                # returned proc calls the *compiled* form of the proc, merging the
         
     | 
| 
       53 
     | 
    
         
            -
                # positional and keywords parameters passed to `#apply` with parameters
         
     | 
| 
       54 
     | 
    
         
            -
                # passed to the applied proc. If a block is given, it is wrapped in a proc
         
     | 
| 
       55 
     | 
    
         
            -
                # that passed merged parameters to the block.
         
     | 
| 
       56 
     | 
    
         
            -
                #
         
     | 
| 
       57 
     | 
    
         
            -
                # @param *pos1 [Array<any>] applied positional parameters
         
     | 
| 
       58 
     | 
    
         
            -
                # @param **kw1 [Hash<any, any] applied keyword parameters
         
     | 
| 
       59 
     | 
    
         
            -
                # @return [Proc] applied proc
         
     | 
| 
       60 
     | 
    
         
            -
                def apply(*pos1, **kw1, &block)
         
     | 
| 
       61 
     | 
    
         
            -
                  compiled = __compiled_proc__
         
     | 
| 
       62 
     | 
    
         
            -
                  c_compiled = block&.__compiled_proc__
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                  ->(__buffer__, *pos2, **kw2, &block2) {
         
     | 
| 
       65 
     | 
    
         
            -
                    c_proc = c_compiled && ->(__buffer__, *pos3, **kw3) {
         
     | 
| 
       66 
     | 
    
         
            -
                      c_compiled.(__buffer__, *pos3, **kw3, &block2)
         
     | 
| 
       67 
     | 
    
         
            -
                    }.__compiled__!
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                    compiled.(__buffer__, *pos1, *pos2, **kw1, **kw2, &c_proc)
         
     | 
| 
       70 
     | 
    
         
            -
                  }.__compiled__!
         
     | 
| 
       71 
     | 
    
         
            -
                end
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                # Caches and returns the rendered HTML for the template with the given
         
     | 
| 
       74 
     | 
    
         
            -
                # arguments.
         
     | 
| 
       75 
     | 
    
         
            -
                #
         
     | 
| 
       76 
     | 
    
         
            -
                # @param key [any] Cache key
         
     | 
| 
       77 
     | 
    
         
            -
                # @return [String] HTML string
         
     | 
| 
       78 
     | 
    
         
            -
                def render_cache(key, *args, **kargs, &block)
         
     | 
| 
       79 
     | 
    
         
            -
                  @render_cache ||= {}
         
     | 
| 
       80 
     | 
    
         
            -
                  @render_cache[key] ||= render(*args, **kargs, &block)
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @return [Hash] cache hash
         
     | 
| 
      
 37 
     | 
    
         
            +
                def __papercraft_render_cache
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @__papercraft_render_cache ||= {}
         
     | 
| 
       81 
39 
     | 
    
         
             
                end
         
     | 
| 
       82 
40 
     | 
    
         
             
              end
         
     | 
| 
       83 
41 
     | 
    
         
             
            end
         
     | 
    
        data/lib/papercraft/template.rb
    CHANGED
    
    | 
         @@ -8,21 +8,34 @@ module Papercraft 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                # @param proc [Proc] template proc
         
     | 
| 
       10 
10 
     | 
    
         
             
                # @param mode [Symbol] mode (:html, :xml)
         
     | 
| 
       11 
     | 
    
         
            -
                def initialize(proc, mode: :html)
         
     | 
| 
       12 
     | 
    
         
            -
                  @proc = proc
         
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(proc = nil, mode: :html, &block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @proc = proc || block
         
     | 
| 
      
 13 
     | 
    
         
            +
                  raise ArgumentError, "No template proc given" if !@proc
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       13 
15 
     | 
    
         
             
                  @mode = mode
         
     | 
| 
       14 
16 
     | 
    
         
             
                end
         
     | 
| 
       15 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
                # Renders the template.
         
     | 
| 
      
 19 
     | 
    
         
            +
                #
         
     | 
| 
      
 20 
     | 
    
         
            +
                # @return [String] generated HTML
         
     | 
| 
       16 
21 
     | 
    
         
             
                def render(*, **, &)
         
     | 
| 
       17 
     | 
    
         
            -
                  (mode == :xml) ? @proc 
     | 
| 
      
 22 
     | 
    
         
            +
                  (mode == :xml) ? Papercraft.xml(@proc, *, **, &) : Papercraft.html(@proc, *, **, &)
         
     | 
| 
       18 
23 
     | 
    
         
             
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                alias_method :call, :render
         
     | 
| 
       19 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
                # Applies the given parameters and block to the template, returning an
         
     | 
| 
      
 27 
     | 
    
         
            +
                # applied template.
         
     | 
| 
      
 28 
     | 
    
         
            +
                #
         
     | 
| 
      
 29 
     | 
    
         
            +
                # @return [Papercraft::Template] applied template
         
     | 
| 
       20 
30 
     | 
    
         
             
                def apply(*, **, &)
         
     | 
| 
       21 
     | 
    
         
            -
                  Template.new( 
     | 
| 
      
 31 
     | 
    
         
            +
                  Template.new(Papercraft.apply(@proc, *, **, &), mode: @mode)
         
     | 
| 
       22 
32 
     | 
    
         
             
                end
         
     | 
| 
       23 
33 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                 
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
                # Returns the compiled proc for the template.
         
     | 
| 
      
 35 
     | 
    
         
            +
                #
         
     | 
| 
      
 36 
     | 
    
         
            +
                # @return [Proc] compiled proc
         
     | 
| 
      
 37 
     | 
    
         
            +
                def __papercraft_compiled_proc
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @proc.__papercraft_compiled_proc(mode: @mode)
         
     | 
| 
       26 
39 
     | 
    
         
             
                end
         
     | 
| 
       27 
40 
     | 
    
         
             
              end
         
     | 
| 
       28 
41 
     | 
    
         
             
            end
         
     | 
    
        data/lib/papercraft/version.rb
    CHANGED
    
    
    
        data/lib/papercraft.rb
    CHANGED
    
    | 
         @@ -114,10 +114,11 @@ module Papercraft 
     | 
|
| 
       114 
114 
     | 
    
         
             
              # @param opts [Hash] Kramdown option overrides
         
     | 
| 
       115 
115 
     | 
    
         
             
              # @return [Kramdown::Document] Kramdown document
         
     | 
| 
       116 
116 
     | 
    
         
             
              def markdown_doc(markdown, **opts)
         
     | 
| 
       117 
     | 
    
         
            -
                @markdown_deps_loaded ||=  
     | 
| 
      
 117 
     | 
    
         
            +
                @markdown_deps_loaded ||= begin
         
     | 
| 
       118 
118 
     | 
    
         
             
                  require 'kramdown'
         
     | 
| 
       119 
119 
     | 
    
         
             
                  require 'rouge'
         
     | 
| 
       120 
120 
     | 
    
         
             
                  require 'kramdown-parser-gfm'
         
     | 
| 
      
 121 
     | 
    
         
            +
                  true
         
     | 
| 
       121 
122 
     | 
    
         
             
                end
         
     | 
| 
       122 
123 
     | 
    
         | 
| 
       123 
124 
     | 
    
         
             
                opts = default_kramdown_options.merge(opts)
         
     | 
| 
         @@ -168,7 +169,7 @@ module Papercraft 
     | 
|
| 
       168 
169 
     | 
    
         
             
              # @return [Array<String>] source map
         
     | 
| 
       169 
170 
     | 
    
         
             
              def source_map(proc)
         
     | 
| 
       170 
171 
     | 
    
         
             
                loc = proc.source_location
         
     | 
| 
       171 
     | 
    
         
            -
                fn = proc. 
     | 
| 
      
 172 
     | 
    
         
            +
                fn = proc.__papercraft_compiled? ? loc.first : Papercraft::Compiler.source_location_to_fn(loc)
         
     | 
| 
       172 
173 
     | 
    
         
             
                Papercraft::Compiler.source_map_store[fn]
         
     | 
| 
       173 
174 
     | 
    
         
             
              end
         
     | 
| 
       174 
175 
     | 
    
         | 
| 
         @@ -186,8 +187,96 @@ module Papercraft 
     | 
|
| 
       186 
187 
     | 
    
         
             
              # @param mode [Symbol] compilation mode (:html, :xml)
         
     | 
| 
       187 
188 
     | 
    
         
             
              # @return [Proc] compiled proc
         
     | 
| 
       188 
189 
     | 
    
         
             
              def compile(proc, mode: :html)
         
     | 
| 
       189 
     | 
    
         
            -
                Papercraft::Compiler.compile(proc, mode:). 
     | 
| 
      
 190 
     | 
    
         
            +
                Papercraft::Compiler.compile(proc, mode:).__papercraft_compiled!
         
     | 
| 
       190 
191 
     | 
    
         
             
              rescue Sirop::Error
         
     | 
| 
       191 
192 
     | 
    
         
             
                raise Papercraft::Error, "Can't compile eval'd template"
         
     | 
| 
       192 
193 
     | 
    
         
             
              end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
              # Renders the given template to HTML with the given arguments. The template
         
     | 
| 
      
 196 
     | 
    
         
            +
              # can be passed either as the first parameter, or as a block, if no parameter
         
     | 
| 
      
 197 
     | 
    
         
            +
              # is given.
         
     | 
| 
      
 198 
     | 
    
         
            +
              #
         
     | 
| 
      
 199 
     | 
    
         
            +
              # @param template [Proc] template proc
         
     | 
| 
      
 200 
     | 
    
         
            +
              # @return [String] HTML string
         
     | 
| 
      
 201 
     | 
    
         
            +
              def html(template = nil, *pos, **kw, &block)
         
     | 
| 
      
 202 
     | 
    
         
            +
                if !template
         
     | 
| 
      
 203 
     | 
    
         
            +
                  template = block
         
     | 
| 
      
 204 
     | 
    
         
            +
                elsif template.is_a?(Template)
         
     | 
| 
      
 205 
     | 
    
         
            +
                  template = template.proc
         
     | 
| 
      
 206 
     | 
    
         
            +
                end
         
     | 
| 
      
 207 
     | 
    
         
            +
                raise ArgumentError, "No template given" if !template
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                template.__papercraft_compiled_proc.(+'', *pos, **kw, &block)
         
     | 
| 
      
 210 
     | 
    
         
            +
              rescue Exception => e
         
     | 
| 
      
 211 
     | 
    
         
            +
                e.is_a?(Papercraft::Error) ? raise : raise(Papercraft.translate_backtrace(e))
         
     | 
| 
      
 212 
     | 
    
         
            +
              end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
              # Renders the given template to XML with the given arguments. The template can
         
     | 
| 
      
 215 
     | 
    
         
            +
              # be passed either as the first parameter, or as a block, if no parameter is
         
     | 
| 
      
 216 
     | 
    
         
            +
              # given.
         
     | 
| 
      
 217 
     | 
    
         
            +
              #
         
     | 
| 
      
 218 
     | 
    
         
            +
              # @param template [Proc] template proc
         
     | 
| 
      
 219 
     | 
    
         
            +
              # @return [String] XML string
         
     | 
| 
      
 220 
     | 
    
         
            +
              def xml(template = nil, *pos, **kw, &block)
         
     | 
| 
      
 221 
     | 
    
         
            +
                if !template
         
     | 
| 
      
 222 
     | 
    
         
            +
                  template = block
         
     | 
| 
      
 223 
     | 
    
         
            +
                elsif template.is_a?(Template)
         
     | 
| 
      
 224 
     | 
    
         
            +
                  template = template.proc
         
     | 
| 
      
 225 
     | 
    
         
            +
                end
         
     | 
| 
      
 226 
     | 
    
         
            +
                raise ArgumentError, "No template given" if !template
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                template = template.proc if template.is_a?(Template)
         
     | 
| 
      
 229 
     | 
    
         
            +
                template.__papercraft_compiled_proc(mode: :xml).(+'', *pos, **kw, &block)
         
     | 
| 
      
 230 
     | 
    
         
            +
              rescue Exception => e
         
     | 
| 
      
 231 
     | 
    
         
            +
                e.is_a?(Papercraft::Error) ? raise : raise(Papercraft.translate_backtrace(e))
         
     | 
| 
      
 232 
     | 
    
         
            +
              end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
              # Returns a proc that applies the given arguments to the original proc. The
         
     | 
| 
      
 235 
     | 
    
         
            +
              # returned proc calls the *compiled* form of the proc, merging the
         
     | 
| 
      
 236 
     | 
    
         
            +
              # positional and keywords parameters passed to `#apply` with parameters
         
     | 
| 
      
 237 
     | 
    
         
            +
              # passed to the applied proc. If a block is given, it is wrapped in a proc
         
     | 
| 
      
 238 
     | 
    
         
            +
              # that passed merged parameters to the block.
         
     | 
| 
      
 239 
     | 
    
         
            +
              #
         
     | 
| 
      
 240 
     | 
    
         
            +
              # @param template [Proc] template proc
         
     | 
| 
      
 241 
     | 
    
         
            +
              # @param *pos1 [Array<any>] applied positional parameters
         
     | 
| 
      
 242 
     | 
    
         
            +
              # @param **kw1 [Hash<any, any] applied keyword parameters
         
     | 
| 
      
 243 
     | 
    
         
            +
              # @return [Proc] applied proc
         
     | 
| 
      
 244 
     | 
    
         
            +
              def apply(template, *pos1, **kw1, &block1)
         
     | 
| 
      
 245 
     | 
    
         
            +
                template = template.proc if template.is_a?(Template)
         
     | 
| 
      
 246 
     | 
    
         
            +
                compiled = template.__papercraft_compiled_proc
         
     | 
| 
      
 247 
     | 
    
         
            +
                block1_compiled = block1&.__papercraft_compiled_proc
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
                ->(__buffer__, *pos2, **kw2, &block2) {
         
     | 
| 
      
 250 
     | 
    
         
            +
                  if block2
         
     | 
| 
      
 251 
     | 
    
         
            +
                    block2_compiled = block1_compiled ?
         
     | 
| 
      
 252 
     | 
    
         
            +
                      ->(__buffer__, *pos3, **kw3) {
         
     | 
| 
      
 253 
     | 
    
         
            +
                        block1_compiled.(__buffer__, *pos3, **kw3, &block2)
         
     | 
| 
      
 254 
     | 
    
         
            +
                      }.__papercraft_compiled! :
         
     | 
| 
      
 255 
     | 
    
         
            +
                      block2.__papercraft_compiled_proc
         
     | 
| 
      
 256 
     | 
    
         
            +
                    compiled.(__buffer__, *pos1, *pos2, **kw1, **kw2, &block2_compiled)
         
     | 
| 
      
 257 
     | 
    
         
            +
                  else
         
     | 
| 
      
 258 
     | 
    
         
            +
                    compiled.(__buffer__, *pos1, *pos2, **kw1, **kw2, &block1_compiled)
         
     | 
| 
      
 259 
     | 
    
         
            +
                  end
         
     | 
| 
      
 260 
     | 
    
         
            +
                }.__papercraft_compiled!
         
     | 
| 
      
 261 
     | 
    
         
            +
              end
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
              # Caches and returns the rendered HTML for the template with the given
         
     | 
| 
      
 264 
     | 
    
         
            +
              # arguments.
         
     | 
| 
      
 265 
     | 
    
         
            +
              #
         
     | 
| 
      
 266 
     | 
    
         
            +
              # @param template [Proc] template proc
         
     | 
| 
      
 267 
     | 
    
         
            +
              # @param key [any] Cache key
         
     | 
| 
      
 268 
     | 
    
         
            +
              # @return [String] HTML string
         
     | 
| 
      
 269 
     | 
    
         
            +
              def cache_html(template, key, *, **, &)
         
     | 
| 
      
 270 
     | 
    
         
            +
                template.__papercraft_render_cache[key] ||= html(template, *, **, &)
         
     | 
| 
      
 271 
     | 
    
         
            +
              end
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
              # Caches and returns the rendered XML for the template with the given
         
     | 
| 
      
 274 
     | 
    
         
            +
              # arguments.
         
     | 
| 
      
 275 
     | 
    
         
            +
              #
         
     | 
| 
      
 276 
     | 
    
         
            +
              # @param template [Proc] template proc
         
     | 
| 
      
 277 
     | 
    
         
            +
              # @param key [any] Cache key
         
     | 
| 
      
 278 
     | 
    
         
            +
              # @return [String] XML string
         
     | 
| 
      
 279 
     | 
    
         
            +
              def cache_xml(template, key, *, **, &)
         
     | 
| 
      
 280 
     | 
    
         
            +
                template.__papercraft_render_cache[key] ||= xml(template, *, **, &)
         
     | 
| 
      
 281 
     | 
    
         
            +
              end
         
     | 
| 
       193 
282 
     | 
    
         
             
            end
         
     |