premonition 2.0.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +158 -81
- data/lib/premonition.rb +10 -3
- data/lib/premonition/attributes/error.rb +32 -0
- data/lib/premonition/attributes/parser.rb +168 -0
- data/lib/premonition/attributes/stacker.rb +33 -0
- data/lib/premonition/commands/install_scss.rb +65 -0
- data/lib/premonition/hook.rb +27 -60
- data/lib/premonition/processor.rb +137 -0
- data/lib/premonition/resources.rb +65 -8
- data/lib/premonition/version.rb +4 -1
- metadata +73 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c3696b91551d20df8b09f16875aaffa95a1910c5dc5ded8b0706cee7c11f4a9a
|
|
4
|
+
data.tar.gz: 1e8544cacc2c1f7891bb5f1cb0b68ebf97babc923301fa2226f702ac175f6b65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9da70c269a26ed2b973677ee951512566314327b800f85884c505687572d6de2ca5733fb5917ae97977ff420c692bed4c96fb2631187f4b858d54174c0ae769f
|
|
7
|
+
data.tar.gz: 5fa694730310a0191792c921351bdc3b0de26f995b3c7e5df22b693ddcef91f6b2451705c4efac460cfa6770cae5062421ee4e1a09787bcfd1e31930ad98e4c4
|
data/README.md
CHANGED
|
@@ -1,113 +1,168 @@
|
|
|
1
1
|
# Premonition
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[Demo site](https://lazee.github.io/premonition-demo/) ([Source code](https://github.com/lazee/premonition-demo))
|
|
4
4
|
|
|
5
|
-
Premonition is a [Jekyll](https://jekyllrb.com/)
|
|
5
|
+
Premonition is a higly customizable [Jekyll](https://jekyllrb.com/) plugin that can convert Markdown block-quotes into beautiful block styled content.
|
|
6
6
|
|
|
7
|
-
By adding a
|
|
8
|
-
Premonition will transform it into a markup block of your choice.
|
|
7
|
+
By simply adding a custom header to the first line of a [block quote](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#blockquotes), Premonition will transform it into a markup block of your choice.
|
|
9
8
|
|
|
10
9
|
<p align="center">
|
|
11
|
-
<img src="https://github.com/lazee/premonition/raw/master/screen.png" height="
|
|
10
|
+
<img src="https://github.com/lazee/premonition/raw/master/screen.png" height="550"/>
|
|
12
11
|
</p>
|
|
13
12
|
|
|
14
13
|
## Features
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
- Highly customizable (Create your own styles and templates easily)
|
|
16
|
+
- Non-intrusive - Its just Markdown!
|
|
17
|
+
- Easy to install
|
|
18
|
+
- Comes with a default stylesheet (Sass/Css) and templates for beautiful messages boxes and citation.
|
|
19
|
+
- Font Awesome 5 support
|
|
20
|
+
|
|
21
|
+
## Version 4 Highlights
|
|
22
|
+
|
|
23
|
+
- Jekyll [Post Excerpts](https://jekyllrb.com/docs/posts/#post-excerpts) support
|
|
24
|
+
- New install command for the default stylesheet.
|
|
25
|
+
- [Kramdown reference links](https://kramdown.gettalong.org/quickref.html#links-and-images) support
|
|
26
|
+
- Jekyll 4 support (3.7 still supported)
|
|
27
|
+
- Added support for block attributes (See documentation further down)
|
|
28
|
+
- Added new citation block type.
|
|
29
|
+
- Minor fixes to the Premonition stylesheet.
|
|
30
|
+
- Removed the need Font Awesome css in default stylesheet, but
|
|
31
|
+
Font Awesome is still supported.
|
|
32
|
+
- Other bug fixes. See HISTORY.md.
|
|
33
|
+
|
|
34
|
+
See UPGRADE.md for help on how to upgrade from 2.x to 4.0.
|
|
21
35
|
|
|
22
36
|
## Requirements
|
|
23
37
|
|
|
24
|
-
|
|
25
|
-
* FontAwesome 4.x (If you are using the default template and styles)
|
|
38
|
+
- Jekyll 3.7.x or higher (We recommend the new Jekyll 4)
|
|
26
39
|
|
|
27
40
|
## Installation
|
|
28
41
|
|
|
29
|
-
Add the following line to your `Gemfile
|
|
42
|
+
Add the following line to your `Gemfile` inside your Jekyll project folder:
|
|
30
43
|
|
|
31
44
|
```
|
|
32
45
|
group :jekyll_plugins do
|
|
33
|
-
gem "premonition", "
|
|
46
|
+
gem "premonition", "4.0.0"
|
|
34
47
|
end
|
|
35
48
|
```
|
|
36
49
|
|
|
37
|
-
Then add
|
|
50
|
+
Then add the the plugin to your `_config.yml`:
|
|
38
51
|
|
|
39
52
|
```yaml
|
|
40
53
|
plugins:
|
|
41
|
-
|
|
54
|
+
- premonition
|
|
42
55
|
```
|
|
43
56
|
|
|
44
|
-
|
|
57
|
+
Now make sure to download the Premonition bundle:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
bundle install
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Installing the default stylesheet
|
|
64
|
+
|
|
65
|
+
Finally, if you want to use the default Premonition styling (You really should!), then you have to install the SASS stylesheet.
|
|
66
|
+
Note: The installer expect you to have installed SASS support like it is described in the Jekyll documentation: https://jekyllrb.com/docs/step-by-step/07-assets/#sass.
|
|
67
|
+
|
|
68
|
+
From your Jekyll project folder, run:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
bundle exec jekyll premonition-install
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This will add the `premonition.scss` file to your `_sass` folder and ask if you want to import this file into your `assets/main.scss` file.
|
|
75
|
+
Both of these settings (destination folder and main file) can be configured. Run `bundle exec jekyll premonition-install --help` to see how.
|
|
76
|
+
|
|
77
|
+
If you prefer CSS, then download the stylesheet/premonition.css file directly from this repo.
|
|
45
78
|
|
|
46
79
|
## Usage
|
|
47
80
|
|
|
48
|
-
Premonition
|
|
49
|
-
|
|
81
|
+
A Premonition block is really just a standard Markdown blockquote where the first line of the block must follow a certain syntax.
|
|
82
|
+
|
|
83
|
+
`> [type] "Title" [ attributes... ]`
|
|
84
|
+
|
|
85
|
+
The type must be set to one of the default Premonition block types, or a type
|
|
86
|
+
defined by you in `_config.yml`.
|
|
50
87
|
|
|
51
|
-
|
|
88
|
+
The default types are:
|
|
52
89
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
90
|
+
- note
|
|
91
|
+
- info
|
|
92
|
+
- warning
|
|
93
|
+
- error
|
|
94
|
+
- citation
|
|
56
95
|
|
|
57
|
-
|
|
96
|
+
The _Title_ will normally be the block header. Leave it empty to disable
|
|
97
|
+
the header.
|
|
58
98
|
|
|
59
|
-
|
|
60
|
-
* info
|
|
61
|
-
* warning
|
|
62
|
-
* error
|
|
99
|
+
_attributes_ are in use by the Citation type, but can be skipped for the other default types. See section about custom types for more info.
|
|
63
100
|
|
|
64
|
-
|
|
101
|
+
### Examples
|
|
65
102
|
|
|
66
|
-
|
|
67
|
-
|
|
103
|
+
Simple note with no header
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
> note ""
|
|
68
107
|
> No headers in here
|
|
69
|
-
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Note
|
|
111
|
+
|
|
112
|
+
```markdown
|
|
113
|
+
> note "I am a not"
|
|
114
|
+
> The body of the note goes here. Premonition allows you to write any `Markdown` inside the block.
|
|
115
|
+
```
|
|
70
116
|
|
|
71
|
-
|
|
117
|
+
Info
|
|
72
118
|
|
|
73
|
-
|
|
119
|
+
```markdown
|
|
120
|
+
> info "I am some info"
|
|
121
|
+
> The body of the info box goes here. Premonition allows you to write any `Markdown` inside the block.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Warning
|
|
125
|
+
|
|
126
|
+
```markdown
|
|
74
127
|
> warning "I am a warning"
|
|
75
|
-
> The body of the warning goes here. Premonition allows you to write any `Markdown` inside the block.
|
|
76
|
-
|
|
128
|
+
> The body of the warning box goes here. Premonition allows you to write any `Markdown` inside the block.
|
|
129
|
+
```
|
|
77
130
|
|
|
78
|
-
|
|
131
|
+
Error
|
|
79
132
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
133
|
+
```markdown
|
|
134
|
+
> error "I am an error"
|
|
135
|
+
> The body of the error box goes here. Premonition allows you to write any `Markdown` inside the block.
|
|
136
|
+
```
|
|
83
137
|
|
|
84
|
-
|
|
138
|
+
Citation (Note the use of attributes here)
|
|
139
|
+
|
|
140
|
+
```markdown
|
|
141
|
+
> citations "Mark Twain" [ cite = "mt" ]
|
|
142
|
+
> I will be a beautiful citation quote
|
|
143
|
+
```
|
|
85
144
|
|
|
86
145
|
## Configuration
|
|
87
146
|
|
|
88
|
-
The templates can be customized in two eays. Either by replacing the default
|
|
147
|
+
The templates can be customized in two eays. Either by replacing one of the default templates, or by adding a new type from scratch.
|
|
89
148
|
|
|
90
|
-
All this is done inside your `_config.yml`.
|
|
149
|
+
All this is done inside your `_config.yml`. Look at the [source code for our demo site](https://github.com/lazee/premonition-demo), for live examples on how configuration can be done.
|
|
91
150
|
|
|
92
151
|
### Templates
|
|
93
152
|
|
|
94
|
-
Like Jekyll itself, Premonition uses the [Liquid Markup Language](https://github.com/Shopify/liquid) for
|
|
95
|
-
|
|
96
|
-
Five variables are available to the template engine:
|
|
153
|
+
Like Jekyll itself, Premonition uses the [Liquid Markup Language](https://github.com/Shopify/liquid) for templating.
|
|
97
154
|
|
|
98
|
-
|
|
99
|
-
* *content* The rendered content for your block.
|
|
100
|
-
* *title* The block title.
|
|
101
|
-
* *type* The type name (eg: note).
|
|
102
|
-
* *meta* This is a hash that can contain any properties you would like to make available to your template. It is configured in `_config.yml`
|
|
155
|
+
Six variables are available to the template engine:
|
|
103
156
|
|
|
104
|
-
|
|
157
|
+
- _header_ Boolean that tells you if a title exists and that a header should be added.
|
|
158
|
+
- _content_ The rendered content for your block.
|
|
159
|
+
- _title_ The block title.
|
|
160
|
+
- _type_ The type name (eg: note).
|
|
161
|
+
- _meta_ This is a hash that can contain any properties you would like to make available to your template. It is configured in `_config.yml`
|
|
162
|
+
- _attrs_ These are the attributes set in the block header. Like we did in the Citation example above.
|
|
105
163
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<div class="fa {{meta.fa-icon}}"></div>
|
|
109
|
-
<div class="content">{% if header %}<p class="header">{{title}}</p>{% endif %}{{content}}</div></div>
|
|
110
|
-
~~~
|
|
164
|
+
Take a look at our default template inside `lib/premonition/resources.rb` to
|
|
165
|
+
get an idea of how this is done.
|
|
111
166
|
|
|
112
167
|
#### Overriding the default template
|
|
113
168
|
|
|
@@ -116,7 +171,7 @@ You can override the default template like this in your `_config.yml`:
|
|
|
116
171
|
```yaml
|
|
117
172
|
premonition:
|
|
118
173
|
default:
|
|
119
|
-
template:
|
|
174
|
+
template: "Liquid template goes here"
|
|
120
175
|
```
|
|
121
176
|
|
|
122
177
|
#### Overriding the template for a default type
|
|
@@ -126,8 +181,8 @@ If you want to override the template for one of the default types (like note), d
|
|
|
126
181
|
```yaml
|
|
127
182
|
premonition:
|
|
128
183
|
types:
|
|
129
|
-
|
|
130
|
-
template:
|
|
184
|
+
note:
|
|
185
|
+
template: "Liquid template goes here"
|
|
131
186
|
```
|
|
132
187
|
|
|
133
188
|
### Adding custom types
|
|
@@ -137,38 +192,60 @@ of the defaults, or add a new one.
|
|
|
137
192
|
|
|
138
193
|
For each type you can
|
|
139
194
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
195
|
+
- Add a custom template (template)
|
|
196
|
+
- Set a default title (default_title)
|
|
197
|
+
- Set meta data that can be used inside the template
|
|
143
198
|
|
|
144
199
|
Each type must have unique id (lowercase letters).
|
|
145
200
|
|
|
146
|
-
|
|
201
|
+
```yaml
|
|
147
202
|
premonition:
|
|
148
203
|
types:
|
|
149
|
-
|
|
204
|
+
custombox:
|
|
150
205
|
meta:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
template:
|
|
154
|
-
default_title:
|
|
206
|
+
my-meta: "By myself"
|
|
207
|
+
advanced:
|
|
208
|
+
template: "Liquid template goes here"
|
|
209
|
+
default_title: "MY BLOCK"
|
|
155
210
|
meta:
|
|
156
|
-
|
|
157
|
-
|
|
211
|
+
my-meta: "By myself"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## More on styling
|
|
158
215
|
|
|
159
|
-
|
|
216
|
+
As described in the Installation section above, it is pretty easy to install the default stylesheet into your project.
|
|
217
|
+
But we recognize that this design probably isn't a perfect fit for everybody. Luckily you can modify it :)
|
|
160
218
|
|
|
161
|
-
|
|
162
|
-
|
|
219
|
+
Our recommendation is to install the default stylesheet and override it in another SASS file. This way it will be
|
|
220
|
+
easy to upgrade the default Stylesheet later without loosing your changes.
|
|
163
221
|
|
|
164
|
-
|
|
222
|
+
The [Jekyll Documentation](https://jekyllrb.com/docs/assets/) describes the process of adding your own SASS files in great details.
|
|
165
223
|
|
|
166
|
-
|
|
167
|
-
Be aware that you have to use v4.x of Font Awesome together with our CSS.
|
|
224
|
+
## Font Awesome support
|
|
168
225
|
|
|
169
|
-
|
|
226
|
+
Premonition 4.x no longer depends on Font Awesome for its default stylesheet.
|
|
227
|
+
But it is still supported.
|
|
170
228
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
229
|
+
To add Font Awesome support you should add something like this
|
|
230
|
+
to your head template file:
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.1/css/all.css">
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Feel free to install it any other way you prefer, as long as you follow their
|
|
237
|
+
[license](https://fontawesome.com/license/free).
|
|
238
|
+
|
|
239
|
+
Now you can swith to Font Awesome for any of the default types by adding
|
|
240
|
+
`fa-icon` to a types meta object. Let's say you want to replace the default error box icon with the beautiful `fa-bug` icon from Font Awesome.
|
|
241
|
+
|
|
242
|
+
Then just add this to your `_config.yml`:
|
|
243
|
+
|
|
244
|
+
```yml
|
|
245
|
+
premonition:
|
|
246
|
+
types:
|
|
247
|
+
error:
|
|
248
|
+
fa-icon: "fa-bug"
|
|
249
|
+
```
|
|
174
250
|
|
|
251
|
+
Simple as that :)
|
data/lib/premonition.rb
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'jekyll'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
require_relative 'premonition/commands/install_scss.rb'
|
|
5
|
+
require_relative 'premonition/attributes/error'
|
|
6
|
+
require_relative 'premonition/attributes/stacker'
|
|
7
|
+
require_relative 'premonition/attributes/parser'
|
|
8
|
+
require_relative 'premonition/version'
|
|
9
|
+
require_relative 'premonition/processor'
|
|
10
|
+
require_relative 'premonition/resources'
|
|
11
|
+
require_relative 'premonition/hook'
|
|
5
12
|
|
|
6
13
|
module Jekyll
|
|
7
14
|
module Premonition
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'strscan'
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Premonition
|
|
7
|
+
module Attributes
|
|
8
|
+
# Public: Custom error for Premonition attributes parser errors.
|
|
9
|
+
class ParserError < StandardError
|
|
10
|
+
# Initialize a new ParserError
|
|
11
|
+
#
|
|
12
|
+
# msg - The error message
|
|
13
|
+
# raw - The raw string send to the parser initially.
|
|
14
|
+
# Used for syntax error output. If nil syntax
|
|
15
|
+
# error output is skipped.
|
|
16
|
+
# pos - The buffer position when error was raised.
|
|
17
|
+
# Used in both error message and syntax error output
|
|
18
|
+
# if raw attribute is set.
|
|
19
|
+
def initialize(msg, raw = nil, pos = 0)
|
|
20
|
+
if raw.nil?
|
|
21
|
+
super(msg)
|
|
22
|
+
else
|
|
23
|
+
super("#{msg} [#{pos}:#{raw.length}]")
|
|
24
|
+
print "Attribute syntax error:\n #{raw}\n"
|
|
25
|
+
pos.times { print ' ' }
|
|
26
|
+
print "^\n"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'strscan'
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Premonition
|
|
7
|
+
module Attributes
|
|
8
|
+
# Public: Premonition block attributes parser.
|
|
9
|
+
#
|
|
10
|
+
# Parses attributes found in block headers like this:
|
|
11
|
+
# > "info" [ foo = abcd, bar = "zot", size = 3 ]
|
|
12
|
+
#
|
|
13
|
+
# The parser itself utilizes the StringScanner in ruby.
|
|
14
|
+
# Each character will be parsed, validated and pushed
|
|
15
|
+
# to a stack (array) according to the rules inside the
|
|
16
|
+
# parser itself.
|
|
17
|
+
#
|
|
18
|
+
# A stack object will be of a certain type:
|
|
19
|
+
#
|
|
20
|
+
# 0 : Outside an attributes block
|
|
21
|
+
# 1 : Inside an attributes block, but between keys or values
|
|
22
|
+
# 2 : Parsing an attribute key
|
|
23
|
+
# 3: Parsing an attribute value
|
|
24
|
+
#
|
|
25
|
+
# Upon parser errors a pretty syntax error will be printed to
|
|
26
|
+
# stdout, showing where the error is.
|
|
27
|
+
class Parser
|
|
28
|
+
# Get parsed attributes as a Hash
|
|
29
|
+
attr_reader :attributes
|
|
30
|
+
|
|
31
|
+
# Initialize a new Parser AND start parsing
|
|
32
|
+
#
|
|
33
|
+
# str - A string containing the attributes block to be parser.
|
|
34
|
+
def initialize(str)
|
|
35
|
+
@raw = str # Keeps th original string for later use
|
|
36
|
+
@buffer = StringScanner.new(str) # Create StringScanner buffer
|
|
37
|
+
@attributes = {} # Initialize the attributes hash
|
|
38
|
+
@stack = [Stacker.new(0)] # Initialize the parser stack with initial "state"
|
|
39
|
+
parse # Start parsing
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def parse
|
|
45
|
+
raise error('No attributes block found in given string') unless @raw.match(/^.*\[.*\].*/)
|
|
46
|
+
|
|
47
|
+
until @buffer.eos?
|
|
48
|
+
char = @buffer.getch
|
|
49
|
+
case @stack.last.type
|
|
50
|
+
when 0 # Outside block mode
|
|
51
|
+
push_stacker(1) if char == '['
|
|
52
|
+
when 1 # In between
|
|
53
|
+
parse_in_between(char)
|
|
54
|
+
when 2 # Key
|
|
55
|
+
parse_key(char)
|
|
56
|
+
when 3 # Value
|
|
57
|
+
parse_value(char)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def parse_in_between(char)
|
|
63
|
+
return if char == ' ' # Ignoring all spaces before, between and after keys and values.
|
|
64
|
+
|
|
65
|
+
if char == ']'
|
|
66
|
+
pop_attribute_from_stack
|
|
67
|
+
push_stacker(4)
|
|
68
|
+
elsif char == ','
|
|
69
|
+
raise error("Attribute separator ',' not allowed here.") if @attributes.length.zero?
|
|
70
|
+
push_stacker(2)
|
|
71
|
+
elsif char.match(/^[a-zA-z0-9\-_]$/)
|
|
72
|
+
push_stacker(2)
|
|
73
|
+
append_char(char)
|
|
74
|
+
else
|
|
75
|
+
raise error("Illegal character '#{char}' outside key and value")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def parse_key(char)
|
|
80
|
+
if char == '='
|
|
81
|
+
push_stacker(3)
|
|
82
|
+
value_mode('plain')
|
|
83
|
+
elsif char.match(/^[a-zA-z0-9\-_]$/)
|
|
84
|
+
append_char(char)
|
|
85
|
+
elsif char == ' '
|
|
86
|
+
m = @buffer.scan(/\s*\=\s*/)
|
|
87
|
+
raise error('Space not allowed inside attribute key') if m.nil?
|
|
88
|
+
push_stacker(3)
|
|
89
|
+
value_mode('plain')
|
|
90
|
+
else
|
|
91
|
+
raise error("Illegal character '#{char}' for attribute key")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def parse_value(char)
|
|
96
|
+
case char
|
|
97
|
+
when ']'
|
|
98
|
+
if plain_mode?
|
|
99
|
+
pop_attribute_from_stack
|
|
100
|
+
push_stacker(4)
|
|
101
|
+
end
|
|
102
|
+
when '"'
|
|
103
|
+
pop_attribute_from_stack unless plain_mode?
|
|
104
|
+
raise error('Illegal " found') unless @stack.last.value.nil? || @stack.last.value.empty?
|
|
105
|
+
value_mode('block')
|
|
106
|
+
when '\\'
|
|
107
|
+
raise error('Backslash is not allowed in unquoted values') if plain_mode?
|
|
108
|
+
raise error('Unsupported escaping of character inside string block') unless ['\\', '"'].include?(@buffer.peek(1))
|
|
109
|
+
append_char(@buffer.peek(1))
|
|
110
|
+
@buffer.pos += 1
|
|
111
|
+
when ','
|
|
112
|
+
if plain_mode?
|
|
113
|
+
pop_attribute_from_stack
|
|
114
|
+
push_stacker(1)
|
|
115
|
+
else
|
|
116
|
+
append_char(char)
|
|
117
|
+
end
|
|
118
|
+
when '='
|
|
119
|
+
raise error('Illegal use of equals character in unquoted value') if plain_mode?
|
|
120
|
+
append_char(char)
|
|
121
|
+
when ' '
|
|
122
|
+
if plain_mode?
|
|
123
|
+
raise error('Illegal spacing in unquoted value') if @buffer.check(/\s*[,\]]/).nil?
|
|
124
|
+
pop_attribute_from_stack
|
|
125
|
+
push_stacker(1)
|
|
126
|
+
else
|
|
127
|
+
append_char(char)
|
|
128
|
+
end
|
|
129
|
+
else
|
|
130
|
+
append_char(char)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def error(msg)
|
|
135
|
+
ParserError.new(msg, @raw, @buffer.pos)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def push_stacker(type)
|
|
139
|
+
@stack << Stacker.new(type)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def append_char(char)
|
|
143
|
+
@stack.last.append(char)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def pop_attribute_from_stack
|
|
147
|
+
v = @stack.pop
|
|
148
|
+
return if [0, 1, 2].include?(v.type) # Ignore these types from stack
|
|
149
|
+
k = @stack.pop
|
|
150
|
+
raise error("Expected key but got: #{k.value}, #{k.type}") unless k.type == 2
|
|
151
|
+
@attributes[k.value] = v.value
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def plain_mode?
|
|
155
|
+
@stack.last.meta['mode'] == 'plain'
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def block_mode?
|
|
159
|
+
@stack.last.meta['mode'] == 'block'
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def value_mode(str)
|
|
163
|
+
@stack.last.meta['mode'] = str
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'strscan'
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Premonition
|
|
7
|
+
module Attributes
|
|
8
|
+
# Instances of this class are pushed onto the parser stack upon parsing of block attributes.
|
|
9
|
+
class Stacker
|
|
10
|
+
# Get the string value from the stacker
|
|
11
|
+
attr_reader :value
|
|
12
|
+
# Get the stacker type. 0 = outside block, 1 = in_between, 2 = key, 3 = value
|
|
13
|
+
attr_reader :type
|
|
14
|
+
# Get and set meta attributes for stacker. Used for setting value mode.
|
|
15
|
+
attr_accessor :meta
|
|
16
|
+
|
|
17
|
+
# Initialize a new Stacker
|
|
18
|
+
#
|
|
19
|
+
# type - The stacker type
|
|
20
|
+
def initialize(type)
|
|
21
|
+
@value = nil
|
|
22
|
+
@type = type
|
|
23
|
+
@meta = {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Append a char to the stacker value
|
|
27
|
+
def append(char)
|
|
28
|
+
@value = @value.nil? ? char : "#{@value}#{char}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module Premonition
|
|
7
|
+
# Public: Premonition stylesheet installer command
|
|
8
|
+
#
|
|
9
|
+
# Jekyll command that will install the Premonition stylesheet and add it to the needed resource files.
|
|
10
|
+
class InstallScssCommand < Jekyll::Command
|
|
11
|
+
class << self
|
|
12
|
+
def init_with_program(prog)
|
|
13
|
+
prog.command(:"premonition-install") do |c|
|
|
14
|
+
c.syntax 'premonition-install [options]'
|
|
15
|
+
c.description 'Install Premonition SASS stylesheet into your Jekyll site.'
|
|
16
|
+
c.option 'dest', '-d DEST', 'Where premonition.scss should be stored. (defaults to _sass/)'
|
|
17
|
+
c.option 'main', '-m DEST', 'The path to your main SASS file (defaults to assets/main.scss)'
|
|
18
|
+
c.action do |args, opts|
|
|
19
|
+
Jekyll::Premonition::InstallScssCommand.process(args, opts)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def process(_args, opts)
|
|
25
|
+
puts '== Installing Premonition Stylesheet and resources =="'
|
|
26
|
+
puts '-- premonition.scss --'
|
|
27
|
+
dest = opts['dest'].nil? || opts['dest'].empty? ? './_sass/' : File.join(opts['dest'], '')
|
|
28
|
+
main = opts['main'].nil? || opts['main'].empty? ? './assets/css/styles.scss' : opts['main']
|
|
29
|
+
raise StandardError, "#{dest} folder does not exist. Create it manually, and run script again." unless Dir.exist?(dest)
|
|
30
|
+
raise StandardError, "#{main} does not exist" unless File.exist?(main)
|
|
31
|
+
|
|
32
|
+
uri = URI('https://raw.githubusercontent.com/lazee/premonition/master/stylesheet/premonition.scss')
|
|
33
|
+
pf = "#{dest}premonition.scss"
|
|
34
|
+
|
|
35
|
+
if File.exist?(pf)
|
|
36
|
+
print "You already have #{pf} installed. Continue? [Y/n]"
|
|
37
|
+
override = gets.chomp
|
|
38
|
+
raise StandardError, 'Aborted. No harm done.' if override == 'n'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
File.write(pf, Net::HTTP.get(uri))
|
|
42
|
+
puts "Saved stylesheet in #{pf}"
|
|
43
|
+
|
|
44
|
+
if File.readlines(main).grep(/\@import \"premonition\"/).any?
|
|
45
|
+
puts "#{main} already imports the Premonition stylesheet."
|
|
46
|
+
else
|
|
47
|
+
puts 'You must add Premonition to your main SASS file.'
|
|
48
|
+
print "Add '@import \"premonition\";' to end of #{main} now? [Y/n] "
|
|
49
|
+
add = gets.chomp
|
|
50
|
+
if add == 'n'
|
|
51
|
+
puts 'Ok. But then you will need to add it manually for the styling of Premonition to work.'
|
|
52
|
+
else
|
|
53
|
+
f = File.open(main, 'a')
|
|
54
|
+
f.write("\n@import \"premonition\";\n")
|
|
55
|
+
f.close
|
|
56
|
+
puts "Added Premonition stylesheet to #{main}."
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
rescue StandardError => e
|
|
60
|
+
puts "ERROR: #{e}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/premonition/hook.rb
CHANGED
|
@@ -1,82 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Jekyll
|
|
2
4
|
module Premonition
|
|
5
|
+
# Registers Premonition hooks in Jekyll.
|
|
6
|
+
#
|
|
7
|
+
# Two hooks are added. One general hook for pages and another special
|
|
8
|
+
# hook for dealing with excerpts within posts.
|
|
9
|
+
#
|
|
10
|
+
# This ladder is really a hack as we scan all Markdown files and insert the
|
|
11
|
+
# excerpt ourselves in the document data. Unfortunately Jekyll prepares
|
|
12
|
+
# the excerpt way to early in the process, preventing us from hooking
|
|
13
|
+
# into it in a prober way. We only support excerpts if the excerpt_separator
|
|
14
|
+
# is explicitly set: https://jekyllrb.com/docs/posts/#post-excerpts
|
|
3
15
|
class Hook < Generator
|
|
4
16
|
safe true
|
|
5
|
-
priority :
|
|
17
|
+
priority :high
|
|
6
18
|
|
|
7
19
|
def initialize(p)
|
|
8
20
|
super(p)
|
|
9
21
|
end
|
|
10
22
|
|
|
11
23
|
def generate(site)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
adder(doc)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
24
|
+
resources = Resources.new site.config
|
|
25
|
+
processor = Processor.new resources
|
|
17
26
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if blockquote?(l) && empty_block?(b)
|
|
23
|
-
if (m = l.match(/^\s*\>\s+([a-z]+)\s+\"(.*)\"$/i))
|
|
24
|
-
y, t = m.captures
|
|
25
|
-
b = { 'title' => t.strip, 'type' => y.strip.downcase, 'content' => [] }
|
|
26
|
-
else
|
|
27
|
-
o << l
|
|
28
|
-
end
|
|
29
|
-
elsif blockquote?(l) && !empty_block?(b)
|
|
30
|
-
b['content'] << l.match(/^\s*\>\s?(.*)$/i).captures[0]
|
|
31
|
-
else
|
|
32
|
-
if !blockquote?(l) && !empty_block?(b)
|
|
33
|
-
o << render_block(b)
|
|
34
|
-
b = nil
|
|
35
|
-
end
|
|
36
|
-
o << l
|
|
27
|
+
Hooks.register [:posts], :pre_render do |doc|
|
|
28
|
+
if process?(resources, doc)
|
|
29
|
+
doc.content = processor.adder(doc.content)
|
|
30
|
+
doc.data['excerpt'] = Jekyll::Excerpt.new(doc) if generate_excerpt? doc
|
|
37
31
|
end
|
|
38
32
|
end
|
|
39
|
-
o << render_block(b) unless empty_block?(b)
|
|
40
|
-
doc.content = o.join
|
|
41
|
-
end
|
|
42
33
|
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
Hooks.register [:pages], :pre_render do |doc|
|
|
35
|
+
doc.content = processor.adder(doc.content) if process?(resources, doc)
|
|
36
|
+
end
|
|
45
37
|
end
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
b.nil?
|
|
49
|
-
end
|
|
39
|
+
private
|
|
50
40
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
c = "#{@resources.markdown.convert(b['content'].join("\n"))}\n\n"
|
|
54
|
-
template = Liquid::Template.parse(t['template'], error_mode: :strict)
|
|
55
|
-
template.render(
|
|
56
|
-
{
|
|
57
|
-
'header' => !t['title'].nil?,
|
|
58
|
-
'title' => t['title'],
|
|
59
|
-
'content' => c,
|
|
60
|
-
'type' => b['type'],
|
|
61
|
-
'meta' => t['meta']
|
|
62
|
-
},
|
|
63
|
-
strict_variables: true
|
|
64
|
-
)
|
|
41
|
+
def generate_excerpt?(doc)
|
|
42
|
+
!doc.data['excerpt_separator'].nil? && !doc.data['excerpt_separator'].empty?
|
|
65
43
|
end
|
|
66
44
|
|
|
67
|
-
def
|
|
68
|
-
|
|
69
|
-
'template' => @resources.config['default']['template'],
|
|
70
|
-
'title' => @resources.config['default']['title'],
|
|
71
|
-
'meta' => @resources.config['default']['meta']
|
|
72
|
-
}
|
|
73
|
-
@resources.config['types'].each do |id, t|
|
|
74
|
-
next unless id == b['type']
|
|
75
|
-
c['title'] = b['title'].empty? || b['title'].nil? ? t['default_title'] : b['title']
|
|
76
|
-
c['template'] = t['template'] unless t['template'].nil?
|
|
77
|
-
c['meta'] = c['meta'].merge(t['meta']) unless t['meta'].nil?
|
|
78
|
-
end
|
|
79
|
-
c
|
|
45
|
+
def process?(resources, doc)
|
|
46
|
+
resources.config['extensions'].include?(File.extname(doc.relative_path)[1..-1])
|
|
80
47
|
end
|
|
81
48
|
end
|
|
82
49
|
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module Premonition
|
|
5
|
+
# Class that does all of the rendering magic within Premonition.
|
|
6
|
+
class Processor
|
|
7
|
+
def initialize(resources)
|
|
8
|
+
@resources = resources
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Called by the registered pre_render hooks.
|
|
12
|
+
#
|
|
13
|
+
# This function takes markdown content as input and converts
|
|
14
|
+
# all the block quotes, with a Premonition header, into html.
|
|
15
|
+
#
|
|
16
|
+
# content - Markdown content
|
|
17
|
+
def adder(content)
|
|
18
|
+
o = []
|
|
19
|
+
references = load_references(content)
|
|
20
|
+
b = nil
|
|
21
|
+
is_code_block = false
|
|
22
|
+
content.each_line do |l|
|
|
23
|
+
is_code_block = !is_code_block if code_block_line?(l)
|
|
24
|
+
if is_code_block
|
|
25
|
+
o << l
|
|
26
|
+
elsif blockquote?(l) && empty_block?(b)
|
|
27
|
+
if (m = l.to_s.match(/^\s*\>\s+([a-z]+)\s+\"(.*)\"\s+(\[.*\])?\s*$/i))
|
|
28
|
+
y, t, attrs = m.captures
|
|
29
|
+
b = { 'title' => t.strip, 'type' => y.strip.downcase, 'content' => [], 'attrs' => attrs }
|
|
30
|
+
else
|
|
31
|
+
o << l
|
|
32
|
+
end
|
|
33
|
+
elsif blockquote?(l) && !empty_block?(b)
|
|
34
|
+
b['content'] << l.to_s.match(/^\s*\>\s?(.*)$/i).captures[0]
|
|
35
|
+
else
|
|
36
|
+
if !blockquote?(l) && !empty_block?(b)
|
|
37
|
+
o << render_block(b, references)
|
|
38
|
+
b = nil
|
|
39
|
+
end
|
|
40
|
+
o << l
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
o << render_block(b, references) unless empty_block?(b)
|
|
44
|
+
o.join
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
# Find all the Kramdown reference name links.
|
|
50
|
+
# https://kramdown.gettalong.org/quickref.html#links-and-images
|
|
51
|
+
# https://github.com/lazee/premonition/issues/10
|
|
52
|
+
def load_references(content)
|
|
53
|
+
refs = ["\n"]
|
|
54
|
+
content.each_line do |l|
|
|
55
|
+
unless l.nil? || l == 0 || (l.is_a? String)
|
|
56
|
+
refs << l if l.to_s.strip!.match(/^\[.*\]:.*\".*\"$/i)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
refs
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def code_block_line?(line)
|
|
63
|
+
line.strip.start_with?('~~~') || line.strip.start_with?('```')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def blockquote?(line)
|
|
67
|
+
line.strip.start_with?('>')
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def empty_block?(block)
|
|
71
|
+
block.nil?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def render_block(block, references)
|
|
75
|
+
t = create_resource(block)
|
|
76
|
+
a = block['content'] + references
|
|
77
|
+
c = "#{@resources.markdown.convert(a.join("\n"))}\n\n"
|
|
78
|
+
attrs = {}
|
|
79
|
+
|
|
80
|
+
unless block['attrs'].nil?
|
|
81
|
+
parser = Jekyll::Premonition::Attributes::Parser.new(block['attrs'])
|
|
82
|
+
attrs = parser.attributes
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
template = Liquid::Template.parse(t['template'], error_mode: :strict)
|
|
86
|
+
template.render(
|
|
87
|
+
{
|
|
88
|
+
'header' => !t['title'].nil?,
|
|
89
|
+
'title' => t['title'],
|
|
90
|
+
'content' => c,
|
|
91
|
+
'type' => block['type'],
|
|
92
|
+
'meta' => t['meta'],
|
|
93
|
+
'attrs' => attrs
|
|
94
|
+
},
|
|
95
|
+
strict_variables: true
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def error_template
|
|
100
|
+
<<~TEMPLATE
|
|
101
|
+
<div class="premonition error">
|
|
102
|
+
<div class="fa {{meta.pn-icon}}"></div>
|
|
103
|
+
<div class="content">
|
|
104
|
+
<p class="header">PREMONITION ERROR: Invalid box type</p>
|
|
105
|
+
You have specified an invalid box type "{{type}}". You can customize your own box types in `_config.yml`.
|
|
106
|
+
See documentation for more help.
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
TEMPLATE
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def create_resource(block)
|
|
113
|
+
c = {
|
|
114
|
+
'template' => @resources.config['default']['template'],
|
|
115
|
+
'title' => @resources.config['default']['title'],
|
|
116
|
+
'meta' => @resources.config['default']['meta']
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
unless @resources.config['types'].include? block['type']
|
|
120
|
+
c['title'] = ''
|
|
121
|
+
c['meta'] = { 'pn-icon' => 'pn-error' }
|
|
122
|
+
c['template'] = error_template
|
|
123
|
+
return c
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
@resources.config['types'].each do |id, t|
|
|
127
|
+
next unless id == block['type']
|
|
128
|
+
|
|
129
|
+
c['title'] = block['title'].empty? || block['title'].nil? ? t['default_title'] : block['title']
|
|
130
|
+
c['template'] = t['template'] unless t['template'].nil?
|
|
131
|
+
c['meta'] = c['meta'].merge(t['meta']) unless t['meta'].nil?
|
|
132
|
+
end
|
|
133
|
+
c
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Jekyll
|
|
2
4
|
module Premonition
|
|
5
|
+
# Class for loading the Premonition configuration and preparing it for use.
|
|
3
6
|
class Resources
|
|
4
7
|
attr_reader :config
|
|
5
8
|
attr_reader :markdown
|
|
6
9
|
|
|
7
10
|
def initialize(site_config)
|
|
8
11
|
@config = load site_config
|
|
12
|
+
# Setup a new Markdown renderer.
|
|
9
13
|
@markdown = Converters::Markdown.new site_config
|
|
10
14
|
end
|
|
11
15
|
|
|
16
|
+
# Load the configuration of Premonition from Jekyll site configuration object.
|
|
12
17
|
def load(site_config)
|
|
13
18
|
cfg = default_config
|
|
14
19
|
p = site_config['premonition'] || {}
|
|
@@ -18,33 +23,69 @@ module Jekyll
|
|
|
18
23
|
cfg['default']['title'] = df['title'].strip unless df['title'].nil?
|
|
19
24
|
cfg['default']['meta'] = cfg['default']['meta'].merge(df['meta']) unless df['meta'].nil?
|
|
20
25
|
load_types p, cfg
|
|
26
|
+
load_extensions p, cfg
|
|
21
27
|
cfg
|
|
22
28
|
end
|
|
23
29
|
|
|
30
|
+
def default_template
|
|
31
|
+
<<~TEMPLATE
|
|
32
|
+
<div class="premonition {% if meta.style %}{{meta.style}} {% endif %}{{type}}">
|
|
33
|
+
<i class="{% if meta.fa-icon %}fas {{meta.fa-icon}}{% else %}premonition {{meta.pn-icon}}{% endif %}"></i>
|
|
34
|
+
<div class="content">
|
|
35
|
+
{% if header %}<p class="header">{{title}}</p>{% endif %}{{content}}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
TEMPLATE
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def citation_template
|
|
42
|
+
<<~TEMPLATE
|
|
43
|
+
<div class="premonition {% if meta.style %}{{meta.style}} {% endif %}{{type}}">
|
|
44
|
+
<i class="{% if meta.fa-icon %}fas {{meta.fa-icon}}{% else %}premonition {{meta.pn-icon}}{% endif %}"></i>
|
|
45
|
+
<blockquote class="content blockquote"{% if attrs.cite %} cite="{{attrs.cite}}"{% endif %}>
|
|
46
|
+
{{content}}
|
|
47
|
+
{% if header %}
|
|
48
|
+
<footer class="blockquote-footer">
|
|
49
|
+
<cite title="{{title}}">{{title}}</cite>
|
|
50
|
+
</footer>
|
|
51
|
+
{% endif %}
|
|
52
|
+
</blockquote>
|
|
53
|
+
</div>
|
|
54
|
+
TEMPLATE
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Setup the default configuration and types
|
|
24
58
|
def default_config
|
|
25
59
|
{
|
|
26
60
|
'default' => {
|
|
27
|
-
'template' =>
|
|
28
|
-
|
|
29
|
-
'meta' => { 'fa-icon' => 'fa-check-square' },
|
|
61
|
+
'template' => default_template,
|
|
62
|
+
'meta' => { 'pn-icon' => 'pn-square', 'fa-icon' => nil },
|
|
30
63
|
'title' => nil
|
|
31
64
|
},
|
|
32
65
|
'types' => {
|
|
33
|
-
'note' => { 'meta' => { '
|
|
34
|
-
'info' => { 'meta' => { '
|
|
35
|
-
'warning' => { 'meta' => { '
|
|
36
|
-
'error' => { 'meta' => { '
|
|
37
|
-
|
|
66
|
+
'note' => { 'meta' => { 'pn-icon' => 'pn-note' } },
|
|
67
|
+
'info' => { 'meta' => { 'pn-icon' => 'pn-info' } },
|
|
68
|
+
'warning' => { 'meta' => { 'pn-icon' => 'pn-warn' } },
|
|
69
|
+
'error' => { 'meta' => { 'pn-icon' => 'pn-error' } },
|
|
70
|
+
'citation' => { 'meta' => { 'pn-icon' => 'pn-quote' }, 'template' => citation_template }
|
|
71
|
+
},
|
|
72
|
+
'extensions' => %w[
|
|
73
|
+
md
|
|
74
|
+
markdown
|
|
75
|
+
]
|
|
38
76
|
}
|
|
39
77
|
end
|
|
40
78
|
|
|
79
|
+
# Basic configuration validation
|
|
41
80
|
def validate_defaults(df, prem)
|
|
42
81
|
fail 'meta must be a hash' if !df['meta'].nil? && !df['meta'].is_a?(Hash)
|
|
43
82
|
fail 'types must be a hash' if !prem['types'].nil? && !prem['types'].is_a?(Hash)
|
|
44
83
|
end
|
|
45
84
|
|
|
85
|
+
# Load extra Premonition types configured/overriden in _config.yml
|
|
46
86
|
def load_types(p, cfg)
|
|
47
87
|
return if p['types'].nil?
|
|
88
|
+
|
|
48
89
|
p['types'].each do |id, obj|
|
|
49
90
|
t = type_config id, obj
|
|
50
91
|
cfg['types'][id] = cfg['types'][id].merge(t) unless cfg['types'][id].nil?
|
|
@@ -52,6 +93,21 @@ module Jekyll
|
|
|
52
93
|
end
|
|
53
94
|
end
|
|
54
95
|
|
|
96
|
+
# Load extra extensions from config.
|
|
97
|
+
#
|
|
98
|
+
# We need this when looking for excerpts
|
|
99
|
+
def load_extensions(p, cfg)
|
|
100
|
+
return if p['extensions'].nil?
|
|
101
|
+
return unless p['extensions'].is_a?(Array)
|
|
102
|
+
return if p['extensions'].empty?
|
|
103
|
+
|
|
104
|
+
cfg['extensions'] = []
|
|
105
|
+
p['extensions'].each do |v|
|
|
106
|
+
cfg['extensions'] << v unless cfg['extensions'].include?(v)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Validate a configured type and return as type hash
|
|
55
111
|
def type_config(id, t)
|
|
56
112
|
validate_type(id, t)
|
|
57
113
|
{
|
|
@@ -61,6 +117,7 @@ module Jekyll
|
|
|
61
117
|
}
|
|
62
118
|
end
|
|
63
119
|
|
|
120
|
+
# Type validation
|
|
64
121
|
def validate_type(id, t)
|
|
65
122
|
fail 'id missing from type' if id.nil?
|
|
66
123
|
fail "id can only be lowercase letters: #{id}" unless id[/[a-z]+/] == id
|
data/lib/premonition/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,77 +1,125 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: premonition
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jakob Vad Nielsen
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-01-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: jekyll
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3.7'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '5.0'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '3.7'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
13
33
|
- !ruby/object:Gem::Dependency
|
|
14
34
|
name: bundler
|
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
|
16
36
|
requirements:
|
|
17
37
|
- - "~>"
|
|
18
38
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
39
|
+
version: 2.1.4
|
|
20
40
|
type: :development
|
|
21
41
|
prerelease: false
|
|
22
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
43
|
requirements:
|
|
24
44
|
- - "~>"
|
|
25
45
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
46
|
+
version: 2.1.4
|
|
27
47
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
48
|
+
name: mocha
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 1.11.2
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 1.11.2
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: rake
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: 13.0.1
|
|
68
|
+
type: :development
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 13.0.1
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: rubocop
|
|
29
77
|
requirement: !ruby/object:Gem::Requirement
|
|
30
78
|
requirements:
|
|
31
79
|
- - ">="
|
|
32
80
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
81
|
+
version: 0.68.0
|
|
34
82
|
- - "<"
|
|
35
83
|
- !ruby/object:Gem::Version
|
|
36
|
-
version:
|
|
84
|
+
version: 0.72.0
|
|
37
85
|
type: :development
|
|
38
86
|
prerelease: false
|
|
39
87
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
88
|
requirements:
|
|
41
89
|
- - ">="
|
|
42
90
|
- !ruby/object:Gem::Version
|
|
43
|
-
version:
|
|
91
|
+
version: 0.68.0
|
|
44
92
|
- - "<"
|
|
45
93
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
94
|
+
version: 0.72.0
|
|
47
95
|
- !ruby/object:Gem::Dependency
|
|
48
|
-
name:
|
|
96
|
+
name: rubocop-jekyll
|
|
49
97
|
requirement: !ruby/object:Gem::Requirement
|
|
50
98
|
requirements:
|
|
51
99
|
- - "~>"
|
|
52
100
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
101
|
+
version: 0.10.0
|
|
54
102
|
type: :development
|
|
55
103
|
prerelease: false
|
|
56
104
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
105
|
requirements:
|
|
58
106
|
- - "~>"
|
|
59
107
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
108
|
+
version: 0.10.0
|
|
61
109
|
- !ruby/object:Gem::Dependency
|
|
62
|
-
name:
|
|
110
|
+
name: test-unit
|
|
63
111
|
requirement: !ruby/object:Gem::Requirement
|
|
64
112
|
requirements:
|
|
65
113
|
- - "~>"
|
|
66
114
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
115
|
+
version: 3.3.5
|
|
68
116
|
type: :development
|
|
69
117
|
prerelease: false
|
|
70
118
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
119
|
requirements:
|
|
72
120
|
- - "~>"
|
|
73
121
|
- !ruby/object:Gem::Version
|
|
74
|
-
version:
|
|
122
|
+
version: 3.3.5
|
|
75
123
|
- !ruby/object:Gem::Dependency
|
|
76
124
|
name: turn
|
|
77
125
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -86,7 +134,7 @@ dependencies:
|
|
|
86
134
|
- - "~>"
|
|
87
135
|
- !ruby/object:Gem::Version
|
|
88
136
|
version: 0.9.7
|
|
89
|
-
description:
|
|
137
|
+
description:
|
|
90
138
|
email:
|
|
91
139
|
- jakobvadnielsen@gmail.com
|
|
92
140
|
executables: []
|
|
@@ -97,14 +145,19 @@ files:
|
|
|
97
145
|
- LICENSE
|
|
98
146
|
- README.md
|
|
99
147
|
- lib/premonition.rb
|
|
148
|
+
- lib/premonition/attributes/error.rb
|
|
149
|
+
- lib/premonition/attributes/parser.rb
|
|
150
|
+
- lib/premonition/attributes/stacker.rb
|
|
151
|
+
- lib/premonition/commands/install_scss.rb
|
|
100
152
|
- lib/premonition/hook.rb
|
|
153
|
+
- lib/premonition/processor.rb
|
|
101
154
|
- lib/premonition/resources.rb
|
|
102
155
|
- lib/premonition/version.rb
|
|
103
156
|
homepage: http://github.com/lazee/premonition
|
|
104
157
|
licenses:
|
|
105
158
|
- MIT
|
|
106
159
|
metadata: {}
|
|
107
|
-
post_install_message:
|
|
160
|
+
post_install_message:
|
|
108
161
|
rdoc_options: []
|
|
109
162
|
require_paths:
|
|
110
163
|
- lib
|
|
@@ -120,8 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
120
173
|
- !ruby/object:Gem::Version
|
|
121
174
|
version: '0'
|
|
122
175
|
requirements: []
|
|
123
|
-
rubygems_version: 3.
|
|
124
|
-
signing_key:
|
|
176
|
+
rubygems_version: 3.1.2
|
|
177
|
+
signing_key:
|
|
125
178
|
specification_version: 4
|
|
126
179
|
summary: Jekyll generator that will convert special block quotes into message boxes.
|
|
127
180
|
test_files: []
|