jekyll-haml-markup 0.1.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
+ SHA1:
3
+ metadata.gz: aa5a1c4f4f6de2b2eec2d73b30f7710c06a68267
4
+ data.tar.gz: 73420ab7f89c64063b39c47269b367e2b5b3a5a7
5
+ SHA512:
6
+ metadata.gz: 49f3975c43de103b7073005b5834b17c132a9080378359f58605161ae2eeef454e55115d8edb15b33ef6e3d45b88c8b8f399f2832ac13f69c0ad2a1d711da80b
7
+ data.tar.gz: f77d17ed31f404a31160a548edb0f6f2b383b366971d653363df80b95b3cd795189b01b039ba76148c5a5aaf66308d8ca05fcf23514969ae96d44905c554e11f
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.3
5
+ before_install: gem install bundler -v 1.16.1
@@ -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 alvaro@faundez.net. 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,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in jekyll-haml-markup.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jekyll-haml-markup (0.1.0)
5
+ haml (~> 5.0)
6
+ jekyll (~> 3.7)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.5.2)
12
+ public_suffix (>= 2.0.2, < 4.0)
13
+ colorator (1.1.0)
14
+ concurrent-ruby (1.0.5)
15
+ em-websocket (0.5.1)
16
+ eventmachine (>= 0.12.9)
17
+ http_parser.rb (~> 0.6.0)
18
+ eventmachine (1.2.5)
19
+ ffi (1.9.18)
20
+ forwardable-extended (2.6.0)
21
+ haml (5.0.4)
22
+ temple (>= 0.8.0)
23
+ tilt
24
+ http_parser.rb (0.6.0)
25
+ i18n (0.9.3)
26
+ concurrent-ruby (~> 1.0)
27
+ jekyll (3.7.2)
28
+ addressable (~> 2.4)
29
+ colorator (~> 1.0)
30
+ em-websocket (~> 0.5)
31
+ i18n (~> 0.7)
32
+ jekyll-sass-converter (~> 1.0)
33
+ jekyll-watch (~> 2.0)
34
+ kramdown (~> 1.14)
35
+ liquid (~> 4.0)
36
+ mercenary (~> 0.3.3)
37
+ pathutil (~> 0.9)
38
+ rouge (>= 1.7, < 4)
39
+ safe_yaml (~> 1.0)
40
+ jekyll-sass-converter (1.5.1)
41
+ sass (~> 3.4)
42
+ jekyll-watch (2.0.0)
43
+ listen (~> 3.0)
44
+ kramdown (1.16.2)
45
+ liquid (4.0.0)
46
+ listen (3.1.5)
47
+ rb-fsevent (~> 0.9, >= 0.9.4)
48
+ rb-inotify (~> 0.9, >= 0.9.7)
49
+ ruby_dep (~> 1.2)
50
+ mercenary (0.3.6)
51
+ minitest (5.11.3)
52
+ pathutil (0.16.1)
53
+ forwardable-extended (~> 2.6)
54
+ public_suffix (3.0.1)
55
+ rake (10.5.0)
56
+ rb-fsevent (0.10.2)
57
+ rb-inotify (0.9.10)
58
+ ffi (>= 0.5.0, < 2)
59
+ rouge (3.1.0)
60
+ ruby_dep (1.5.0)
61
+ safe_yaml (1.0.4)
62
+ sass (3.5.5)
63
+ sass-listen (~> 4.0.0)
64
+ sass-listen (4.0.0)
65
+ rb-fsevent (~> 0.9, >= 0.9.4)
66
+ rb-inotify (~> 0.9, >= 0.9.7)
67
+ temple (0.8.0)
68
+ tilt (2.0.8)
69
+
70
+ PLATFORMS
71
+ ruby
72
+
73
+ DEPENDENCIES
74
+ bundler (~> 1.16)
75
+ jekyll-haml-markup!
76
+ minitest (~> 5.0)
77
+ rake (~> 10.0)
78
+
79
+ BUNDLED WITH
80
+ 1.16.1
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Álvaro Faúndez
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,44 @@
1
+ # JEKYLL-HAML-MARKUP
2
+
3
+ [Jekyll](https://jekyllrb.com) plugin that enables [Haml](http://haml.info) as a markup option for layouts and partials.
4
+
5
+ ## Installation
6
+
7
+ Add it to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'jekyll-haml-markup', group: :jekyll_plugins
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ You just need to save your layout or template with extension `.haml`, replacing any other extension.
16
+
17
+ The haml markup will be rendered before the [Liquid](http://shopify.github.io/liquid/) parsing, that means that you will need to escape with `\` any line that doesn't match haml syntax. For example:
18
+
19
+ ```haml
20
+ !!!
21
+ %html
22
+ %head
23
+ \{% asset style.css %}
24
+ %body
25
+ \{{ content }}
26
+ ```
27
+
28
+ ## Development
29
+
30
+ I started this gem because I couldn't make work the gem [jekyll-haml](https://github.com/samvincent/jekyll-haml).
31
+
32
+ At this moment, this gem just works overriding [Jekyll](https://github.com/jekyll/jekyll) classes and methods. It's not a stable option and it has to be reviewed. If you want to help, just email me.
33
+
34
+ ## Contributing
35
+
36
+ Bug reports and pull requests are welcome on GitHub at https://github.com/afaundez/jekyll-haml-markup. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+
42
+ ## Code of Conduct
43
+
44
+ Everyone interacting in the Jekyll::Haml::Markup project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/jekyll-haml-markup/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'jekyll-haml-markup'
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,30 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jekyll-haml-markup/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jekyll-haml-markup"
8
+ spec.version = Jekyll::Haml::Markup::VERSION
9
+ spec.authors = ["Alvaro Faundez"]
10
+ spec.email = ["alvaro@faundez.net"]
11
+
12
+ spec.summary = %q{Jekyll plugin to use Haml on templates.}
13
+ spec.description = %q{Jekyll plugin that add the option to write layouts and partials in Haml.}
14
+ spec.homepage = 'https://github.com/afaundez/jekyll-haml'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.16"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "minitest", "~> 5.0"
27
+
28
+ spec.add_runtime_dependency 'jekyll', '~> 3.7'
29
+ spec.add_runtime_dependency 'haml', '~> 5.0'
30
+ end
@@ -0,0 +1,92 @@
1
+ require 'jekyll/configuration'
2
+ # frozen_string_literal: true
3
+
4
+ module Jekyll
5
+ class Configuration < Hash
6
+ # Default options. Overridden by values in _config.yml.
7
+ # Strings rather than symbols are used for compatibility with YAML.
8
+ DEFAULTS = Configuration[{
9
+ 'haml_ext' => 'haml',
10
+ 'haml' => 'lib-haml',
11
+ 'lib-haml' => {},
12
+
13
+ # Where things are
14
+ "source" => Dir.pwd,
15
+ "destination" => File.join(Dir.pwd, "_site"),
16
+ "collections_dir" => "",
17
+ "plugins_dir" => "_plugins",
18
+ "layouts_dir" => "_layouts",
19
+ "data_dir" => "_data",
20
+ "includes_dir" => "_includes",
21
+ "collections" => {},
22
+
23
+ # Handling Reading
24
+ "safe" => false,
25
+ "include" => [".htaccess"],
26
+ "exclude" => %w(
27
+ Gemfile Gemfile.lock node_modules vendor/bundle/ vendor/cache/ vendor/gems/
28
+ vendor/ruby/
29
+ ),
30
+ "keep_files" => [".git", ".svn"],
31
+ "encoding" => "utf-8",
32
+ "markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
33
+ "strict_front_matter" => false,
34
+
35
+ # Filtering Content
36
+ "show_drafts" => nil,
37
+ "limit_posts" => 0,
38
+ "future" => false,
39
+ "unpublished" => false,
40
+
41
+ # Plugins
42
+ "whitelist" => [],
43
+ "plugins" => [],
44
+
45
+ # Conversion
46
+ "markdown" => "kramdown",
47
+ "highlighter" => "rouge",
48
+ "lsi" => false,
49
+ "excerpt_separator" => "\n\n",
50
+ "incremental" => false,
51
+
52
+ # Serving
53
+ "detach" => false, # default to not detaching the server
54
+ "port" => "4000",
55
+ "host" => "127.0.0.1",
56
+ "baseurl" => nil, # this mounts at /, i.e. no subdirectory
57
+ "show_dir_listing" => false,
58
+
59
+ # Output Configuration
60
+ "permalink" => "date",
61
+ "paginate_path" => "/page:num",
62
+ "timezone" => nil, # use the local timezone
63
+
64
+ "quiet" => false,
65
+ "verbose" => false,
66
+ "defaults" => [],
67
+
68
+ "liquid" => {
69
+ "error_mode" => "warn",
70
+ },
71
+
72
+ "rdiscount" => {
73
+ "extensions" => [],
74
+ },
75
+
76
+ "redcarpet" => {
77
+ "extensions" => [],
78
+ },
79
+
80
+ "kramdown" => {
81
+ "auto_ids" => true,
82
+ "toc_levels" => "1..6",
83
+ "entity_output" => "as_char",
84
+ "smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
85
+ "input" => "GFM",
86
+ "hard_wrap" => false,
87
+ "footnote_nr" => 1,
88
+ "show_warnings" => false,
89
+ },
90
+ }.map { |k, v| [k, v.freeze] }].freeze
91
+ end
92
+ end
@@ -0,0 +1,34 @@
1
+ require 'jekyll/converter'
2
+ require 'jekyll/haml/parser'
3
+
4
+ module Jekyll
5
+ module Converters
6
+ class Haml < Identity
7
+ safe true
8
+
9
+ def extname_list
10
+ @extname_list ||= @config["haml_ext"].split(",").map do |e|
11
+ ".#{e.downcase}"
12
+ end
13
+ end
14
+
15
+ def matches(ext)
16
+ extname_list.include?(ext.downcase)
17
+ end
18
+
19
+ def output_ext(ext)
20
+ '.html'
21
+ end
22
+
23
+ def get_processor
24
+ case @config["haml"].downcase
25
+ when "lib-haml" then return Jekyll::Haml::Parser.new(@config)
26
+ end
27
+ end
28
+
29
+ def convert(content)
30
+ get_processor.convert content
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ require 'jekyll/convertible'
2
+
3
+ module Jekyll
4
+ module Convertible
5
+
6
+ def haml_file?
7
+ %w(.haml).include?(ext)
8
+ end
9
+
10
+ def render_with_haml?
11
+ haml_file?
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'jekyll/excerpt'
2
+
3
+ module Jekyll
4
+ class Excerpt
5
+
6
+ def_delegators :render_with_haml?
7
+
8
+ end
9
+ end
@@ -0,0 +1,225 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Tags
5
+ class IncludeTagError < StandardError
6
+ attr_accessor :path
7
+
8
+ def initialize(msg, path)
9
+ super(msg)
10
+ @path = path
11
+ end
12
+ end
13
+
14
+ class IncludeTag < Liquid::Tag
15
+ VALID_SYNTAX = %r!
16
+ ([\w-]+)\s*=\s*
17
+ (?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
18
+ !x
19
+ VARIABLE_SYNTAX = %r!
20
+ (?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
21
+ (?<params>.*)
22
+ !x
23
+
24
+ def initialize(tag_name, markup, tokens)
25
+ super
26
+ matched = markup.strip.match(VARIABLE_SYNTAX)
27
+ if matched
28
+ @file = matched["variable"].strip
29
+ @params = matched["params"].strip
30
+ else
31
+ @file, @params = markup.strip.split(%r!\s+!, 2)
32
+ end
33
+ validate_params if @params
34
+ @tag_name = tag_name
35
+ end
36
+
37
+ def syntax_example
38
+ "{% #{@tag_name} file.ext param='value' param2='value' %}"
39
+ end
40
+
41
+ def parse_params(context)
42
+ params = {}
43
+ markup = @params
44
+
45
+ while (match = VALID_SYNTAX.match(markup))
46
+ markup = markup[match.end(0)..-1]
47
+
48
+ value = if match[2]
49
+ match[2].gsub(%r!\\"!, '"')
50
+ elsif match[3]
51
+ match[3].gsub(%r!\\'!, "'")
52
+ elsif match[4]
53
+ context[match[4]]
54
+ end
55
+
56
+ params[match[1]] = value
57
+ end
58
+ params
59
+ end
60
+
61
+ def validate_file_name(file)
62
+ if file !~ %r!^[a-zA-Z0-9_/\.-]+$! || file =~ %r!\./! || file =~ %r!/\.!
63
+ raise ArgumentError, <<-MSG
64
+ Invalid syntax for include tag. File contains invalid characters or sequences:
65
+
66
+ #{file}
67
+
68
+ Valid syntax:
69
+
70
+ #{syntax_example}
71
+
72
+ MSG
73
+ end
74
+ end
75
+
76
+ def validate_params
77
+ full_valid_syntax = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!
78
+ unless @params =~ full_valid_syntax
79
+ raise ArgumentError, <<-MSG
80
+ Invalid syntax for include tag:
81
+
82
+ #{@params}
83
+
84
+ Valid syntax:
85
+
86
+ #{syntax_example}
87
+
88
+ MSG
89
+ end
90
+ end
91
+
92
+ # Grab file read opts in the context
93
+ def file_read_opts(context)
94
+ context.registers[:site].file_read_opts
95
+ end
96
+
97
+ # Render the variable if required
98
+ def render_variable(context)
99
+ if @file.match(VARIABLE_SYNTAX)
100
+ partial = context.registers[:site]
101
+ .liquid_renderer
102
+ .file("(variable)")
103
+ .parse(@file)
104
+ partial.render!(context)
105
+ end
106
+ end
107
+
108
+ def tag_includes_dirs(context)
109
+ context.registers[:site].includes_load_paths.freeze
110
+ end
111
+
112
+ def locate_include_file(context, file, safe)
113
+ includes_dirs = tag_includes_dirs(context)
114
+ includes_dirs.each do |dir|
115
+ path = File.join(dir.to_s, file.to_s)
116
+ return path if valid_include_file?(path, dir.to_s, safe)
117
+ end
118
+ raise IOError, could_not_locate_message(file, includes_dirs, safe)
119
+ end
120
+
121
+ def render(context)
122
+ site = context.registers[:site]
123
+
124
+ file = render_variable(context) || @file
125
+ validate_file_name(file)
126
+
127
+ path = locate_include_file(context, file, site.safe)
128
+ return unless path
129
+
130
+ add_include_to_dependency(site, path, context)
131
+
132
+ partial = load_cached_partial(path, context)
133
+
134
+ context.stack do
135
+ context["include"] = parse_params(context) if @params
136
+ begin
137
+ partial.render!(context)
138
+ rescue Liquid::Error => e
139
+ e.template_name = path
140
+ e.markup_context = "included " if e.markup_context.nil?
141
+ raise e
142
+ end
143
+ end
144
+ end
145
+
146
+ def add_include_to_dependency(site, path, context)
147
+ if context.registers[:page] && context.registers[:page].key?("path")
148
+ site.regenerator.add_dependency(
149
+ site.in_source_dir(context.registers[:page]["path"]),
150
+ path
151
+ )
152
+ end
153
+ end
154
+
155
+ def load_cached_partial(path, context)
156
+ context.registers[:cached_partials] ||= {}
157
+ cached_partial = context.registers[:cached_partials]
158
+
159
+ if cached_partial.key?(path)
160
+ cached_partial[path]
161
+ else
162
+ unparsed_file = context.registers[:site]
163
+ .liquid_renderer
164
+ .file(path)
165
+ begin
166
+ cached_partial[path] = unparsed_file.parse(read_file(path, context))
167
+ rescue Liquid::Error => e
168
+ e.template_name = path
169
+ e.markup_context = "included " if e.markup_context.nil?
170
+ raise e
171
+ end
172
+ end
173
+ end
174
+
175
+ def valid_include_file?(path, dir, safe)
176
+ !outside_site_source?(path, dir, safe) && File.file?(path)
177
+ end
178
+
179
+ def outside_site_source?(path, dir, safe)
180
+ safe && !realpath_prefixed_with?(path, dir)
181
+ end
182
+
183
+ def realpath_prefixed_with?(path, dir)
184
+ File.exist?(path) && File.realpath(path).start_with?(dir)
185
+ rescue StandardError
186
+ false
187
+ end
188
+
189
+ # This method allows to modify the file content by inheriting from the class.
190
+ def read_file(file, context)
191
+ File.read(file, file_read_opts(context))
192
+ end
193
+
194
+ private
195
+
196
+ def could_not_locate_message(file, includes_dirs, safe)
197
+ message = "Could not locate the included file '#{file}' in any of "\
198
+ "#{includes_dirs}. Ensure it exists in one of those directories and"
199
+ message + if safe
200
+ " is not a symlink as those are not allowed in safe mode."
201
+ else
202
+ ", if it is a symlink, does not point outside your site source."
203
+ end
204
+ end
205
+ end
206
+
207
+ class IncludeRelativeTag < IncludeTag
208
+ def tag_includes_dirs(context)
209
+ Array(page_path(context)).freeze
210
+ end
211
+
212
+ def page_path(context)
213
+ if context.registers[:page].nil?
214
+ context.registers[:site].source
215
+ else
216
+ current_doc_dir = File.dirname(context.registers[:page]["path"])
217
+ context.registers[:site].in_source_dir current_doc_dir
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+
224
+ Liquid::Template.register_tag("include", Jekyll::Tags::IncludeTag)
225
+ Liquid::Template.register_tag("include_relative", Jekyll::Tags::IncludeRelativeTag)
@@ -0,0 +1,40 @@
1
+ require 'haml'
2
+
3
+ module Jekyll
4
+ module Haml
5
+ class Parser
6
+
7
+ def initialize(config)
8
+ unless defined?(Haml)
9
+ Jekyll::External.require_with_graceful_fail "haml"
10
+ end
11
+ @config = config["lib-haml"] || {}
12
+ setup
13
+ end
14
+
15
+ def setup
16
+ make_accessible
17
+ end
18
+
19
+ def convert(content)
20
+ document = ::Haml::Engine.new(content, @config)
21
+ html_output = document.render
22
+ if @config["show_warnings"]
23
+ document.warnings.each do |warning|
24
+ Jekyll.logger.warn "Haml warning:", warning
25
+ end
26
+ end
27
+ html_output
28
+ end
29
+
30
+ private
31
+ def make_accessible(hash = @config)
32
+ hash.keys.each do |key|
33
+ hash[key.to_sym] = hash[key]
34
+ make_accessible(hash[key]) if hash[key].is_a?(Hash)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ require "jekyll/haml/version"
2
+
3
+ require_relative 'converters/haml'
4
+ require_relative 'haml/parser'
5
+ require_relative 'tags/include'
6
+ require_relative 'configuration'
7
+ require_relative 'convertible'
8
+ require_relative 'excerpt'
9
+ require_relative 'haml_renderer'
10
+ require_relative 'renderer'
11
+ require_relative 'site'
@@ -0,0 +1,54 @@
1
+ module Jekyll
2
+ class HamlRenderer
3
+ class File
4
+ def initialize(renderer, filename)
5
+ @renderer = renderer
6
+ @filename = filename
7
+ end
8
+
9
+ def parse(content)
10
+ measure_time do
11
+ @template = ::Haml::Engine.new(content) #, :line_numbers => true)
12
+ end
13
+
14
+ self
15
+ end
16
+
17
+ def render(*args)
18
+ measure_time do
19
+ measure_bytes do
20
+ @template.render(*args)
21
+ end
22
+ end
23
+ end
24
+
25
+ def render!(*args)
26
+ measure_time do
27
+ measure_bytes do
28
+ @template = @template.render(*args)
29
+ end
30
+ end
31
+ end
32
+
33
+ def warnings
34
+ [] # @template.warnings
35
+ end
36
+
37
+ private
38
+
39
+ def measure_bytes
40
+ yield.tap do |str|
41
+ @renderer.increment_bytes(@filename, str.bytesize)
42
+ end
43
+ end
44
+
45
+ def measure_time
46
+ before = Time.now
47
+ yield
48
+ ensure
49
+ after = Time.now
50
+ @renderer.increment_time(@filename, after - before)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,94 @@
1
+ module Jekyll
2
+ class HamlRenderer::Table
3
+ def initialize(stats)
4
+ @stats = stats
5
+ end
6
+
7
+ def to_s(n = 50)
8
+ data = data_for_table(n)
9
+ widths = table_widths(data)
10
+ generate_table(data, widths)
11
+ end
12
+
13
+ private
14
+
15
+ def generate_table(data, widths)
16
+ str = String.new("\n")
17
+
18
+ table_head = data.shift
19
+ str << generate_row(table_head, widths)
20
+ str << generate_table_head_border(table_head, widths)
21
+
22
+ data.each do |row_data|
23
+ str << generate_row(row_data, widths)
24
+ end
25
+
26
+ str << "\n"
27
+ str
28
+ end
29
+
30
+ def generate_table_head_border(row_data, widths)
31
+ str = String.new("")
32
+
33
+ row_data.each_index do |cell_index|
34
+ str << "-" * widths[cell_index]
35
+ str << "-+-" unless cell_index == row_data.length - 1
36
+ end
37
+
38
+ str << "\n"
39
+ str
40
+ end
41
+
42
+ def generate_row(row_data, widths)
43
+ str = String.new("")
44
+
45
+ row_data.each_with_index do |cell_data, cell_index|
46
+ str << if cell_index.zero?
47
+ cell_data.ljust(widths[cell_index], " ")
48
+ else
49
+ cell_data.rjust(widths[cell_index], " ")
50
+ end
51
+
52
+ str << " | " unless cell_index == row_data.length - 1
53
+ end
54
+
55
+ str << "\n"
56
+ str
57
+ end
58
+
59
+ def table_widths(data)
60
+ widths = []
61
+
62
+ data.each do |row|
63
+ row.each_with_index do |cell, index|
64
+ widths[index] = [ cell.length, widths[index] ].compact.max
65
+ end
66
+ end
67
+
68
+ widths
69
+ end
70
+
71
+ def data_for_table(n)
72
+ sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
73
+ sorted = sorted.slice(0, n)
74
+
75
+ table = [%w(Filename Count Bytes Time)]
76
+
77
+ sorted.each do |filename, file_stats|
78
+ row = []
79
+ row << filename
80
+ row << file_stats[:count].to_s
81
+ row << format_bytes(file_stats[:bytes])
82
+ row << format("%.3f", file_stats[:time])
83
+ table << row
84
+ end
85
+
86
+ table
87
+ end
88
+
89
+ def format_bytes(bytes)
90
+ bytes /= 1024.0
91
+ format("%.2fK", bytes)
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+ require 'jekyll/haml_renderer'
3
+ require_relative 'haml_renderer/file'
4
+ require_relative 'haml_renderer/table'
5
+
6
+ module Jekyll
7
+ class HamlRenderer
8
+ def initialize(site)
9
+ @site = site
10
+ # Haml::Template.error_mode = @site.config["haml"]["error_mode"].to_sym
11
+ reset
12
+ end
13
+
14
+ def reset
15
+ @stats = {}
16
+ end
17
+
18
+ def file(filename)
19
+ filename = @site.in_source_dir(filename).sub(
20
+ %r!\A#{Regexp.escape(@site.source)}/!,
21
+ ""
22
+ )
23
+
24
+ HamlRenderer::File.new(self, filename).tap do
25
+ @stats[filename] ||= new_profile_hash
26
+ @stats[filename][:count] += 1
27
+ end
28
+ end
29
+
30
+ def increment_bytes(filename, bytes)
31
+ @stats[filename][:bytes] += bytes
32
+ end
33
+
34
+ def increment_time(filename, time)
35
+ @stats[filename][:time] += time
36
+ end
37
+
38
+ def stats_table(n = 50)
39
+ HamlRenderer::Table.new(@stats).to_s(n)
40
+ end
41
+
42
+ def self.format_error(e, path)
43
+ "#{e.message} in #{path}"
44
+ end
45
+
46
+ private
47
+ def new_profile_hash
48
+ Hash.new { |hash, key| hash[key] = 0 }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,60 @@
1
+ require 'jekyll/renderer'
2
+
3
+ module Jekyll
4
+ class Renderer
5
+ def render_document
6
+ info = {
7
+ :registers => { :site => site, :page => payload["page"] },
8
+ }
9
+ output = document.content
10
+
11
+ if document.render_with_haml?
12
+ Jekyll.logger.debug "Rendering Haml:", document.relative_path
13
+ output = render_haml(output, payload, info, document.path)
14
+ end
15
+
16
+ if document.render_with_liquid?
17
+ Jekyll.logger.debug "Rendering Liquid:", document.relative_path
18
+ output = render_liquid(output, payload, info, document.path)
19
+ end
20
+
21
+ Jekyll.logger.debug "Rendering Markup:", document.relative_path
22
+ output = convert(output)
23
+ document.content = output
24
+
25
+ if document.place_in_layout?
26
+ Jekyll.logger.debug "Rendering Layout:", document.relative_path
27
+ output = place_in_layouts(output, payload, info)
28
+ end
29
+
30
+ output
31
+ end
32
+
33
+ def render_haml(content, payload, info, path = nil)
34
+ template = site.haml_renderer.file(path).parse(content)
35
+ template.warnings.each do |e|
36
+ Jekyll.logger.warn "Haml Warning:",
37
+ HamlRenderer.format_error(e, path || document.relative_path)
38
+ end
39
+ template.render!(payload, info)
40
+ end
41
+
42
+ private
43
+ def render_layout(output, layout, info)
44
+ payload["content"] = output
45
+ payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
46
+
47
+ if layout.render_with_haml?
48
+ Jekyll.logger.debug "Rendering Haml:", layout.relative_path
49
+ layout.content = ::Haml::Engine.new(layout.content).render
50
+ end
51
+
52
+ render_liquid(
53
+ layout.content,
54
+ payload,
55
+ info,
56
+ layout.relative_path
57
+ )
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,14 @@
1
+ require 'jekyll/site'
2
+
3
+ module Jekyll
4
+ class Site
5
+ attr_reader :haml_renderer
6
+
7
+ alias_method :pre_haml_initialize, :initialize
8
+
9
+ def initialize(config)
10
+ pre_haml_initialize(config)
11
+ @haml_renderer = HamlRenderer.new(self)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ require 'jekyll/tags/include'
2
+
3
+ # frozen_string_literal: true
4
+
5
+ module Jekyll
6
+ module Tags
7
+ class IncludeTag < Liquid::Tag
8
+
9
+ def read_file(file, context)
10
+ ::Haml::Engine.new(File.read(file, file_read_opts(context))).render
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Jekyll
2
+ module Haml
3
+ module Markup
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'jekyll-haml-markup/version'
2
+
3
+ require 'jekyll'
4
+
5
+ require_relative 'jekyll/converters/haml'
6
+ require_relative 'jekyll/haml/parser'
7
+ require_relative 'jekyll/tags/include'
8
+ require_relative 'jekyll/configuration'
9
+ require_relative 'jekyll/convertible'
10
+ require_relative 'jekyll/excerpt'
11
+ require_relative 'jekyll/haml_renderer'
12
+ require_relative 'jekyll/renderer'
13
+ require_relative 'jekyll/site'
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-haml-markup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alvaro Faundez
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-01-30 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: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
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
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jekyll
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.7'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: haml
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ description: Jekyll plugin that add the option to write layouts and partials in Haml.
84
+ email:
85
+ - alvaro@faundez.net
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - CODE_OF_CONDUCT.md
93
+ - Gemfile
94
+ - Gemfile.lock
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - jekyll-haml-markup.gemspec
101
+ - lib/jekyll-haml-markup.rb
102
+ - lib/jekyll-haml-markup/version.rb
103
+ - lib/jekyll/configuration.rb
104
+ - lib/jekyll/converters/haml.rb
105
+ - lib/jekyll/convertible.rb
106
+ - lib/jekyll/excerpt.rb
107
+ - lib/jekyll/haml.rb
108
+ - lib/jekyll/haml/include.rb
109
+ - lib/jekyll/haml/parser.rb
110
+ - lib/jekyll/haml_renderer.rb
111
+ - lib/jekyll/haml_renderer/file.rb
112
+ - lib/jekyll/haml_renderer/table.rb
113
+ - lib/jekyll/renderer.rb
114
+ - lib/jekyll/site.rb
115
+ - lib/jekyll/tags/include.rb
116
+ homepage: https://github.com/afaundez/jekyll-haml
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.6.14
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Jekyll plugin to use Haml on templates.
140
+ test_files: []