blob: df0a26a1e0d592a0607843286552e25311700310 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# tag to read and insert a file relative to the current working directory
# (like include, but in the dir where it is invoked)
# there is also readj which reads a file and applies jekyll processing to it
# handy if we want to include a toc.json file which itself calls {% read_jekyll child/toc.json %}
# (note however variables do not seem to be exported when use readj (TODO),
# although they are exported if you have _includes/file.md and use the standard include file)
# the argument can be a variable or a filename literal (not quoted)
# TODO: figure out how to accept a quoted string as an argument
require 'pathname'
module JekyllRead
class ReadTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
@text = text
@mode = :auto
end
def load_file(context, filename, context_page)
# Pathname API ignores first arg below if second is absolute
file = Pathname.new(File.dirname(context_page['path'])) + filename
file = file.cleanpath
# is there a better way to trim a leading / ?
file = file.relative_path_from(Pathname.new("/")) unless file.relative?
raise "No such file #{file} in read call (from #{context.dig('page','path')})" unless file.exist?
file
end
def render_jekyll(context, filename)
file = load_file(context, filename, context['page'] || context.registers[:page])
# support vars and paths relative to a file being readj'd
jekyllSite = context.registers[:site]
targetPage = Jekyll::Page.new(jekyllSite, jekyllSite.source, File.dirname(file), File.basename(file))
relative_link_parser = JekyllRelativeLinks::Generator.new(nil)
relative_link_parser.prepare_for_site(jekyllSite)
relative_link_parser.replace_relative_links!(targetPage)
targetPage.render(jekyllSite.layouts, jekyllSite.site_payload)
targetPage.output
end
def render_literal(context, filename)
file = load_file(context, filename, context['page'])
file = File.open(file, "rb")
return file.read
end
def render(context)
filename = @text.strip
context[filename] || filename
mode = @mode
if (mode == :auto)
mode = filename.end_with?(".md") ? :jekyll : :literal
end
if (mode == :jekyll)
render_jekyll(context, filename)
elsif (mode == :literal)
render_literal(context, filename)
else
raise "Unknown mode #{mode}"
end
end
end
class ReadJekyllTag < ReadTag
def initialize(tag_name, text, tokens)
super
@mode = :jekyll
end
end
class ReadLiteralTag < ReadTag
def initialize(tag_name, text, tokens)
super
@mode = :literal
end
end
end
Liquid::Template.register_tag('read', JekyllRead::ReadTag)
Liquid::Template.register_tag('read_jekyll', JekyllRead::ReadJekyllTag)
Liquid::Template.register_tag('read_literal', JekyllRead::ReadLiteralTag)
# for compatibility with old markdown
Liquid::Template.register_tag('readj', JekyllRead::ReadJekyllTag)