19070: Still trying to fix test_with_arvbox
[arvados.git] / doc / zenweb-liquid.rb
index f301aa4ad9c6a7ec3fa9e15d0bc56236e2da6335..3e8672e0216e0290982556b82f83eac964a34534 100644 (file)
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: CC-BY-SA-3.0
+
 require 'zenweb'
+require 'liquid'
 
 module ZenwebLiquid
   VERSION = '0.0.1'
 end
 
 module Zenweb
+
   class Page
-    
+
+    def render_liquid page, content
+      liquid self.body, content, page, binding
+    end
+
     ##
     # Render a page's liquid and return the intermediate result
-    def render_liquid page, content, binding = TOPLEVEL_BINDING
-      require 'liquid'
-      
-      unless defined? @liquid_template then
-        @liquid_template = Liquid::Template.parse(content).render()
-      end
-      
-      @liquid_template.render(binding)
+    def liquid template, content, page, binding = TOPLEVEL_BINDING
+      Liquid::Template.file_system = Liquid::LocalFileSystem.new(File.join(File.dirname(Rake.application().rakefile), "_includes"))
+      unless defined? @liquid_template
+        @liquid_template = Liquid::Template.parse(template)
+      end
+
+      vars = {}
+      vars["content"] = content
+
+      vars["site"] = site.config.h.clone
+      pages = {}
+      site.pages.each do |f, p|
+        pages[f] = p.config.h.clone
+        pages[f]["url"] = p.url
+      end
+      vars["site"]["pages"] = pages
+
+      vars["page"] = page.config.h.clone
+      vars["page"]["url"] = page.url
+
+      @liquid_template.render(vars)
     end
   end
+
+  class LiquidCode < Liquid::Include
+    Syntax = /(#{Liquid::QuotedFragment}+)(\s+(?:as)\s+(#{Liquid::QuotedFragment}+))?/o
+
+    def initialize(tag_name, markup, tokens)
+      Liquid::Tag.instance_method(:initialize).bind(self).call(tag_name, markup, tokens)
+
+      if markup =~ Syntax
+        @template_name_expr = $1
+        @language = $3
+        @attributes    = {}
+      else
+        raise SyntaxError.new("Error in tag 'code' - Valid syntax: include '[code_file]' as '[language]'")
+      end
+    end
+
+    def render(context)
+      require 'coderay'
+
+      partial = load_cached_partial(@template_name_expr, context)
+      html = ''
+
+      # be explicit about errors
+      context.exception_renderer = lambda do |exc|
+        exc.is_a?(Liquid::InternalError) ? "Liquid error: #{exc.cause.message}" : exc
+      end
+
+      context.stack do
+        html = CodeRay.scan(partial.root.nodelist.join, @language).div
+      end
+
+      html
+    end
+
+    Liquid::Template.register_tag('code', LiquidCode)
+  end
+
+  class LiquidCodeBlock < Liquid::Block
+    Syntax = /((?:as)\s+(#{Liquid::QuotedFragment}+))?/o
+
+    def initialize(tag_name, markup, tokens)
+      Liquid::Tag.instance_method(:initialize).bind(self).call(tag_name, markup, tokens)
+
+      if markup =~ Syntax
+        @language = $2
+        @attributes = {}
+      else
+        raise SyntaxError.new("Error in tag 'code' - Valid syntax: codeblock as '[language]'")
+      end
+    end
+
+    def render(context)
+      require 'coderay'
+
+      partial = super
+      html = ''
+
+      if partial[0] == '\n'
+        partial = partial[1..-1]
+      end
+
+      # be explicit about errors
+      context.exception_renderer = lambda do |exc|
+        exc.is_a?(Liquid::InternalError) ? "Liquid error: #{exc.cause.message}" : exc
+      end
+
+      context.stack do
+        html = CodeRay.scan(partial, @language).div
+      end
+
+      "<notextile>#{html}</notextile>"
+    end
+
+    Liquid::Template.register_tag('codeblock', LiquidCodeBlock)
+  end
 end