Merge branch '18600-copy-by-ref'
[arvados.git] / doc / zenweb-liquid.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: CC-BY-SA-3.0
4
5 require 'zenweb'
6 require 'liquid'
7
8 module ZenwebLiquid
9   VERSION = '0.0.1'
10 end
11
12 module Zenweb
13
14   class Page
15
16     def render_liquid page, content
17       liquid self.body, content, page, binding
18     end
19
20     ##
21     # Render a page's liquid and return the intermediate result
22     def liquid template, content, page, binding = TOPLEVEL_BINDING
23       Liquid::Template.file_system = Liquid::LocalFileSystem.new(File.join(File.dirname(Rake.application().rakefile), "_includes"))
24       unless defined? @liquid_template
25         @liquid_template = Liquid::Template.parse(template)
26       end
27
28       vars = {}
29       vars["content"] = content
30
31       vars["site"] = site.config.h.clone
32       pages = {}
33       site.pages.each do |f, p|
34         pages[f] = p.config.h.clone
35         pages[f]["url"] = p.url
36       end
37       vars["site"]["pages"] = pages
38
39       vars["page"] = page.config.h.clone
40       vars["page"]["url"] = page.url
41
42       @liquid_template.render(vars)
43     end
44   end
45
46   class LiquidCode < Liquid::Include
47     Syntax = /(#{Liquid::QuotedFragment}+)(\s+(?:as)\s+(#{Liquid::QuotedFragment}+))?/o
48
49     def initialize(tag_name, markup, tokens)
50       Liquid::Tag.instance_method(:initialize).bind(self).call(tag_name, markup, tokens)
51
52       if markup =~ Syntax
53         @template_name_expr = $1
54         @language = $3
55         @attributes    = {}
56       else
57         raise SyntaxError.new("Error in tag 'code' - Valid syntax: include '[code_file]' as '[language]'")
58       end
59     end
60
61     def render(context)
62       require 'coderay'
63
64       partial = load_cached_partial(@template_name_expr, context)
65       html = ''
66
67       # be explicit about errors
68       context.exception_renderer = lambda do |exc|
69         exc.is_a?(Liquid::InternalError) ? "Liquid error: #{exc.cause.message}" : exc
70       end
71
72       context.stack do
73         html = CodeRay.scan(partial.root.nodelist.join, @language).div
74       end
75
76       html
77     end
78
79     Liquid::Template.register_tag('code', LiquidCode)
80   end
81
82   class LiquidCodeBlock < Liquid::Block
83     Syntax = /((?:as)\s+(#{Liquid::QuotedFragment}+))?/o
84
85     def initialize(tag_name, markup, tokens)
86       Liquid::Tag.instance_method(:initialize).bind(self).call(tag_name, markup, tokens)
87
88       if markup =~ Syntax
89         @language = $2
90         @attributes = {}
91       else
92         raise SyntaxError.new("Error in tag 'code' - Valid syntax: codeblock as '[language]'")
93       end
94     end
95
96     def render(context)
97       require 'coderay'
98
99       partial = super
100       html = ''
101
102       if partial[0] == '\n'
103         partial = partial[1..-1]
104       end
105
106       # be explicit about errors
107       context.exception_renderer = lambda do |exc|
108         exc.is_a?(Liquid::InternalError) ? "Liquid error: #{exc.cause.message}" : exc
109       end
110
111       context.stack do
112         html = CodeRay.scan(partial, @language).div
113       end
114
115       "<notextile>#{html}</notextile>"
116     end
117
118     Liquid::Template.register_tag('codeblock', LiquidCodeBlock)
119   end
120 end