jekyll-dry 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e999472a8eab6ae46d936e0455d0d1b036cc9b9dc0cd93d61dbfe3db9ca4a465
4
+ data.tar.gz: 2a6370165c59fbbf18049f19d3f5a51f6f0816a296d57ac9871f80696f6d7cec
5
+ SHA512:
6
+ metadata.gz: '058246a2c85ef4efb7f483f46fb0f0b47071e9256f7256ede62bce018007c1d4279c64b51a82700d0b8c6dde8afa194659b8394a8e85d8b048a38e70a1632ed4'
7
+ data.tar.gz: 2a1a41e461641c5fd3ff5a10ad0fa7a293c0645d0768169d5c5f30e7296dca13633870b3ac995b03841e74ffb0e9d4d5d940ff4c6eda3f4bcca249854d50c87f
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /vendor/
10
+ /_playground/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.5
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+
3
+ cache: bundler
4
+
5
+ branches:
6
+ only:
7
+ - master
8
+
9
+ script:
10
+ - bundle exec rake build
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at vagiz.d@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jekyll-dry.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,20 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jekyll-dry (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (10.5.0)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bundler (~> 2.0)
16
+ jekyll-dry!
17
+ rake (~> 10.0)
18
+
19
+ BUNDLED WITH
20
+ 2.0.2
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Vagiz Duseev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 vduseev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # jekyll-dry
2
+
3
+ [![Build Status](https://travis-ci.org/vduseev/jekyll-dry.svg?branch=master)](https://travis-ci.org/vduseev/jekyll-dry)
4
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f261f89a633e47e3964ecc37bb826d4f)](https://www.codacy.com/manual/vduseev/jekyll-dry?utm_source=github.com&utm_medium=referral&utm_content=vduseev/jekyll-dry&utm_campaign=Badge_Grade)
5
+
6
+ Jekyll plugin that helps you to implement the DRY (Don't Repeat Yourself) principle while writing documentation using Jekyll.
7
+ The plugin allows you to reuse any fragments of markdown multiple times across a single Jekyll website. The fragments can include Liquid syntax and tags.
8
+
9
+ ## Table of contents
10
+
11
+ * User Guide:
12
+ * [Usage](#usage)
13
+ * [Installation](#installation)
14
+ * [Incompatibility with GitHub Pages](#incompatibility-with-github-pages)
15
+ * Implementation:
16
+ * [Plugin's architecture](architecture.md)
17
+ * [Detailed Design](detailed_design.md)
18
+
19
+ ## Usage
20
+
21
+ ### Fragment's beginning tag: `{% frag ... %}`
22
+
23
+ `frag` tag marks the beginning of a reusable fragment and assigns a unique id to it. Everything between `frag` and `endfrag` tags with unique id is considered a unique reusable fragment that can be included to any page.
24
+
25
+ <a name="example-of-frag-usage">Example of usage</a>:
26
+ ```
27
+ It was decided that the amount of dependencies of the executable will
28
+ be kept at minimum. For that reason {% frag dependencies %}the only
29
+ dependency is Python's `argparse` library{% endfrag dependencies %}.
30
+ ```
31
+
32
+ As a result of the above markup the `dependencies` file will be generated and will contain following text:
33
+ ```
34
+ the only dependency is Python's `argparse` library
35
+ ```
36
+
37
+ The generated file is now available for inclusion at any page, including the page where it was initially declared. During generation process `frag` tag is replaced in page with an empty string.
38
+
39
+ ### Fragment's end tag: `{% endfrag ... %}`
40
+
41
+ `endfrag` tag only marks the end of the fragment declared by `frag` tag and is only used by it. After Jekyll processes the page `endfrag` disappears.
42
+
43
+ If no matching `endfrag` is found for a given `frag`, then that `frag` will not be counted as a valid fragment and will not produce an include file.
44
+
45
+ <a name="example-of-endfrag-usage">Example of usage</a>: [see above](#example-of-frag-usage).
46
+
47
+ During generation process `endfrag` tag is replaced in page with an empty string.
48
+
49
+ ### Fragment embedding tag: `{% > ... %}`
50
+
51
+ `>` inclusion tag that searches for an include file with a given unique id generated by `frag` tag. Works in exactly same way as traditional `include` tag, but does not use parameters.
52
+
53
+ <a name="example-of-inclusion-usage">Example of usage:</a>
54
+ ```
55
+ Testing will require a test suite that covers a set of test cases
56
+ derived from initial use cases. However, since {% > dependencies %},
57
+ the testing will be entirely implemented using just the `py.test`
58
+ library.
59
+ ```
60
+
61
+ Which will produce the following result:
62
+
63
+ Testing will require a test suite that covers a set of test cases derived from initial use cases. However, since the only
64
+ dependency is Python's `argparse` library, the testing will be entirely implemented using just the `py.test` library.
65
+
66
+ ## Installation
67
+
68
+ Drop the `jekyll-dry.rb` file into the `_plugins` directory of the website as described in the first option of enabling a plugin in [Jekyll documentation](https://jekyllrb.com/docs/plugins/#installing-a-plugin):
69
+ ```
70
+ In your site source root, make a _plugins directory. Place your plugins
71
+ here. Any file ending in *.rb inside this directory will be loaded
72
+ before Jekyll generates your site.
73
+ ```
74
+
75
+ ## Incompatibility with GitHub Pages
76
+
77
+ Since this is a custom plugin which is not included in the code set of GitHub pages plugins it will not work with GitHub's automatic website generation.
78
+
79
+ You will have to generate the website locally and then push the contents of the `_site` folder to GitHub in order to publish your website.
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/clean'
3
+
4
+ task :default => [:clean]
5
+ #task :default => :spec
data/architecture.md ADDED
@@ -0,0 +1,65 @@
1
+ # Architecture of jekyll-dry plugin
2
+
3
+ The plugin consists of three new Liquid tags: `frag`, `endfrag`, and `>`.
4
+
5
+ ## Fragment's beginning tag: `frag`
6
+
7
+ `frag` tag is inherited from `Liquid::Block` and automatically detects `endfrag` tag with the same id that was used for `frag` tag itself. That means that the tag's class method must perform a text search on the page using regex expression with the starting position of the search equal to the position of the first character after the current `frag` tag.
8
+
9
+ If a corresponding `endfrag` tag is not found, then the `render()` method of the tag does not return anything.
10
+
11
+ However, if matching `endfrag` tag is found, then the whole text between the pair of `frag` and `endfrag` tags is captured and saved to a variable.
12
+
13
+ Any other `frag` and `endfrag` tags trapped in the captured text are removed.
14
+
15
+ After that, the text is saved to the file in the output directory. The saving path must be `output_directory_path/_fragments/`. And the name of the file must be equal to the unique id (*or variable as it is called in the source code of `include` tag*) provided with the tag.
16
+
17
+ If the file with the same name already exists in the `_fragments` directory, then an exception must be thrown from the plugin, saying:
18
+ ```
19
+ The fragment with such name already exists: <fragment's name here>
20
+ ```
21
+
22
+ ## Fragment's end tag: `endfrag`
23
+
24
+ `endfrag` tag is only required for the correct work of the `frag` tag. It is replaced with empty string, or simply, not rendered at all when processed.
25
+
26
+ ## Fragment's embedding tag: `>`
27
+
28
+ `>` embedding tag must have a lower priority than `frag` tag. This is required because all fragment files must be generated before `>` tag gets parsed and processed by Jekyll.
29
+
30
+ Embedding tag looks for the file specified in the variable to the tag in the `output_directory_path/_fragments/` directory.
31
+
32
+ If file is not found then nothing is rendered.
33
+
34
+ If, however, the file is found, the embedding tag reads it and resolves all internal inclusions completely (see a [note on recursive fragment embedding](#recursion)), regenerating the initial requested fragment while doing so.
35
+
36
+ If no regeneration is required and the fragment already has a final form, then the `>` tag embeds the contents of the file in place of itself on the page.
37
+
38
+ ## <a name="recursion">Note on recursive fragment embedding and loops</a>
39
+
40
+ A fragment might contain an inclusion of another fragment inside itself. For example:
41
+ ```
42
+ {% frag example_of_loop %}
43
+ This text illustrates that the fragment can contain another fragment
44
+ inside itself. {% > totally_different_fragment %} Such inclusion is
45
+ correctly resolved during generation process.
46
+ {% endfrag example_of_loop %}
47
+ ```
48
+
49
+ In order to resolve this the `frag` tag first generates all fragment files, including `>` tag inside them left intact.
50
+
51
+ The example above will result in a following fragment generated.
52
+
53
+ `output_directory_path/_fragments/example_of_loop`:
54
+ ```
55
+ This text illustrates that the fragment can contain another fragment
56
+ inside itself. {% > totally_different_fragment %} Such inclusion is
57
+ correctly resolved during generation process.
58
+ ```
59
+
60
+ Later, when `>` tag is being processed, the first time it encounters the usage of the `example_of_loop` fragment in a page, it detects an internal inclusion of another fragment, in this case a fragment called `totally_different_fragment`. So, it goes and pulls up that fragment's file and replaces the `{% > totally_different_fragment %}` string in `example_of_loop` file with the actual content of `totally_different_fragment` file. Hence, it regenerates the `example_of_loop` file leaving it ready-to-use for all other cases, where this fragment will be included whether it's the same page or a different one. This action must be performed in a recursive fashion, or using a stack, until the fragment embedded in another fragment is static and has a determined content. In other words, when embedded fragment has no inclusions in it. As soon as this condition is satisfied the loop, or recursion, has to be stopped.
61
+
62
+ A special validity check must be included into the logic to make sure that under no circumstances a fragment contains an inclusion of itself. Or, in other words, that there is no loop in fragment embedding. Whenever this is detected, an exception must be thrown, saying:
63
+ ```
64
+ A loop in fragment inclusion is detected: <looped fragment's name here>
65
+ ```
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "jekyll/dry"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,48 @@
1
+ # Detailed design of jekyll-dry plugin
2
+
3
+ ## Fragment's beginning tag: `frag`
4
+
5
+ ### Hierarchy note
6
+
7
+ Must be in module `Jekyll`. Must be in module `Tags`.
8
+
9
+ ### Class `FragTag`
10
+
11
+ Class `FragTag` must be inherited from `Liquid::Tag`.
12
+
13
+ #### Methods of `FragTag`
14
+
15
+ ##### `initialize` method
16
+
17
+ ###### Arguments:
18
+
19
+ * tag_name
20
+ * markup
21
+ * tokens
22
+
23
+ ###### Logic:
24
+ 1. The `initialize method` should first make a call to the `super` method.
25
+ 1. Then it should verify that markup string matches the predefined markup pattern similar to the one in the source code of the `include` tag. The regex below matches following example of markup:
26
+ ```
27
+ file_path.ext param1="value1" param2='value2'
28
+ ```
29
+ The regex that matches that string is:
30
+ ```
31
+ # Capture group "fragment_id":
32
+ # - Starts with any amount of any symbols other than "{"
33
+ # - One or more untitled capture group:
34
+ # - Starts with "{{"
35
+ # - Followed by any number of whitespace characters
36
+ # - One or more: word, "-", or "."
37
+ # - Followed by any number of whitespace characters
38
+ # - Maybe one "|" followed by any amount of any symbols
39
+ # - Ends with "}}"
40
+ # - And any amount of symbols other than "\s", "{", or "}"
41
+ #
42
+ # Capture group "params":
43
+ # - Everything not captured by "fragment_id" group
44
+
45
+ (?<fragment_id>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
46
+ (?<params>.*)
47
+ ```
48
+ 1. If markup matched this regex, then a capture group named `fragment_id` must be extracted
@@ -0,0 +1,31 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "jekyll-dry"
7
+ spec.version = Jekyll::JekyllDry::VERSION
8
+ spec.authors = ["vduseev"]
9
+ spec.email = ["vagiz.d@gmail.com"]
10
+
11
+ spec.summary = %q{Don't Repeat Yourself. Reuse text fragments.}
12
+ spec.description = %q{Jekyll plugin that helps you to implement the DRY (Don't Repeat Yourself) principle while writing documentation using Jekyll.}
13
+ spec.homepage = "https://github.com/vduseev/jekyll-dry"
14
+ spec.license = "MIT"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/vduseev/jekyll-dry"
18
+ spec.metadata["changelog_uri"] = "https://raw.githubusercontent.com/vduseev/jekyll-dry/master/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_development_dependency "bundler", "~> 2.0"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ end
data/lib/jekyll-dry.rb ADDED
@@ -0,0 +1,116 @@
1
+ # (The MIT License)
2
+ #
3
+ # Copyright (c) 2018 Vagiz Duseev
4
+
5
+ module ContextExt
6
+ def find_variable(key)
7
+ variable = super(key)
8
+ unless variable
9
+ variable = registers[:site].fragments[key]
10
+ end
11
+ variable
12
+ end
13
+ end
14
+
15
+ Jekyll::Hooks.register :site, :pre_render do |container, payload|
16
+ Liquid::Context.prepend(ContextExt)
17
+ end
18
+
19
+ module Jekyll
20
+ class FragmentGenerator < Generator
21
+ TagStart = /#{Liquid::TagStart}#{Liquid::WhitespaceControl}?\s*/o
22
+ TagEnd = /\s*#{Liquid::WhitespaceControl}?#{Liquid::TagEnd}/o
23
+ FragmentSubPattern = /#{TagStart}(?i:(end)?frag)\s*(.*?)#{TagEnd}\s*/om
24
+ FullFragmentPattern = %r/
25
+ #{TagStart}(?i:frag)\s*(?<id>.*?)#{TagEnd}
26
+ (?<body>.*)
27
+ #{TagStart}(?i:endfrag)\s*\k<id>#{TagEnd}
28
+ /xom
29
+
30
+ def generate(site)
31
+ # Initialize hash map that will store the fragments for rendering
32
+ class << site
33
+ attr_accessor :fragments
34
+ end
35
+ site.fragments = Hash.new
36
+
37
+ # Parse fragments on pages
38
+ site.pages.each do |page|
39
+ fragments = parse_page(page.content)
40
+
41
+ site.fragments.merge!(fragments) do |key, old_val, new_val|
42
+ # This section is invoked every time there is a duplicate key
43
+ # in site.fragments and parsed fragments
44
+ raise Liquid::SyntaxError.new(
45
+ "Duplicate fragment #{key} on page #{page.url}",
46
+ original_fragment: old_val,
47
+ duplicate_fragment: new_val
48
+ )
49
+ end
50
+ end
51
+ end
52
+
53
+ def parse_page(content)
54
+ fragments = Hash.new
55
+
56
+ pos = 0
57
+ while m = FullFragmentPattern.match(content, pos)
58
+ body = clean_fragment(m[:body])
59
+ fragments.store(m[:id], body)
60
+ puts("fragment #{m[:id]}:", body)
61
+ pos = m.begin(:id)
62
+ end
63
+ fragments
64
+ end
65
+
66
+ def clean_fragment(body)
67
+ pattern = /\s*#{FragmentSubPattern}\s*/om
68
+ clean_body = body.gsub(FragmentSubPattern, "")
69
+ clean_body.lstrip!
70
+ clean_body.rstrip!
71
+ end
72
+ end
73
+
74
+ class FragmentBlockBody < Liquid::BlockBody
75
+ def initialize
76
+ super
77
+ end
78
+
79
+ def whitespace_handler(token, parse_context)
80
+ return unless token =~ Jekyll::FragmentGenerator::FragmentSubPattern
81
+ previous_token = @nodelist.last
82
+ if previous_token.is_a? String
83
+ # previous_token.rstrip!
84
+ end
85
+ parse_context.trim_whitespace = true
86
+ end
87
+ end
88
+
89
+ class FragmentBlock < Liquid::Block
90
+ def initialize(tag_name, markup, options)
91
+ super
92
+ end
93
+
94
+ def parse(tokens)
95
+ @body = FragmentBlockBody.new
96
+ while parse_body(@body, tokens)
97
+ end
98
+ end
99
+ end
100
+
101
+ class Fragment < FragmentBlock
102
+ def initialize(tag_name, markup, options)
103
+ super
104
+ @fragment_id, _ = markup.strip.split(%r!\s+!, 2)
105
+ end
106
+
107
+ def render(context)
108
+ output = super
109
+ #context[@fragment_id] = output
110
+ #context.resource_limits.assign_score += output.length
111
+ output
112
+ end
113
+ end
114
+ end
115
+
116
+ Liquid::Template.register_tag('frag', Jekyll::Fragment)
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module JekyllDry
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-dry
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - vduseev
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Jekyll plugin that helps you to implement the DRY (Don't Repeat Yourself)
42
+ principle while writing documentation using Jekyll.
43
+ email:
44
+ - vagiz.d@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".ruby-version"
51
+ - ".travis.yml"
52
+ - CODE_OF_CONDUCT.md
53
+ - Gemfile
54
+ - Gemfile.lock
55
+ - LICENSE
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - _playground/about.md
60
+ - architecture.md
61
+ - bin/console
62
+ - bin/setup
63
+ - detailed_design.md
64
+ - jekyll-dry.gemspec
65
+ - lib/jekyll-dry.rb
66
+ - lib/version.rb
67
+ homepage: https://github.com/vduseev/jekyll-dry
68
+ licenses:
69
+ - MIT
70
+ metadata:
71
+ homepage_uri: https://github.com/vduseev/jekyll-dry
72
+ source_code_uri: https://github.com/vduseev/jekyll-dry
73
+ changelog_uri: https://raw.githubusercontent.com/vduseev/jekyll-dry/master/CHANGELOG.md
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.0.3
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Don't Repeat Yourself. Reuse text fragments.
93
+ test_files: []