lifer 0.9.0 → 0.10.1
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 +38 -0
- data/Gemfile.lock +6 -6
- data/README.md +4 -0
- data/lib/lifer/builder/html/from_any.rb +66 -0
- data/lib/lifer/builder/html/from_erb.rb +10 -12
- data/lib/lifer/builder/html/from_liquid/liquid_env.rb +0 -2
- data/lib/lifer/builder/html/from_liquid.rb +16 -29
- data/lib/lifer/builder/html.rb +1 -0
- data/lib/lifer/entry/markdown.rb +20 -23
- data/lib/lifer/entry.rb +4 -7
- data/lib/lifer/version.rb +1 -1
- data/lib/lifer.rb +4 -0
- metadata +5 -5
- data/lib/lifer/builder/html/from_liquid/layout_tag.rb +0 -66
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ae7d44054aac227a4d75940cf8c6d30b46ba403780f5d8583d0db22dfd8cf36e
         | 
| 4 | 
            +
              data.tar.gz: 7c8ac4e684afa95e23f22dc1b6ad0472391c3fc946a6b7bbbdf9acfbf46ac31d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 464566f240f05e2c5e199582555ccecd9bc6449ad477d53adb24905d76e07b9f93c13d050f69cd6c5923f9f9434edca1d14b4d01d674c5b4148bb5d9c85723df
         | 
| 7 | 
            +
              data.tar.gz: 270f4d8c20bc24b180ae474a6d62037b2f2347a4d9e25f7a4af207d0e85d6df66fec0f92a82f57248e05ac34966ba69ff542a30c9e36d4f90e99fe41a46eeba6
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,43 @@ | |
| 1 1 | 
             
            ## Next
         | 
| 2 2 |  | 
| 3 | 
            +
            ## v0.10.1
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            This release resolves a bug with `Entry#summary`. When I originally implemented
         | 
| 6 | 
            +
            summaries as first paragraphs, I didn't realize that using the Kramdown
         | 
| 7 | 
            +
            representation of the document would result in special characters being
         | 
| 8 | 
            +
            transformed badly:
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                In the ldquorealmrdquo where dreams dance
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            This change ensures that we don't end up with trash like that, or other HTML
         | 
| 13 | 
            +
            trash.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            The summary is meant to be ideal for things like `<meta>` description tags,
         | 
| 16 | 
            +
            which should only contain plain text.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## v0.10.0
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            This release lets all layout files (either Liquid or ERB files) provide a
         | 
| 22 | 
            +
            reference to parent, or "root", layout files that should wrap the via
         | 
| 23 | 
            +
            frontmatter.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Previously, we did this for Liquid layouts using the custom `layout` tag. But
         | 
| 26 | 
            +
            because there was no equivalent tag for ERB files, I realized it would be less
         | 
| 27 | 
            +
            work to just provide the value via frontmatter. The same way for every type of
         | 
| 28 | 
            +
            layout file.
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            End users (just me?) must update their Lifer project Liquid layouts accordingly:
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ```diff
         | 
| 33 | 
            +
            - {% layout "layouts/root_layout.html.liquid" %}
         | 
| 34 | 
            +
            + ---
         | 
| 35 | 
            +
            + layout: layouts/root_layout.html.liquid
         | 
| 36 | 
            +
            + ---
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              Layout content.
         | 
| 39 | 
            +
            ```
         | 
| 40 | 
            +
             | 
| 3 41 | 
             
            ## v0.9.0
         | 
| 4 42 |  | 
| 5 43 | 
             
            Atom feeds now support entries with both `#published_at` and `#updated_at`
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                lifer (0. | 
| 4 | 
            +
                lifer (0.10.1)
         | 
| 5 5 | 
             
                  i18n (< 2)
         | 
| 6 6 | 
             
                  kramdown (~> 2.4)
         | 
| 7 7 | 
             
                  liquid (~> 5.6, < 6)
         | 
| @@ -32,9 +32,9 @@ GEM | |
| 32 32 | 
             
                  irb (~> 1.10)
         | 
| 33 33 | 
             
                  reline (>= 0.3.8)
         | 
| 34 34 | 
             
                diff-lcs (1.5.1)
         | 
| 35 | 
            -
                ffi (1.17. | 
| 36 | 
            -
                ffi (1.17. | 
| 37 | 
            -
                ffi (1.17. | 
| 35 | 
            +
                ffi (1.17.2-arm64-darwin)
         | 
| 36 | 
            +
                ffi (1.17.2-x86_64-darwin)
         | 
| 37 | 
            +
                ffi (1.17.2-x86_64-linux-gnu)
         | 
| 38 38 | 
             
                i18n (1.14.7)
         | 
| 39 39 | 
             
                  concurrent-ruby (~> 1.0)
         | 
| 40 40 | 
             
                io-console (0.7.2)
         | 
| @@ -44,7 +44,7 @@ GEM | |
| 44 44 | 
             
                kramdown (2.5.1)
         | 
| 45 45 | 
             
                  rexml (>= 3.3.9)
         | 
| 46 46 | 
             
                language_server-protocol (3.17.0.3)
         | 
| 47 | 
            -
                liquid (5.8. | 
| 47 | 
            +
                liquid (5.8.6)
         | 
| 48 48 | 
             
                  bigdecimal
         | 
| 49 49 | 
             
                  strscan (>= 3.1.1)
         | 
| 50 50 | 
             
                listen (3.9.0)
         | 
| @@ -107,7 +107,7 @@ GEM | |
| 107 107 | 
             
                  sorbet-runtime (>= 0.5.10782)
         | 
| 108 108 | 
             
                sorbet-runtime (0.5.11558)
         | 
| 109 109 | 
             
                stringio (3.1.1)
         | 
| 110 | 
            -
                strscan (3.1. | 
| 110 | 
            +
                strscan (3.1.5)
         | 
| 111 111 | 
             
                xpath (3.2.0)
         | 
| 112 112 | 
             
                  nokogiri (~> 1.8)
         | 
| 113 113 | 
             
                yard (0.9.37)
         | 
    
        data/README.md
    CHANGED
    
    | @@ -107,6 +107,10 @@ Then, build and push the gem to RubyGems: | |
| 107 107 | 
             
                $ gem build
         | 
| 108 108 | 
             
                $ gem push lifer-<new_version_without_the_v_prefix>.gem
         | 
| 109 109 |  | 
| 110 | 
            +
            And ensure that the release commit(s) are on the `main` branch:
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                $ git push origin main
         | 
| 113 | 
            +
             | 
| 110 114 | 
             
            ## Contributing
         | 
| 111 115 |  | 
| 112 116 | 
             
            I'm not currently accepting unsolicited contributions to Lifer. I'm still
         | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            class Lifer::Builder
         | 
| 2 | 
            +
              class HTML
         | 
| 3 | 
            +
                # A base class for all HTML builder adapters. The methods provided by this
         | 
| 4 | 
            +
                # class are either required or reusable by builder subclasses. See the
         | 
| 5 | 
            +
                # committed HTML builder adapter classes for example implementations.
         | 
| 6 | 
            +
                class FromAny
         | 
| 7 | 
            +
                  class << self
         | 
| 8 | 
            +
                    # Build and render an entry.
         | 
| 9 | 
            +
                    #
         | 
| 10 | 
            +
                    # @param entry [Lifer::Entry] The entry to be rendered.
         | 
| 11 | 
            +
                    # @return [String] The rendered entry.
         | 
| 12 | 
            +
                    def build(entry:)
         | 
| 13 | 
            +
                      new(entry: entry).render
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # The base class does not provide a render method, but any subclass
         | 
| 18 | 
            +
                  # should be expected to.
         | 
| 19 | 
            +
                  #
         | 
| 20 | 
            +
                  # @raise [NotImplementedError]
         | 
| 21 | 
            +
                  def render
         | 
| 22 | 
            +
                    raise NotImplementedError,
         | 
| 23 | 
            +
                      "subclasses must implement a custom `#render` method"
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  private
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  # The frontmatter provided by the layout file.
         | 
| 29 | 
            +
                  #
         | 
| 30 | 
            +
                  # @return [Hash] The frontmatter represented as a hash.
         | 
| 31 | 
            +
                  def frontmatter
         | 
| 32 | 
            +
                    return {} unless frontmatter?
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    Lifer::Utilities.symbolize_keys(
         | 
| 35 | 
            +
                      YAML.load layout_file_contents(raw: true)[Lifer::FRONTMATTER_REGEX, 1],
         | 
| 36 | 
            +
                        permitted_classes: [Time]
         | 
| 37 | 
            +
                    )
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  # Checks whether frontmatter is present in the layout file.
         | 
| 41 | 
            +
                  #
         | 
| 42 | 
            +
                  # @return [boolean]
         | 
| 43 | 
            +
                  def frontmatter?
         | 
| 44 | 
            +
                    @frontmatter ||=
         | 
| 45 | 
            +
                      layout_file_contents(raw: true).match?(Lifer::FRONTMATTER_REGEX)
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  # The contents of the layout file.
         | 
| 49 | 
            +
                  #
         | 
| 50 | 
            +
                  # @param raw [boolean] Whether to include or exclude frontmatter from
         | 
| 51 | 
            +
                  #   the contents.
         | 
| 52 | 
            +
                  # @return [String] The contents of the layout file.
         | 
| 53 | 
            +
                  def layout_file_contents(raw: false)
         | 
| 54 | 
            +
                    cache_variable = "@layout_file_contents_#{raw}"
         | 
| 55 | 
            +
                    cached_value = instance_variable_get cache_variable
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    return cached_value if cached_value
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    contents = File.read layout_file
         | 
| 60 | 
            +
                    contents = contents.gsub(Lifer::FRONTMATTER_REGEX, "") unless raw
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    instance_variable_set cache_variable, contents
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| @@ -23,23 +23,21 @@ class Lifer::Builder::HTML | |
| 23 23 | 
             
              #       </body>
         | 
| 24 24 | 
             
              #     </html>
         | 
| 25 25 | 
             
              #
         | 
| 26 | 
            -
              class FromERB
         | 
| 27 | 
            -
                class << self
         | 
| 28 | 
            -
                  # Build and render an entry.
         | 
| 29 | 
            -
                  #
         | 
| 30 | 
            -
                  # @param entry [Lifer::Entry] The entry to be rendered.
         | 
| 31 | 
            -
                  # @return [String] The rendered entry.
         | 
| 32 | 
            -
                  def build(entry:)
         | 
| 33 | 
            -
                    new(entry: entry).render
         | 
| 34 | 
            -
                  end
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 26 | 
            +
              class FromERB < FromAny
         | 
| 37 27 | 
             
                # Reads the entry as ERB, given our renderer context (see the documentation
         | 
| 38 28 | 
             
                # for `#build_binding_context`) and renders the production-ready entry.
         | 
| 39 29 | 
             
                #
         | 
| 40 30 | 
             
                # @return [String] The rendered entry.
         | 
| 41 31 | 
             
                def render
         | 
| 42 | 
            -
                  ERB.new( | 
| 32 | 
            +
                  document = ERB.new(layout_file_contents).result context
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  return document unless (relative_layout_path = frontmatter[:layout])
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  document_binding = binding.tap { |binding|
         | 
| 37 | 
            +
                    binding.local_variable_set :content, document
         | 
| 38 | 
            +
                  }
         | 
| 39 | 
            +
                  layout_path = "%s/%s" % [Lifer.root, relative_layout_path]
         | 
| 40 | 
            +
                  ERB.new(File.read layout_path).result(document_binding)
         | 
| 43 41 | 
             
                end
         | 
| 44 42 |  | 
| 45 43 | 
             
                private
         | 
| @@ -22,8 +22,6 @@ class Lifer::Builder::HTML::FromLiquid | |
| 22 22 | 
             
                      Liquid::LocalFileSystem.new(Lifer.root, "%s.html.liquid")
         | 
| 23 23 |  | 
| 24 24 | 
             
                    environment.register_filter Lifer::Builder::HTML::FromLiquid::Filters
         | 
| 25 | 
            -
                    environment.register_tag "layout",
         | 
| 26 | 
            -
                      Lifer::Builder::HTML::FromLiquid::LayoutTag
         | 
| 27 25 | 
             
                  end
         | 
| 28 26 | 
             
                end
         | 
| 29 27 | 
             
              end
         | 
| @@ -1,10 +1,5 @@ | |
| 1 1 | 
             
            require "liquid"
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative "from_liquid/drops"
         | 
| 4 | 
            -
            require_relative "from_liquid/filters"
         | 
| 5 | 
            -
            require_relative "from_liquid/layout_tag"
         | 
| 6 | 
            -
            require_relative "from_liquid/liquid_env"
         | 
| 7 | 
            -
             | 
| 8 3 | 
             
            class Lifer::Builder::HTML
         | 
| 9 4 | 
             
              # If the HTML builder is given a Liquid template, it uses this class to parse
         | 
| 10 5 | 
             
              # the Liquid into HTML. Lifer project metadata is provided as context. For
         | 
| @@ -28,16 +23,10 @@ class Lifer::Builder::HTML | |
| 28 23 | 
             
              #       </body>
         | 
| 29 24 | 
             
              #     </html>
         | 
| 30 25 | 
             
              #
         | 
| 31 | 
            -
              class FromLiquid
         | 
| 32 | 
            -
                 | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                  # @param entry [Lifer::Entry] The entry to render.
         | 
| 36 | 
            -
                  # @return [String] The rendered entry, ready for output.
         | 
| 37 | 
            -
                  def build(entry:) = new(entry:).render
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                attr_accessor :entry, :layout_file
         | 
| 26 | 
            +
              class FromLiquid < FromAny
         | 
| 27 | 
            +
                require_relative "from_liquid/drops"
         | 
| 28 | 
            +
                require_relative "from_liquid/filters"
         | 
| 29 | 
            +
                require_relative "from_liquid/liquid_env"
         | 
| 41 30 |  | 
| 42 31 | 
             
                # Reads the entry as Liquid, given our document context, and renders
         | 
| 43 32 | 
             
                # an entry.
         | 
| @@ -49,13 +38,23 @@ class Lifer::Builder::HTML | |
| 49 38 | 
             
                      .parse(entry.to_html, **parse_options)
         | 
| 50 39 | 
             
                      .render(context, **render_options)
         | 
| 51 40 | 
             
                  )
         | 
| 41 | 
            +
                  document = Liquid::Template
         | 
| 42 | 
            +
                    .parse(layout_file_contents, **parse_options)
         | 
| 43 | 
            +
                    .render(document_context, **render_options)
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  return document unless (relative_layout_path = frontmatter[:layout])
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  layout_path = "%s/%s" % [Lifer.root, relative_layout_path]
         | 
| 48 | 
            +
                  document_context = context.merge! "content" => document
         | 
| 52 49 | 
             
                  Liquid::Template
         | 
| 53 | 
            -
                    .parse( | 
| 50 | 
            +
                    .parse(File.read layout_path, **parse_options)
         | 
| 54 51 | 
             
                    .render(document_context, **render_options)
         | 
| 55 52 | 
             
                end
         | 
| 56 53 |  | 
| 57 54 | 
             
                private
         | 
| 58 55 |  | 
| 56 | 
            +
                attr_accessor :entry, :layout_file
         | 
| 57 | 
            +
             | 
| 59 58 | 
             
                def initialize(entry:)
         | 
| 60 59 | 
             
                  @entry = entry
         | 
| 61 60 | 
             
                  @layout_file = entry.collection.layout_file
         | 
| @@ -79,19 +78,6 @@ class Lifer::Builder::HTML | |
| 79 78 | 
             
                  }
         | 
| 80 79 | 
             
                end
         | 
| 81 80 |  | 
| 82 | 
            -
                # @private
         | 
| 83 | 
            -
                # It's possible for the provided layout to request a parent layout, which
         | 
| 84 | 
            -
                # makes this method a bit complicated.
         | 
| 85 | 
            -
                #
         | 
| 86 | 
            -
                # @return [String] A Liquid layout document, ready for parsing.
         | 
| 87 | 
            -
                def layout
         | 
| 88 | 
            -
                  contents = File.read layout_file
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                  return contents unless contents.match?(/\{%\s*#{LayoutTag::NAME}.*%\}/)
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                  contents + "\n{% #{LayoutTag::ENDNAME} %}"
         | 
| 93 | 
            -
                end
         | 
| 94 | 
            -
             | 
| 95 81 | 
             
                def liquid_environment = (@liquid_environment ||= LiquidEnv.global)
         | 
| 96 82 |  | 
| 97 83 | 
             
                def parse_options
         | 
| @@ -103,6 +89,7 @@ class Lifer::Builder::HTML | |
| 103 89 |  | 
| 104 90 | 
             
                def render_options
         | 
| 105 91 | 
             
                  {
         | 
| 92 | 
            +
                    registers: {file_system: liquid_environment.file_system},
         | 
| 106 93 | 
             
                    strict_variables: true,
         | 
| 107 94 | 
             
                    strict_filters: true
         | 
| 108 95 | 
             
                  }
         | 
    
        data/lib/lifer/builder/html.rb
    CHANGED
    
    
    
        data/lib/lifer/entry/markdown.rb
    CHANGED
    
    | @@ -30,14 +30,16 @@ class Lifer::Entry::Markdown < Lifer::Entry | |
| 30 30 | 
             
              def summary
         | 
| 31 31 | 
             
                return super if super
         | 
| 32 32 |  | 
| 33 | 
            -
                return if  | 
| 34 | 
            -
                return first_paragraph if first_paragraph.length <= TRUNCATION_THRESHOLD
         | 
| 33 | 
            +
                return if raw_first_paragraph_text.nil?
         | 
| 35 34 |  | 
| 36 | 
            -
                 | 
| 37 | 
            -
                 | 
| 38 | 
            -
             | 
| 35 | 
            +
                text = raw_first_paragraph_text
         | 
| 36 | 
            +
                return text if text.length <= TRUNCATION_THRESHOLD
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                truncated_text = text[0..TRUNCATION_THRESHOLD]
         | 
| 39 | 
            +
                if (index_of_final_fullstop = text.rindex ". ")
         | 
| 40 | 
            +
                  truncated_text[0..index_of_final_fullstop]
         | 
| 39 41 | 
             
                else
         | 
| 40 | 
            -
                  "%s..." %  | 
| 42 | 
            +
                  "%s..." % truncated_text
         | 
| 41 43 | 
             
                end
         | 
| 42 44 | 
             
              end
         | 
| 43 45 |  | 
| @@ -57,7 +59,7 @@ class Lifer::Entry::Markdown < Lifer::Entry | |
| 57 59 | 
             
              #
         | 
| 58 60 | 
             
              # @return [String] The HTML for the body of the entry.
         | 
| 59 61 | 
             
              def to_html
         | 
| 60 | 
            -
                Kramdown::Document.new(body).to_html
         | 
| 62 | 
            +
                @to_html ||= Kramdown::Document.new(body).to_html
         | 
| 61 63 | 
             
              end
         | 
| 62 64 |  | 
| 63 65 | 
             
              private
         | 
| @@ -75,25 +77,20 @@ class Lifer::Entry::Markdown < Lifer::Entry | |
| 75 77 | 
             
                end.uniq
         | 
| 76 78 | 
             
              end
         | 
| 77 79 |  | 
| 78 | 
            -
              #  | 
| 80 | 
            +
              # Detects the raw paragraph text from the entry.
         | 
| 79 81 | 
             
              #
         | 
| 82 | 
            +
              # @fixme It would be easier and less error prone to do this with Nokogiri. But
         | 
| 83 | 
            +
              #   we currently don't need the dependency for any other reason, so let's
         | 
| 84 | 
            +
              #   defer adding it until then.
         | 
| 80 85 | 
             
              # @private
         | 
| 81 | 
            -
              def  | 
| 82 | 
            -
                 | 
| 83 | 
            -
             | 
| 84 | 
            -
                    Kramdown::Document.new(body).root
         | 
| 85 | 
            -
                      .children
         | 
| 86 | 
            -
                      .detect { |child| child.type == :p }
         | 
| 87 | 
            -
                  )
         | 
| 88 | 
            -
              end
         | 
| 86 | 
            +
              def raw_first_paragraph_text
         | 
| 87 | 
            +
                paragraphs = to_html.match %r{<p[^>]*>(.*?)</p>}im
         | 
| 88 | 
            +
                paragraph = paragraphs ? paragraphs[1].strip : nil
         | 
| 89 89 |  | 
| 90 | 
            -
             | 
| 91 | 
            -
              def kramdown_paragraph_text(kramdown_element)
         | 
| 92 | 
            -
                return if kramdown_element.nil?
         | 
| 90 | 
            +
                return unless paragraph
         | 
| 93 91 |  | 
| 94 | 
            -
                 | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
                  .gsub(/\n/, " ")
         | 
| 92 | 
            +
                paragraph = paragraph.gsub /<\/?[^>]*>/, ""
         | 
| 93 | 
            +
                paragraph = CGI.unescapeHTML paragraph
         | 
| 94 | 
            +
                paragraph.gsub(/[\s\n\t]+/, " ").strip
         | 
| 98 95 | 
             
              end
         | 
| 99 96 | 
             
            end
         | 
    
        data/lib/lifer/entry.rb
    CHANGED
    
    | @@ -39,10 +39,6 @@ module Lifer | |
| 39 39 | 
             
                #
         | 
| 40 40 | 
             
                FILENAME_DATE_FORMAT = /^(\d{4}-\d{1,2}-\d{1,2})-/
         | 
| 41 41 |  | 
| 42 | 
            -
                # We expect frontmatter to be provided in the following format.
         | 
| 43 | 
            -
                #
         | 
| 44 | 
            -
                FRONTMATTER_REGEX = /^---\n(.*)---\n/m
         | 
| 45 | 
            -
             | 
| 46 42 | 
             
                # If tags are represented in YAML frontmatter as a string, they're split on
         | 
| 47 43 | 
             
                # commas and/or spaces.
         | 
| 48 44 | 
             
                #
         | 
| @@ -147,7 +143,7 @@ module Lifer | |
| 147 143 | 
             
                def body
         | 
| 148 144 | 
             
                  return full_text.strip unless frontmatter?
         | 
| 149 145 |  | 
| 150 | 
            -
                  full_text.gsub(FRONTMATTER_REGEX, "").strip
         | 
| 146 | 
            +
                  full_text.gsub(Lifer::FRONTMATTER_REGEX, "").strip
         | 
| 151 147 | 
             
                end
         | 
| 152 148 |  | 
| 153 149 | 
             
                def feedable?
         | 
| @@ -168,7 +164,8 @@ module Lifer | |
| 168 164 | 
             
                  return {} unless frontmatter?
         | 
| 169 165 |  | 
| 170 166 | 
             
                  Lifer::Utilities.symbolize_keys(
         | 
| 171 | 
            -
                    YAML.load | 
| 167 | 
            +
                    YAML.load full_text[Lifer::FRONTMATTER_REGEX, 1],
         | 
| 168 | 
            +
                      permitted_classes: [Time]
         | 
| 172 169 | 
             
                  )
         | 
| 173 170 | 
             
                end
         | 
| 174 171 |  | 
| @@ -326,6 +323,6 @@ module Lifer | |
| 326 323 | 
             
                  File.basename(file).match(FILENAME_DATE_FORMAT)[1]
         | 
| 327 324 | 
             
                end
         | 
| 328 325 |  | 
| 329 | 
            -
                def frontmatter? = (full_text && full_text.match?(FRONTMATTER_REGEX))
         | 
| 326 | 
            +
                def frontmatter? = (full_text && full_text.match?(Lifer::FRONTMATTER_REGEX))
         | 
| 330 327 | 
             
              end
         | 
| 331 328 | 
             
            end
         | 
    
        data/lib/lifer/version.rb
    CHANGED
    
    
    
        data/lib/lifer.rb
    CHANGED
    
    | @@ -24,6 +24,10 @@ module Lifer | |
| 24 24 | 
             
                "(\\/\\.)+"   # Contains a dot directory.
         | 
| 25 25 | 
             
              ] | IGNORE_DIRECTORIES.map { |d| "^(#{d})" }
         | 
| 26 26 |  | 
| 27 | 
            +
              # We expect frontmatter in any file to be provided in the following format.
         | 
| 28 | 
            +
              #
         | 
| 29 | 
            +
              FRONTMATTER_REGEX = /^---\n(.*)---\n/m
         | 
| 30 | 
            +
             | 
| 27 31 | 
             
              class << self
         | 
| 28 32 | 
             
                # The first time `Lifer.brain` is referenced, we build a new `Lifer::Brain`
         | 
| 29 33 | 
             
                # object that is used and reused until the current process has ended.
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: lifer
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.10.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - benjamin wil
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2025- | 
| 11 | 
            +
            date: 2025-05-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: i18n
         | 
| @@ -159,6 +159,7 @@ files: | |
| 159 159 | 
             
            - lib/lifer/brain.rb
         | 
| 160 160 | 
             
            - lib/lifer/builder.rb
         | 
| 161 161 | 
             
            - lib/lifer/builder/html.rb
         | 
| 162 | 
            +
            - lib/lifer/builder/html/from_any.rb
         | 
| 162 163 | 
             
            - lib/lifer/builder/html/from_erb.rb
         | 
| 163 164 | 
             
            - lib/lifer/builder/html/from_liquid.rb
         | 
| 164 165 | 
             
            - lib/lifer/builder/html/from_liquid/drops.rb
         | 
| @@ -170,7 +171,6 @@ files: | |
| 170 171 | 
             
            - lib/lifer/builder/html/from_liquid/drops/tag_drop.rb
         | 
| 171 172 | 
             
            - lib/lifer/builder/html/from_liquid/drops/tags_drop.rb
         | 
| 172 173 | 
             
            - lib/lifer/builder/html/from_liquid/filters.rb
         | 
| 173 | 
            -
            - lib/lifer/builder/html/from_liquid/layout_tag.rb
         | 
| 174 174 | 
             
            - lib/lifer/builder/html/from_liquid/liquid_env.rb
         | 
| 175 175 | 
             
            - lib/lifer/builder/rss.rb
         | 
| 176 176 | 
             
            - lib/lifer/builder/txt.rb
         | 
| @@ -210,8 +210,8 @@ licenses: | |
| 210 210 | 
             
            - MIT
         | 
| 211 211 | 
             
            metadata:
         | 
| 212 212 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 213 | 
            -
              homepage_uri: https://github.com/benjaminwil/lifer/blob/v0. | 
| 214 | 
            -
              source_code_uri: https://github.com/benjaminwil/lifer/tree/v0. | 
| 213 | 
            +
              homepage_uri: https://github.com/benjaminwil/lifer/blob/v0.10.1/README.md
         | 
| 214 | 
            +
              source_code_uri: https://github.com/benjaminwil/lifer/tree/v0.10.1
         | 
| 215 215 | 
             
              changelog_uri: https://github.com/benjaminwil/lifer/blob/main/CHANGELOG.md
         | 
| 216 216 | 
             
            post_install_message:
         | 
| 217 217 | 
             
            rdoc_options: []
         | 
| @@ -1,66 +0,0 @@ | |
| 1 | 
            -
            class Lifer::Builder::HTML::FromLiquid
         | 
| 2 | 
            -
              # Note that if you want to learn more about the shape of this class, check out
         | 
| 3 | 
            -
              # `Liquid::Block` in the `liquid` gem.
         | 
| 4 | 
            -
              #
         | 
| 5 | 
            -
              # The layout tag is a bit magic. The idea here is to emulate how Jekyll
         | 
| 6 | 
            -
              # handles `layout:` YAML frontmatter within entries to change the normal
         | 
| 7 | 
            -
              # parent layout to an override parent layout--but without the need for
         | 
| 8 | 
            -
              # frontmatter.
         | 
| 9 | 
            -
              #
         | 
| 10 | 
            -
              # The reason we took this strategy was to avoid pre-processing every entry for
         | 
| 11 | 
            -
              # frontmatter when we didn't need to. Maybe in the long run this was a bad
         | 
| 12 | 
            -
              # call? I don't know.
         | 
| 13 | 
            -
              #
         | 
| 14 | 
            -
              # @example Usage from a Liquid template.
         | 
| 15 | 
            -
              #     {% layout "path/to/my_liquid_layout_template" %}
         | 
| 16 | 
            -
              #
         | 
| 17 | 
            -
              # (The required `endlayout` tag will be appended to the end of the file
         | 
| 18 | 
            -
              # on render if you do not insert it yourself.
         | 
| 19 | 
            -
              #
         | 
| 20 | 
            -
              class LayoutTag < Liquid::Block
         | 
| 21 | 
            -
                # The name of the tag in Liquid templates, `layout`.
         | 
| 22 | 
            -
                #
         | 
| 23 | 
            -
                NAME = :layout
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                # The end name of the tag in Liquid templates, `endlayout`.
         | 
| 26 | 
            -
                #
         | 
| 27 | 
            -
                ENDNAME = ("end%s" % NAME).to_sym
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                def initialize(layout, path, options)
         | 
| 30 | 
            -
                  @path = path.delete("\"").strip
         | 
| 31 | 
            -
                  super
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                # A layout tag wraps an entire document and outputs it inside of whatever
         | 
| 35 | 
            -
                # the `@layout` is. This lets a child document specify a parernt layout!
         | 
| 36 | 
            -
                # Very confusing stuff.
         | 
| 37 | 
            -
                #
         | 
| 38 | 
            -
                # @param context [Liquid::Context] All of the context of the Liquid
         | 
| 39 | 
            -
                #   document that would be rendered.
         | 
| 40 | 
            -
                # @return [String] A rendered document.
         | 
| 41 | 
            -
                def render(context)
         | 
| 42 | 
            -
                  document_context = context.environments.first
         | 
| 43 | 
            -
                  parse_options = document_context["parse_options"]
         | 
| 44 | 
            -
                  liquid_file_system = parse_options[:environment].file_system
         | 
| 45 | 
            -
                  render_options = document_context["render_options"]
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                  current_layout_file = File
         | 
| 48 | 
            -
                    .read(document_context["entry"]["collection"]["layout_file"])
         | 
| 49 | 
            -
                    .gsub(/\{%\s*#{tag_name}.+%\}/, "")
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                  content_with_layout = Liquid::Template
         | 
| 52 | 
            -
                    .parse(current_layout_file, **parse_options)
         | 
| 53 | 
            -
                    .render(document_context, **render_options)
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                  Liquid::Template
         | 
| 56 | 
            -
                    .parse(
         | 
| 57 | 
            -
                      liquid_file_system.read_template_file(@path),
         | 
| 58 | 
            -
                      **parse_options
         | 
| 59 | 
            -
                    )
         | 
| 60 | 
            -
                    .render(
         | 
| 61 | 
            -
                      document_context.merge({"content" => content_with_layout}),
         | 
| 62 | 
            -
                      **render_options
         | 
| 63 | 
            -
                    )
         | 
| 64 | 
            -
                end
         | 
| 65 | 
            -
              end
         | 
| 66 | 
            -
            end
         |