liquid_markdown 0.2.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +104 -0
- data/Rakefile +6 -0
- data/lib/liquid_markdown/converter/plain_text.rb +70 -0
- data/lib/liquid_markdown/core_ext/hash/keys.rb +173 -0
- data/lib/liquid_markdown/core_ext/string/strip.rb +15 -0
- data/lib/liquid_markdown/filters/text_filter.rb +5 -0
- data/lib/liquid_markdown/liquid/liquid_methods.rb +62 -0
- data/lib/liquid_markdown/render.rb +45 -0
- data/lib/liquid_markdown/resolver.rb +83 -0
- data/lib/liquid_markdown/template_handler.rb +41 -0
- data/lib/liquid_markdown/version.rb +3 -0
- data/lib/liquid_markdown.rb +21 -0
- data/liquid_markdown.gemspec +32 -0
- data/liquid_markdown.iml +48 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 45f8086f20ee4250420ca3654c2d33fa6def1938
|
4
|
+
data.tar.gz: 4b5765a5d6bbe9925b559321459acbab7dfc6663
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1f0162db51321fafb8cada8d21a32695f3dd9cd9db3dc33288f03e19ddf4a1b91b3e461ca533747c509ccd1a05ad13a95bac77e39fa4f26620c929c59484f1a6
|
7
|
+
data.tar.gz: d2faee0bb5c59f6ed2d0ddc6334840300d8b0519554a682c9480eb674cb0fe737bdeb183b2b60a276b2d910d54a143d83ac7d421f7eef548e1b7684a6ae0a786
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at gary@buzzware.com.au. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Gary McGhee
|
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,104 @@
|
|
1
|
+
# LiquidMarkdown
|
2
|
+
|
3
|
+
Combines [Liquid](https://github.com/Shopify/liquid) and [Markdown](https://daringfireball.net/projects/markdown/) templating
|
4
|
+
for generic templating and Rails Mailers.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'liquid_markdown'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install liquid_markdown
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
You can use `liquid_markdown` in your mailer with `.liqmd` file extension
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
# app/mailers/user_mailer.rb
|
28
|
+
class UserMailer < ApplicationMailer
|
29
|
+
def welcome(user)
|
30
|
+
@user = user
|
31
|
+
@lmVariables = @user.values
|
32
|
+
|
33
|
+
mail(to: @user.email, subject: 'liquid markdown layout') do |format|
|
34
|
+
format.html
|
35
|
+
format.text
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# app/views/user_mailer/welcome.liqmd
|
42
|
+
|
43
|
+
# Hello Admin
|
44
|
+
|
45
|
+
Below are the list of products that you purchased
|
46
|
+
|
47
|
+
<ul id="products">
|
48
|
+
<li>
|
49
|
+
<h2>{{ product.name }}</h2>
|
50
|
+
Only {{ product.price | price }}
|
51
|
+
</li>
|
52
|
+
</ul>
|
53
|
+
|
54
|
+
Thanks
|
55
|
+
------
|
56
|
+
ABC XYZ
|
57
|
+
```
|
58
|
+
|
59
|
+
We can compile Liquid templates manually using `html` to convert into html format and `text` to convert into plain text.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
lm = LiquidMarkdown::Render.new("Hello {{user.profile.name}}!", {user: {profile: {name: 'Bob'}}})
|
63
|
+
lm.html # => "<p>Hello Bob!</p>"
|
64
|
+
lm.text # => "Hello Bob!"
|
65
|
+
```
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
lm = LiquidMarkdown::Render.new("# my first heading")
|
69
|
+
lm.html # => "<h1>my first heading</h1>"
|
70
|
+
lm.text # => "my first heading"
|
71
|
+
```
|
72
|
+
|
73
|
+
We can combine both Liquid and Markdown together, Liquid will get compiled first and then Markdown will get compiled
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
lm = LiquidMarkdown::Render.new("# Hello {{username | upcase}}", {username: 'Admin'})
|
77
|
+
lm.html # => "<h1>Hello ADMIN</h1>"
|
78
|
+
lm.text # => "Hello ADMIN"
|
79
|
+
```
|
80
|
+
|
81
|
+
## Depricated (need to remove this)
|
82
|
+
We can also setup layout options to wrap result within that layout. use `{{yield}}` block in your template where we can render output.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
lm = LiquidMarkdown::Render.new("# Hello {{username | upcase}}", {username: 'Admin'})
|
86
|
+
lm.layout = "<html><head></head><body>{{yield}}</body></html>"
|
87
|
+
lm.html # => "<html><head></head><body><h1>Hello ADMIN</h1></body></html>"
|
88
|
+
```
|
89
|
+
|
90
|
+
## Development
|
91
|
+
|
92
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
93
|
+
|
94
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
95
|
+
|
96
|
+
## Contributing
|
97
|
+
|
98
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/buzzware/liquid_markdown. 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.
|
99
|
+
|
100
|
+
|
101
|
+
## License
|
102
|
+
|
103
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
104
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# https://github.com/gettalong/kramdown/pull/219/commits/8dbaf6e2987b283cf82594bae4e95c7ebd5d422d
|
4
|
+
#--
|
5
|
+
# Copyright (C) 2009-2014 Thomas Leitner <t_leitner@gmx.at>
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# This file is part of kramdown which is licensed under the MIT.
|
9
|
+
#++
|
10
|
+
#
|
11
|
+
|
12
|
+
require 'kramdown'
|
13
|
+
require 'kramdown/converter'
|
14
|
+
|
15
|
+
module Kramdown
|
16
|
+
module Converter
|
17
|
+
|
18
|
+
# Converts tree to plain text. Removes all formatting and attributes.
|
19
|
+
# This converter can be used to generate clean text for use in meta tags,
|
20
|
+
# plain text emails, etc.
|
21
|
+
class PlainText < Base
|
22
|
+
|
23
|
+
TEXT_TYPES ||= [
|
24
|
+
:smart_quote,
|
25
|
+
:typographic_sym,
|
26
|
+
:entity,
|
27
|
+
:text
|
28
|
+
].freeze
|
29
|
+
|
30
|
+
def initialize(root, options)
|
31
|
+
super
|
32
|
+
@plain_text = '' # bin for plain text
|
33
|
+
end
|
34
|
+
|
35
|
+
def convert(el)
|
36
|
+
type = el.type
|
37
|
+
category = ::Kramdown::Element.category(el)
|
38
|
+
|
39
|
+
@plain_text << convert_type(type, el) if TEXT_TYPES.include?(type)
|
40
|
+
@plain_text << "\n" if category == :block
|
41
|
+
|
42
|
+
el.children.each { |e| convert(e) }
|
43
|
+
|
44
|
+
@plain_text.strip if type == :root
|
45
|
+
end
|
46
|
+
|
47
|
+
def convert_type(type, el)
|
48
|
+
send("convert_#{type}", el)
|
49
|
+
end
|
50
|
+
|
51
|
+
def convert_text(el)
|
52
|
+
el.value
|
53
|
+
end
|
54
|
+
|
55
|
+
def convert_entity(el)
|
56
|
+
el.value.char
|
57
|
+
end
|
58
|
+
|
59
|
+
def convert_smart_quote(el)
|
60
|
+
smart_quote_entity(el).char
|
61
|
+
end
|
62
|
+
|
63
|
+
def convert_typographic_sym(el)
|
64
|
+
::Kramdown::Converter::Html::TYPOGRAPHIC_SYMS[el.value]
|
65
|
+
.map(&:char)
|
66
|
+
.join('')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# Extracted from rails
|
2
|
+
# https://raw.githubusercontent.com/rails/rails/master/activesupport/lib/active_support/core_ext/hash/keys.rb
|
3
|
+
|
4
|
+
class Hash
|
5
|
+
# Returns a new hash with all keys converted using the +block+ operation.
|
6
|
+
#
|
7
|
+
# hash = { name: 'Rob', age: '28' }
|
8
|
+
#
|
9
|
+
# hash.transform_keys { |key| key.to_s.upcase } # => {"NAME"=>"Rob", "AGE"=>"28"}
|
10
|
+
#
|
11
|
+
# If you do not provide a +block+, it will return an Enumerator
|
12
|
+
# for chaining with other methods:
|
13
|
+
#
|
14
|
+
# hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
|
15
|
+
def transform_keys
|
16
|
+
return enum_for(:transform_keys) { size } unless block_given?
|
17
|
+
result = {}
|
18
|
+
each_key do |key|
|
19
|
+
result[yield(key)] = self[key]
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
# Destructively converts all keys using the +block+ operations.
|
25
|
+
# Same as +transform_keys+ but modifies +self+.
|
26
|
+
def transform_keys!
|
27
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
28
|
+
keys.each do |key|
|
29
|
+
self[yield(key)] = delete(key)
|
30
|
+
end
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a new hash with all keys converted to strings.
|
35
|
+
#
|
36
|
+
# hash = { name: 'Rob', age: '28' }
|
37
|
+
#
|
38
|
+
# hash.stringify_keys
|
39
|
+
# # => {"name"=>"Rob", "age"=>"28"}
|
40
|
+
def stringify_keys
|
41
|
+
transform_keys(&:to_s)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Destructively converts all keys to strings. Same as
|
45
|
+
# +stringify_keys+, but modifies +self+.
|
46
|
+
def stringify_keys!
|
47
|
+
transform_keys!(&:to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a new hash with all keys converted to symbols, as long as
|
51
|
+
# they respond to +to_sym+.
|
52
|
+
#
|
53
|
+
# hash = { 'name' => 'Rob', 'age' => '28' }
|
54
|
+
#
|
55
|
+
# hash.symbolize_keys
|
56
|
+
# # => {:name=>"Rob", :age=>"28"}
|
57
|
+
def symbolize_keys
|
58
|
+
transform_keys { |key| key.to_sym rescue key }
|
59
|
+
end
|
60
|
+
alias_method :to_options, :symbolize_keys
|
61
|
+
|
62
|
+
# Destructively converts all keys to symbols, as long as they respond
|
63
|
+
# to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
|
64
|
+
def symbolize_keys!
|
65
|
+
transform_keys! { |key| key.to_sym rescue key }
|
66
|
+
end
|
67
|
+
alias_method :to_options!, :symbolize_keys!
|
68
|
+
|
69
|
+
# Validates all keys in a hash match <tt>*valid_keys</tt>, raising
|
70
|
+
# +ArgumentError+ on a mismatch.
|
71
|
+
#
|
72
|
+
# Note that keys are treated differently than HashWithIndifferentAccess,
|
73
|
+
# meaning that string and symbol keys will not match.
|
74
|
+
#
|
75
|
+
# { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
|
76
|
+
# { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
|
77
|
+
# { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
78
|
+
def assert_valid_keys(*valid_keys)
|
79
|
+
valid_keys.flatten!
|
80
|
+
each_key do |k|
|
81
|
+
unless valid_keys.include?(k)
|
82
|
+
raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns a new hash with all keys converted by the block operation.
|
88
|
+
# This includes the keys from the root hash and from all
|
89
|
+
# nested hashes and arrays.
|
90
|
+
#
|
91
|
+
# hash = { person: { name: 'Rob', age: '28' } }
|
92
|
+
#
|
93
|
+
# hash.deep_transform_keys{ |key| key.to_s.upcase }
|
94
|
+
# # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
|
95
|
+
def deep_transform_keys(&block)
|
96
|
+
_deep_transform_keys_in_object(self, &block)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Destructively converts all keys by using the block operation.
|
100
|
+
# This includes the keys from the root hash and from all
|
101
|
+
# nested hashes and arrays.
|
102
|
+
def deep_transform_keys!(&block)
|
103
|
+
_deep_transform_keys_in_object!(self, &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns a new hash with all keys converted to strings.
|
107
|
+
# This includes the keys from the root hash and from all
|
108
|
+
# nested hashes and arrays.
|
109
|
+
#
|
110
|
+
# hash = { person: { name: 'Rob', age: '28' } }
|
111
|
+
#
|
112
|
+
# hash.deep_stringify_keys
|
113
|
+
# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
|
114
|
+
def deep_stringify_keys
|
115
|
+
deep_transform_keys(&:to_s)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Destructively converts all keys to strings.
|
119
|
+
# This includes the keys from the root hash and from all
|
120
|
+
# nested hashes and arrays.
|
121
|
+
def deep_stringify_keys!
|
122
|
+
deep_transform_keys!(&:to_s)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns a new hash with all keys converted to symbols, as long as
|
126
|
+
# they respond to +to_sym+. This includes the keys from the root hash
|
127
|
+
# and from all nested hashes and arrays.
|
128
|
+
#
|
129
|
+
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
|
130
|
+
#
|
131
|
+
# hash.deep_symbolize_keys
|
132
|
+
# # => {:person=>{:name=>"Rob", :age=>"28"}}
|
133
|
+
def deep_symbolize_keys
|
134
|
+
deep_transform_keys { |key| key.to_sym rescue key }
|
135
|
+
end
|
136
|
+
|
137
|
+
# Destructively converts all keys to symbols, as long as they respond
|
138
|
+
# to +to_sym+. This includes the keys from the root hash and from all
|
139
|
+
# nested hashes and arrays.
|
140
|
+
def deep_symbolize_keys!
|
141
|
+
deep_transform_keys! { |key| key.to_sym rescue key }
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
# support methods for deep transforming nested hashes and arrays
|
146
|
+
def _deep_transform_keys_in_object(object, &block)
|
147
|
+
case object
|
148
|
+
when Hash
|
149
|
+
object.each_with_object({}) do |(key, value), result|
|
150
|
+
result[yield(key)] = _deep_transform_keys_in_object(value, &block)
|
151
|
+
end
|
152
|
+
when Array
|
153
|
+
object.map { |e| _deep_transform_keys_in_object(e, &block) }
|
154
|
+
else
|
155
|
+
object
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def _deep_transform_keys_in_object!(object, &block)
|
160
|
+
case object
|
161
|
+
when Hash
|
162
|
+
object.keys.each do |key|
|
163
|
+
value = object.delete(key)
|
164
|
+
object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
|
165
|
+
end
|
166
|
+
object
|
167
|
+
when Array
|
168
|
+
object.map! { |e| _deep_transform_keys_in_object!(e, &block) }
|
169
|
+
else
|
170
|
+
object
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class String
|
2
|
+
# Returns a new string after stripping all html tags
|
3
|
+
#
|
4
|
+
# string = "<hello>threre</hello>"
|
5
|
+
#
|
6
|
+
# string.strip_html_tags => "there"
|
7
|
+
def strip_html_tags
|
8
|
+
empty = ''.freeze
|
9
|
+
self.to_s
|
10
|
+
.gsub(/<script.*?<\/script>/m, empty)
|
11
|
+
.gsub(/<!--.*?-->/m, empty)
|
12
|
+
.gsub(/<style.*?<\/style>/m, empty)
|
13
|
+
.gsub(/<.*?>/m, empty)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright 2007 by Domizio Demichelis
|
2
|
+
# This library is free software. It may be used, redistributed and/or modified
|
3
|
+
# under the same terms as Ruby itself
|
4
|
+
#
|
5
|
+
# This extension is usesd in order to expose the object of the implementing class
|
6
|
+
# to liquid as it were a Drop. It also limits the liquid-callable methods of the instance
|
7
|
+
# to the allowed method passed with the liquid_methods call
|
8
|
+
# Example:
|
9
|
+
#
|
10
|
+
# class SomeClass
|
11
|
+
# liquid_methods :an_allowed_method
|
12
|
+
#
|
13
|
+
# def an_allowed_method
|
14
|
+
# 'this comes from an allowed method'
|
15
|
+
# end
|
16
|
+
# def unallowed_method
|
17
|
+
# 'this will never be an output'
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# if you want to extend the drop to other methods you can defines more methods
|
22
|
+
# in the class <YourClass>::LiquidDropClass
|
23
|
+
#
|
24
|
+
# class SomeClass::LiquidDropClass
|
25
|
+
# def another_allowed_method
|
26
|
+
# 'and this from another allowed method'
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# usage:
|
32
|
+
# @something = SomeClass.new
|
33
|
+
#
|
34
|
+
# template:
|
35
|
+
# {{something.an_allowed_method}}{{something.unallowed_method}} {{something.another_allowed_method}}
|
36
|
+
#
|
37
|
+
# output:
|
38
|
+
# 'this comes from an allowed method and this from another allowed method'
|
39
|
+
#
|
40
|
+
# You can also chain associations, by adding the liquid_method call in the
|
41
|
+
# association models.
|
42
|
+
#
|
43
|
+
class Module
|
44
|
+
|
45
|
+
def liquid_methods(*allowed_methods)
|
46
|
+
drop_class = eval "class #{self.to_s}::LiquidDropClass < Liquid::Drop; self; end"
|
47
|
+
define_method :to_liquid do
|
48
|
+
drop_class.new(self)
|
49
|
+
end
|
50
|
+
drop_class.class_eval do
|
51
|
+
def initialize(object)
|
52
|
+
@object = object
|
53
|
+
end
|
54
|
+
allowed_methods.each do |sym|
|
55
|
+
define_method sym do
|
56
|
+
@object.send sym
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module LiquidMarkdown
|
2
|
+
class Render
|
3
|
+
# setup your html layout layout to wrap around your LiquidMarkdown output
|
4
|
+
# layout = "<html><head></head><body>{{yield}}</body></html>"
|
5
|
+
attr_reader :template, :liquid_hash, :global_filter_proc
|
6
|
+
attr_writer :layout
|
7
|
+
attr_accessor :markdown_settings, :liquid_settings
|
8
|
+
|
9
|
+
def initialize(template, liquid_hash={})
|
10
|
+
@template = template
|
11
|
+
@liquid_hash = liquid_hash
|
12
|
+
@markdown_settings = {auto_ids: false, parse_block_html: true}
|
13
|
+
@liquid_settings = {strict_filters: true, strict_variables: true}
|
14
|
+
@global_filter_proc = ->(output) { output.is_a?(String) ? output.strip_html_tags : output }
|
15
|
+
end
|
16
|
+
|
17
|
+
def html
|
18
|
+
rendered_content = markdown(liquidize)
|
19
|
+
insert_into_template(rendered_content.to_html)
|
20
|
+
end
|
21
|
+
|
22
|
+
def text
|
23
|
+
rendered_content = markdown(liquidize)
|
24
|
+
rendered_content.to_plain_text
|
25
|
+
end
|
26
|
+
|
27
|
+
def markdown(template_value)
|
28
|
+
Kramdown::Document.new(template_value, @markdown_settings)
|
29
|
+
end
|
30
|
+
|
31
|
+
def liquidize
|
32
|
+
Liquid::Template.parse(@template)
|
33
|
+
.render(@liquid_hash, @liquid_settings, global_filter: @global_filter_proc)
|
34
|
+
end
|
35
|
+
|
36
|
+
def insert_into_template(rendered_content)
|
37
|
+
return rendered_content if layout == ''
|
38
|
+
layout.sub('{{yield}}', rendered_content)
|
39
|
+
end
|
40
|
+
|
41
|
+
def layout
|
42
|
+
@layout ||= ''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'panoramic/orm/active_record'
|
2
|
+
|
3
|
+
module LiquidMarkdown
|
4
|
+
class Resolver < ActionView::Resolver
|
5
|
+
require 'singleton'
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
# this method is mandatory to implement a Resolver
|
9
|
+
def find_templates(name, prefix, partial, details, key=nil, locals=[])
|
10
|
+
return [] if @@resolver_options[:only] && !@@resolver_options[:only].include?(prefix)
|
11
|
+
|
12
|
+
conditions = {
|
13
|
+
:path => build_path(name, prefix),
|
14
|
+
:locale => [normalize_array(details[:locale]).first, nil],
|
15
|
+
:format => normalize_array(details[:formats]),
|
16
|
+
:handler => normalize_array(details[:handlers]),
|
17
|
+
:partial => partial || false
|
18
|
+
}
|
19
|
+
|
20
|
+
@records = []
|
21
|
+
@@model.find_model_templates(conditions).map do |record|
|
22
|
+
@records << record
|
23
|
+
if record.format == 'html'
|
24
|
+
rec = OpenStruct.new(record.attributes)
|
25
|
+
rec.format = 'text'
|
26
|
+
@records << rec
|
27
|
+
else
|
28
|
+
rec = OpenStruct.new(record.attributes)
|
29
|
+
rec.format = 'html'
|
30
|
+
@records << rec
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@records.map do |record|
|
35
|
+
initialize_template(record, record.format)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Instantiate Resolver by passing a model (decoupled from ORMs)
|
40
|
+
def self.using(model, options={})
|
41
|
+
@@model = model
|
42
|
+
@@resolver_options = options
|
43
|
+
self.instance
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Initialize an ActionView::Template object based on the record found.
|
49
|
+
def initialize_template(record, format)
|
50
|
+
source = record.body
|
51
|
+
identifier = "#{record.class} - #{record.id} - #{record.path.inspect} (#{format})"
|
52
|
+
handler = ActionView::Template.registered_template_handler(record.handler)
|
53
|
+
|
54
|
+
details = {
|
55
|
+
:format => Mime[format],
|
56
|
+
:updated_at => record.updated_at,
|
57
|
+
:virtual_path => virtual_path(record.path, record.partial)
|
58
|
+
}
|
59
|
+
|
60
|
+
ActionView::Template.new(source, identifier, handler, details)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Build path with eventual prefix
|
64
|
+
def build_path(name, prefix)
|
65
|
+
prefix.present? ? "#{prefix}/#{name}" : name
|
66
|
+
end
|
67
|
+
|
68
|
+
# Normalize array by converting all symbols to strings.
|
69
|
+
def normalize_array(array)
|
70
|
+
array.map(&:to_s)
|
71
|
+
end
|
72
|
+
|
73
|
+
# returns a path depending if its a partial or template
|
74
|
+
def virtual_path(path, partial)
|
75
|
+
return path unless partial
|
76
|
+
if index = path.rindex("/")
|
77
|
+
path.insert(index + 1, "_")
|
78
|
+
else
|
79
|
+
"_#{path}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module LiquidMarkdown
|
2
|
+
module TemplateHandler
|
3
|
+
UNDERSCORE = '_'.freeze
|
4
|
+
OBJECT_ATTRIBUTE_MATCHER = /%\{([a-z0-9_]+\.[a-z0-9_]+)\}/i
|
5
|
+
|
6
|
+
def self.render(template, context, format)
|
7
|
+
variables = expand_variables(template, extract_variables(context))
|
8
|
+
liquid_variables = variables.deep_stringify_keys
|
9
|
+
lm = LiquidMarkdown::Render.new(template, liquid_variables)
|
10
|
+
lm.send(format)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.expand_variables(template, variables)
|
14
|
+
template.scan(OBJECT_ATTRIBUTE_MATCHER)
|
15
|
+
.map(&:first)
|
16
|
+
.each_with_object(variables) do |match, buffer|
|
17
|
+
target, attribute = match.split('.')
|
18
|
+
buffer[match.to_sym] = variables[target.to_sym].public_send(attribute)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.extract_variables(context)
|
23
|
+
context
|
24
|
+
.instance_variable_get(:@_assigns)
|
25
|
+
.each_with_object({}) do |(name, value), buffer|
|
26
|
+
next if name.start_with?(UNDERSCORE)
|
27
|
+
buffer[name.to_sym] = value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class LIQMD
|
32
|
+
def self.call(template)
|
33
|
+
if template.formats.include?(:html)
|
34
|
+
"LiquidMarkdown::TemplateHandler.render(#{template.source.inspect}, self, :html)"
|
35
|
+
else
|
36
|
+
"LiquidMarkdown::TemplateHandler.render(#{template.source.inspect}, self, :text)"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LiquidMarkdown
|
2
|
+
require 'kramdown'
|
3
|
+
require 'liquid'
|
4
|
+
require 'action_view'
|
5
|
+
require 'action_mailer'
|
6
|
+
|
7
|
+
require 'liquid_markdown/core_ext/hash/keys'
|
8
|
+
require 'liquid_markdown/core_ext/string/strip'
|
9
|
+
require 'liquid_markdown/liquid/liquid_methods'
|
10
|
+
|
11
|
+
require 'liquid_markdown/filters/text_filter'
|
12
|
+
require 'liquid_markdown/converter/plain_text'
|
13
|
+
|
14
|
+
require 'liquid_markdown/version'
|
15
|
+
require 'liquid_markdown/template_handler'
|
16
|
+
require 'liquid_markdown/render'
|
17
|
+
# require 'liquid_markdown/resolver' # don't automatically require this, as it requires panoramic - leave that for users to require themselves
|
18
|
+
end
|
19
|
+
|
20
|
+
ActionView::Template.register_template_handler :liqmd, LiquidMarkdown::TemplateHandler::LIQMD
|
21
|
+
Liquid::Template.register_filter(TextFilter)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'liquid_markdown/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'liquid_markdown'
|
8
|
+
spec.version = LiquidMarkdown::VERSION
|
9
|
+
spec.authors = ['Gary McGhee']
|
10
|
+
spec.email = ['gary@buzzware.com.au']
|
11
|
+
|
12
|
+
spec.summary = %q{Combines Liquid and Markdown templating for generic templating and Rails Mailers}
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = 'https://github.com/buzzware/liquid_markdown'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_runtime_dependency 'kramdown', '~> 1.12', '>= 1.12.0'
|
23
|
+
spec.add_dependency 'liquid', '~> 4.0', '>= 4.0.0'
|
24
|
+
spec.add_dependency 'actionmailer', '>= 4.0'
|
25
|
+
spec.add_dependency 'actionview', '>= 4.0'
|
26
|
+
spec.add_dependency 'panoramic', '~> 0.0.6'
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
|
+
spec.add_development_dependency 'pry-meta', '~> 0.0.10'
|
32
|
+
end
|
data/liquid_markdown.iml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
3
|
+
<component name="FacetManager">
|
4
|
+
<facet type="gem" name="Ruby Gem">
|
5
|
+
<configuration>
|
6
|
+
<option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
|
7
|
+
<option name="GEM_APP_TEST_PATH" value="$MODULE_DIR$/test" />
|
8
|
+
<option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
|
9
|
+
</configuration>
|
10
|
+
</facet>
|
11
|
+
</component>
|
12
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
13
|
+
<exclude-output />
|
14
|
+
<content url="file://$MODULE_DIR$">
|
15
|
+
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
16
|
+
<excludeFolder url="file://$MODULE_DIR$/.bundle" />
|
17
|
+
<excludeFolder url="file://$MODULE_DIR$/vendor/bundle" />
|
18
|
+
</content>
|
19
|
+
<orderEntry type="jdk" jdkName="RVM: ruby-2.2.5" jdkType="RUBY_SDK" />
|
20
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
21
|
+
<orderEntry type="library" scope="PROVIDED" name="actionmailer (v5.0.0.1, RVM: ruby-2.2.5) [gem]" level="application" />
|
22
|
+
<orderEntry type="library" scope="PROVIDED" name="actionview (v5.0.0.1, RVM: ruby-2.2.5) [gem]" level="application" />
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.14.6, RVM: ruby-2.2.5) [gem]" level="application" />
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="byebug (v9.0.6, RVM: ruby-2.2.5) [gem]" level="application" />
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="coderay (v1.1.1, RVM: ruby-2.2.5) [gem]" level="application" />
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, RVM: ruby-2.2.5) [gem]" level="application" />
|
27
|
+
<orderEntry type="library" scope="PROVIDED" name="kramdown (v1.12.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
28
|
+
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.0.3, RVM: ruby-2.2.5) [gem]" level="application" />
|
29
|
+
<orderEntry type="library" scope="PROVIDED" name="method_source (v0.8.2, RVM: ruby-2.2.5) [gem]" level="application" />
|
30
|
+
<orderEntry type="library" scope="PROVIDED" name="mime-types (v3.1, RVM: ruby-2.2.5) [gem]" level="application" />
|
31
|
+
<orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2016.0521, RVM: ruby-2.2.5) [gem]" level="application" />
|
32
|
+
<orderEntry type="library" scope="PROVIDED" name="mini_portile2 (v2.1.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
33
|
+
<orderEntry type="library" scope="PROVIDED" name="panoramic (v0.0.6, RVM: ruby-2.2.5) [gem]" level="application" />
|
34
|
+
<orderEntry type="library" scope="PROVIDED" name="pry (v0.10.4, RVM: ruby-2.2.5) [gem]" level="application" />
|
35
|
+
<orderEntry type="library" scope="PROVIDED" name="rack-test (v0.6.3, RVM: ruby-2.2.5) [gem]" level="application" />
|
36
|
+
<orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.0.3, RVM: ruby-2.2.5) [gem]" level="application" />
|
37
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v10.4.2, RVM: ruby-2.2.5) [gem]" level="application" />
|
38
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.5.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
39
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.5.2, RVM: ruby-2.2.5) [gem]" level="application" />
|
40
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.5.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
41
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.5.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
42
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.5.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
43
|
+
<orderEntry type="library" scope="PROVIDED" name="slop (v3.6.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
44
|
+
<orderEntry type="library" scope="PROVIDED" name="sprockets-rails (v3.2.0, RVM: ruby-2.2.5) [gem]" level="application" />
|
45
|
+
<orderEntry type="library" scope="PROVIDED" name="thor (v0.19.4, RVM: ruby-2.2.5) [gem]" level="application" />
|
46
|
+
<orderEntry type="library" scope="PROVIDED" name="websocket-extensions (v0.1.2, RVM: ruby-2.2.5) [gem]" level="application" />
|
47
|
+
</component>
|
48
|
+
</module>
|
metadata
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: liquid_markdown
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gary McGhee
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kramdown
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.12.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.12'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.12.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: liquid
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 4.0.0
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '4.0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 4.0.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: actionmailer
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '4.0'
|
60
|
+
type: :runtime
|
61
|
+
prerelease: false
|
62
|
+
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '4.0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: actionview
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '4.0'
|
74
|
+
type: :runtime
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '4.0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: panoramic
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.0.6
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 0.0.6
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: bundler
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '1.12'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - "~>"
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '1.12'
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rake
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '10.0'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '10.0'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: rspec
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '3.0'
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "~>"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '3.0'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: pry-meta
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 0.0.10
|
144
|
+
type: :development
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 0.0.10
|
151
|
+
description: Combines Liquid and Markdown templating for generic templating and Rails
|
152
|
+
Mailers
|
153
|
+
email:
|
154
|
+
- gary@buzzware.com.au
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- ".gitignore"
|
160
|
+
- ".rspec"
|
161
|
+
- ".travis.yml"
|
162
|
+
- CODE_OF_CONDUCT.md
|
163
|
+
- Gemfile
|
164
|
+
- LICENSE.txt
|
165
|
+
- README.md
|
166
|
+
- Rakefile
|
167
|
+
- lib/liquid_markdown.rb
|
168
|
+
- lib/liquid_markdown/converter/plain_text.rb
|
169
|
+
- lib/liquid_markdown/core_ext/hash/keys.rb
|
170
|
+
- lib/liquid_markdown/core_ext/string/strip.rb
|
171
|
+
- lib/liquid_markdown/filters/text_filter.rb
|
172
|
+
- lib/liquid_markdown/liquid/liquid_methods.rb
|
173
|
+
- lib/liquid_markdown/render.rb
|
174
|
+
- lib/liquid_markdown/resolver.rb
|
175
|
+
- lib/liquid_markdown/template_handler.rb
|
176
|
+
- lib/liquid_markdown/version.rb
|
177
|
+
- liquid_markdown.gemspec
|
178
|
+
- liquid_markdown.iml
|
179
|
+
homepage: https://github.com/buzzware/liquid_markdown
|
180
|
+
licenses:
|
181
|
+
- MIT
|
182
|
+
metadata: {}
|
183
|
+
post_install_message:
|
184
|
+
rdoc_options: []
|
185
|
+
require_paths:
|
186
|
+
- lib
|
187
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
197
|
+
requirements: []
|
198
|
+
rubyforge_project:
|
199
|
+
rubygems_version: 2.4.8
|
200
|
+
signing_key:
|
201
|
+
specification_version: 4
|
202
|
+
summary: Combines Liquid and Markdown templating for generic templating and Rails
|
203
|
+
Mailers
|
204
|
+
test_files: []
|