| # |
| # 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) |