premonition 1.0.2 → 2.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5c6cb2b3b2a0a1819165e8f659d5155283ea02b2
4
- data.tar.gz: 93837406183c136e70a64481b8d7c6c1b8c5a3e9
2
+ SHA256:
3
+ metadata.gz: e9a29f7bec573bd93038e89e6d4c1abe04449288e8d359edad90df802e9fb80a
4
+ data.tar.gz: c2e036a85dfd010f8255017274efd32047d644e85edff6f1829ac3a03f08eb72
5
5
  SHA512:
6
- metadata.gz: 2bd2fade3e41a00033f9e08f12884284aa2abb2d9e7162ace82f73b9b2c27d17f23a9a4866ca135bfced8391ee3406aadd150c2e9f8d9fd0660a8f686e7355cf
7
- data.tar.gz: 2d8cc1b674470ed803e03d22ef67ed6f730a24a6cc3461f7d7d9a93c2a6420de9e48c9f52a23bc7011e4c5715da07feae2406258405ce3f46f1e5b8abadb228e
6
+ metadata.gz: 1cd9d612d1dd98610961f8b7f446591848639829b6b995b15f92701caca3f9a25ab048d4f4a800a43524f491ec1c8f5c097950713a3c47cc20b457bbbace3390
7
+ data.tar.gz: ad78680f73ac7f317cefd32f071a36b3616edb2d3a453b685f1ac57f642d88428ebcb595517c4a8a1beeb239b922262fc1d87cd43594ace997b5d53abf3a5081
data/README.md CHANGED
@@ -1,128 +1,174 @@
1
1
  # Premonition
2
- Premonition is a [Jekyll](https://jekyllrb.com/) extension that makes it possible to add block-styled Markdown side content to your documentation, for example summaries, notes, hints or warnings.
3
2
 
4
- It recognizes a special header in [block quotes](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#blockquotes) and converts then into html before the Markdown parser
5
- are run. As of now it only supports the [RedCarpet Markdown parser](https://github.com/vmg/redcarpet), but Kramdown support might be added in the future if requested.
3
+ **DEMO: https://amedia.github.io/premonition-demo/**
4
+
5
+ Premonition is a [Jekyll](https://jekyllrb.com/) extension that makes it possible to add block-styled content to your site in plain Markdown.
6
+
7
+ By adding a special header to the first line of a [block quote](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#blockquotes),
8
+ Premonition will transform it into a markup block of your choice.
9
+
10
+ <p align="center">
11
+ <img src="https://github.com/amedia/premonition/raw/master/screen.png" height="450"/>
12
+ </p>
6
13
 
7
14
  ## Features
8
15
 
9
- * Highly customizable
10
- * Non-intrusive - Content are rendered as block-quotes by any other parser
16
+ * Highly customizable (Create your own styles and templates easily)
17
+ * Non-intrusive - Content are presented as block-quotes by any other renderer.
11
18
  * Easy to install
19
+ * Comes with a stylesheet (Sass/Css) and templates for rendering typical information boxes.
20
+ * Support for both Kramdown and RedCarpet.
12
21
 
13
22
  ## Requirements
14
23
 
15
- * Redcarpet
16
24
  * Jekyll 3.7.x or higher
25
+ * FontAwesome 4.x (If you are using the default template and styles)
17
26
 
18
27
  ## Installation
19
28
 
20
- Add the following line to your `Gemfile` inside your Jekyll project. It should look something like this, depending on your Jekyll version:
29
+ Add the following line to your `Gemfile`:
21
30
 
22
31
  ```
23
- gem "redcarpet"
24
32
  group :jekyll_plugins do
25
- gem "premonition", "~> 1.0.0"
33
+ gem "premonition", "~> 2.0.0"
26
34
  end
27
35
  ```
28
- As Premonition depends on Redcarpet, you must make sure this dependency is added as well.
29
36
 
30
- Then add Premonition to `plugins` inside the Jekyll config file (`_config.yml`):
37
+ Then add Premonition to `plugins` in `_config.yml`:
31
38
 
32
39
  ```yaml
33
40
  plugins:
34
41
  - premonition
35
42
  ```
36
43
 
44
+ Finally run `bundle install`
45
+
37
46
  ## Usage
38
47
 
39
- Premonition blocks are really just standard Markdown block quote where the first line must follow a
48
+ Premonition blocks are really just a standard Markdown blockquote where the first line must be on a
40
49
  special format to activate the transformation.
41
50
 
42
51
  `> [type] "Title"`
43
52
 
44
- The type can be any letter string. It is used to map a block to type configuration. This enables
45
- you to customize the look of different types. Like *Info*, *Warning* and *Error* boxes for example.
46
- By default the type will be added to the surrounding `<div>` block of the generated html code.
53
+ The type can be any letter string. It is used to map a block to its type configuration and/or css.
54
+ By default the type will be added as a class to the outer `<div>` of the
55
+ generated markup.
56
+
57
+ Default types are:
47
58
 
48
- The *Title* is as you might have guessed the title that will be added to the block.
59
+ * note
60
+ * info
61
+ * warning
62
+ * error
63
+
64
+ The *Title* is the box header. It can be left empty to disable the box header:
65
+
66
+ ~~~markdown
67
+ > warning ""
68
+ > No headers in here
69
+ ~~~
49
70
 
50
71
  Example:
51
72
 
52
73
  ~~~markdown
53
74
  > warning "I am a warning"
54
- > The body of the warning goes here. Premonition also allow you to write Markdown inside the block.
75
+ > The body of the warning goes here. Premonition allows you to write any `Markdown` inside the block.
55
76
  ~~~
56
77
 
57
- This will be converted into something like this bu Premonition
78
+ Premonition will then convert this into something like:
58
79
 
59
80
  ~~~html
60
- <div class="premonition warning">
61
- <span class="header">Info</span>
62
- <p>The body of the warning goes here. Premonition also allow you to write Markdown inside the block.</p>
81
+ <div class="premonition info"><div class="fa fa-check-square"></div><div class="content"><p class="header">Info</p><p>The body of the warning goes here. Premonition also allow you to write Markdown inside the block.</p></div></div>
63
82
  ~~~
64
83
 
65
- The title can be omitted by providing an empty string . Like this:
84
+ You can change the markup into anything you like by adding your own template.
66
85
 
67
- ~~~markdown
68
- > warning ""
69
- > No headers in here
70
- ~~~
86
+ ## Configuration
71
87
 
72
- Now you can add some CSS styling.
88
+ The templates can be customized in two eays. Either by replacing the default template, or by adding a custom template to a type.
73
89
 
74
- ## Configuration
90
+ All this is done inside your `_config.yml`.
91
+
92
+ ### Templates
75
93
 
76
- If you don't like the markup that Premonition produces, then you can change it in two ways.
77
- Either by replacing the default template, or by configuring templates for each type.
94
+ Like Jekyll itself, Premonition uses the [Liquid Markup Language](https://github.com/Shopify/liquid) for its templates.
78
95
 
79
- All this are done inside your `_config.yml`
96
+ Five variables are available to the template engine:
80
97
 
81
- ### Replacing the default template
98
+ * *header* Boolean that tells you if a title exists and that a header should be added.
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`
103
+
104
+ Our default template:
105
+
106
+ ~~~html
107
+ <div class="premonition {{type}}">
108
+ <div class="fa {{meta.fa-icon}}"></div>
109
+ <div class="content">{% if header %}<p class="header">{{title}}</p>{% endif %}{{content}}</div></div>
110
+ ~~~
111
+
112
+ #### Overriding the default template
113
+
114
+ You can override the default template like this in your `_config.yml`:
82
115
 
83
116
  ```yaml
84
117
  premonition:
85
118
  default:
86
- template: '<div></i>%{header}%{content}</div>'
87
- header_template: '<span class="header">%{title}</span>'
119
+ template: 'Liquid template goes here'
88
120
  ```
89
121
 
90
- Please be aware of the placeholders inside the template. These placeholders will be replaced with
91
- the actual content of your block.
122
+ #### Overriding the template for a default type
92
123
 
93
- Available placeholders are
124
+ If you want to override the template for one of the default types (like note), do it like this:
94
125
 
95
- * *header* This is where the content from the header_template will be added if the title is not empty.
96
- * *content* This is where the rendered content of your block quote are added.
97
- * *title* This is where you block title will be added.
98
- * *type* The type name of the block.
126
+ ```yaml
127
+ premonition:
128
+ types:
129
+ - id: note
130
+ template: 'Liquid template goes here'
131
+ ```
99
132
 
100
133
  ### Adding custom types
101
134
 
102
- Sometimes you might want to have different markup for different block types. This can easily be done
103
- by adding types to your Premonition configuration inside `_config.yml`
135
+ Adding a custom type is just a matter of adding it to `_config.yml`. You can either override one
136
+ of the defaults, or add a new one.
137
+
138
+ For each type you can
139
+
140
+ * Add a custom template (template)
141
+ * Set a default title (default_title)
142
+ * Set meta data that can be used inside the template
143
+
144
+ Each type must have unique id (lowercase letters).
104
145
 
105
146
  ~~~yaml
106
147
  premonition:
107
- default:
108
- template: '<div></i>%{header}%{content}</div>'
109
- header_template: '<span class="header %{type}">%{title}</span>'
110
148
  types:
111
- - id: tip
112
- template: '<div class="alert alert-success" role=""><i class="fa fa-check-square-o"></i>%{header}%{content}</div>'
113
- - id: note
114
- template: '<div class="alert alert-info" role="alert"><i class="fa fa-info-circle"></i>%{header}%{content}</div>'
149
+ - id: custombox
150
+ meta:
151
+ fa-icon: fa-exclamation-circle
152
+ - id: advanced
153
+ template: 'Liquid template goes here'
154
+ default_title: 'MY BLOCK'
155
+ meta:
156
+ fa-icon: fa-exclamation-triangle
115
157
  ~~~
116
158
 
117
- NOTE: You cannot add a custom header_template to types at the moment. This will be fixed soon.
159
+ ## Styling
118
160
 
119
- #### Default titles
161
+ Premonition comes with a stylesheet you can copy into to your project. Either
162
+ as a Sass file or as plain css. The [Jekyll Documentation](https://jekyllrb.com/docs/assets/) describes the process in great details.
120
163
 
121
- You can add a default title to a type.
164
+ Download the stylesheet from here : https://github.com/amedia/premonition/tree/master/stylesheet
122
165
 
123
- ~~~yaml
124
- - id: tip
125
- template: '<div class="alert alert-success" role=""><i class="fa fa-check-square-o"></i>%{header}%{content}</div>'
126
- default_title: 'TIP!'
127
- ~~~
166
+ In order to get the fancy icons, you will have to add [Font Awesome](https://fontawesome.com/) to your html header file.
167
+ Be aware that you have to use v4.x of Font Awesome together with our CSS.
168
+
169
+ The easiest way to get startet with Font Awesome is to add this to your html header file:
170
+
171
+ ~~~html
172
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
173
+ ~~~~
128
174
 
@@ -1,4 +1,3 @@
1
- require 'redcarpet'
2
1
  require 'jekyll'
3
2
  require 'premonition/version'
4
3
  require 'premonition/resources'
@@ -3,28 +3,16 @@ module Jekyll
3
3
  class Hook < Generator
4
4
  safe true
5
5
  priority :low
6
- attr_reader :resources
7
6
 
8
7
  def initialize(p)
9
8
  super(p)
10
- unless defined?(Redcarpet)
11
- Jekyll::External.require_with_graceful_fail(
12
- "redcarpet (in #{__FILE__})"
13
- )
14
- end
15
9
  end
16
10
 
17
11
  def generate(site)
18
- @resources = Resources.new site
19
- Hooks.register :documents, :pre_render do |doc|
12
+ @resources = Resources.new site.config
13
+ Hooks.register [:documents, :pages], :pre_render do |doc|
20
14
  adder(doc)
21
15
  end
22
- Hooks.register :pages, :pre_render do |page|
23
- adder(page)
24
- end
25
- Hooks.register :posts, :pre_render do |page|
26
- adder(page)
27
- end
28
16
  end
29
17
 
30
18
  def adder(doc)
@@ -34,12 +22,12 @@ module Jekyll
34
22
  if blockquote?(l) && empty_block?(b)
35
23
  if (m = l.match(/^\>\s+([a-z]+)\s+\"(.*)\"$/i))
36
24
  y, t = m.captures
37
- b = { title: t.strip, type: y.strip.downcase, content: [] }
25
+ b = { 'title' => t.strip, 'type' => y.strip.downcase, 'content' => [] }
38
26
  else
39
27
  o << l
40
28
  end
41
29
  elsif blockquote?(l) && !empty_block?(b)
42
- b[:content] << l.match(/^\>(.*)$/i).captures[0].strip
30
+ b['content'] << l.match(/^\>\s?(.*)$/i).captures[0]
43
31
  else
44
32
  if !blockquote?(l) && !empty_block?(b)
45
33
  o << render_block(b)
@@ -61,37 +49,32 @@ module Jekyll
61
49
  end
62
50
 
63
51
  def render_block(b)
64
- t = create_templ(b)
65
- c = "#{@resources.renderer.render(b[:content].join("\n"))}\n\n"
66
- v = {
67
- title: t[:title],
68
- content: c,
69
- type: b[:type]
70
- }
71
- v[:header] = header(t[:title]) % v
72
- clean_markup(t[:template] % v)
73
- end
74
-
75
- def clean_markup(r)
76
- br = '<br>' * 2
77
- r = r.gsub('<p>', '').gsub('</p>', br).strip
78
- r = r.gsub(br, '') if r.scan(/<br><br>/m).size == 1
79
- r
80
- end
81
-
82
- def header(t)
83
- t.empty? ? '' : @resources.config[:default][:header_template]
52
+ t = create_resource(b)
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
+ )
84
65
  end
85
66
 
86
- def create_templ(b)
67
+ def create_resource(b)
87
68
  c = {
88
- template: @resources.config[:default][:template],
89
- title: @resources.config[:default][:title]
69
+ 'template' => @resources.config['default']['template'],
70
+ 'title' => @resources.config['default']['title'],
71
+ 'meta' => @resources.config['default']['meta']
90
72
  }
91
- @resources.config[:types].each do |t|
92
- next unless t[:id] == b[:type]
93
- c[:title] = b[:title].empty? ? t[:default_title] : b[:title]
94
- c[:template] = t[:template]
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?
95
78
  end
96
79
  c
97
80
  end
@@ -2,63 +2,71 @@ module Jekyll
2
2
  module Premonition
3
3
  class Resources
4
4
  attr_reader :config
5
- attr_reader :renderer
5
+ attr_reader :markdown
6
6
 
7
- def initialize(site)
8
- @config = load_config site
9
- @renderer = create_renderer site
7
+ def initialize(site_config)
8
+ @config = load site_config
9
+ @markdown = Converters::Markdown.new site_config
10
10
  end
11
11
 
12
- def create_renderer(site)
13
- hsh = {}
14
- ext_lookup(site).each { |a| hsh[a] = true }
15
- Redcarpet::Markdown.new(Redcarpet::Render::HTML, hsh)
16
- end
17
-
18
- def ext_lookup(site)
19
- ((site.config['redcarpet'] || {})['extensions'] || [])
20
- end
21
-
22
- def load_config(site)
23
- cfg = create_default_config
24
- prem = site.config['premonition'] || {}
25
- df = prem['default'] || {}
26
- cfg[:default][:template] = df['template'].strip unless df['template'].nil?
27
- cfg[:default][:header_template] = df['header_template'].strip unless df['header_template'].nil?
28
- cfg[:default][:title] = df['title'].strip unless df['title'].nil?
29
- unless prem['types'].nil?
30
- fail('types configuration must be an array') unless prem['types'].is_a?(Array)
31
- prem['types'].each { |t| cfg[:types] << load_config_type(t) }
32
- end
12
+ def load(site_config)
13
+ cfg = default_config
14
+ p = site_config['premonition'] || {}
15
+ df = p['default'] || {}
16
+ validate_defaults df, p
17
+ cfg['default']['template'] = df['template'].strip unless df['template'].nil?
18
+ cfg['default']['title'] = df['title'].strip unless df['title'].nil?
19
+ cfg['default']['meta'] = cfg['default']['meta'].merge(df['meta']) unless df['meta'].nil?
20
+ load_types p, cfg
33
21
  cfg
34
22
  end
35
23
 
36
- def load_config_type(t)
37
- validate_config_type(t)
24
+ def default_config
38
25
  {
39
- id: t['id'],
40
- template: t['template'].strip,
41
- default_title: (t['default_title'].nil? ? '' : t['default_title'].strip)
26
+ 'default' => {
27
+ 'template' => '<div class="premonition {{type}}"><div class="fa {{meta.fa-icon}}"></div>'\
28
+ '<div class="content">{% if header %}<p class="header">{{title}}</p>{% endif %}{{content}}</div></div>',
29
+ 'meta' => { 'fa-icon' => 'fa-check-square' },
30
+ 'title' => nil
31
+ },
32
+ 'types' => {
33
+ 'note' => { 'meta' => { 'fa-icon' => 'fa-check-square' } },
34
+ 'info' => { 'meta' => { 'fa-icon' => 'fa-info-circle' } },
35
+ 'warning' => { 'meta' => { 'fa-icon' => 'fa-exclamation-circle' } },
36
+ 'error' => { 'meta' => { 'fa-icon' => 'fa-exclamation-triangle' } }
37
+ }
42
38
  }
43
39
  end
44
40
 
45
- def validate_config_type(t)
46
- fail('id missing from type') if t['id'].nil?
47
- fail("id can only be lowercase letters: #{t['id']}") unless t['id'][/[a-z]+/] == t['id']
48
- fail('template missing from type') if t['template'].nil?
41
+ def validate_defaults(df, prem)
42
+ fail 'meta must be a hash' if !df['meta'].nil? && !df['meta'].is_a?(Hash)
43
+ fail 'types must be a hash' if !prem['types'].nil? && !prem['types'].is_a?(Hash)
49
44
  end
50
45
 
51
- def create_default_config
46
+ def load_types(p, cfg)
47
+ return if p['types'].nil?
48
+ p['types'].each do |id, obj|
49
+ t = type_config id, obj
50
+ cfg['types'][id] = cfg['types'][id].merge(t) unless cfg['types'][id].nil?
51
+ cfg['types'][id] = t if cfg['types'][id].nil?
52
+ end
53
+ end
54
+
55
+ def type_config(id, t)
56
+ validate_type(id, t)
52
57
  {
53
- default: {
54
- template: '<div class="premonition %{type}">%{header}%{content}</div>',
55
- header_template: ' <span class="header">%{title}</span>',
56
- title: 'Info'
57
- },
58
- types: []
58
+ 'template' => t['template'].nil? ? nil : t['template'].strip,
59
+ 'default_title' => t['default_title'].nil? || t['default_title'].empty? ? nil : t['default_title'].strip,
60
+ 'meta' => t['meta'].nil? ? {} : t['meta']
59
61
  }
60
62
  end
61
63
 
64
+ def validate_type(id, t)
65
+ fail 'id missing from type' if id.nil?
66
+ fail "id can only be lowercase letters: #{id}" unless id[/[a-z]+/] == id
67
+ fail 'meta must be an hash' if !t['meta'].nil? && !t['meta'].is_a?(Hash)
68
+ end
69
+
62
70
  def fail(msg)
63
71
  Jekyll.logger.error 'Fatal (Premonition):', msg
64
72
  raise LoadError, msg
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  module Premonition
3
- VERSION = '1.0.2'.freeze
3
+ VERSION = '2.0.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: premonition
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakob Vad Nielsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-06 00:00:00.000000000 Z
11
+ date: 2018-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '3.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: mocha
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: rake
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -59,19 +73,19 @@ dependencies:
59
73
  - !ruby/object:Gem::Version
60
74
  version: '0'
61
75
  - !ruby/object:Gem::Dependency
62
- name: rspec
76
+ name: turn
63
77
  requirement: !ruby/object:Gem::Requirement
64
78
  requirements:
65
- - - "~>"
79
+ - - ">="
66
80
  - !ruby/object:Gem::Version
67
- version: '3.0'
81
+ version: '0'
68
82
  type: :development
69
83
  prerelease: false
70
84
  version_requirements: !ruby/object:Gem::Requirement
71
85
  requirements:
72
- - - "~>"
86
+ - - ">="
73
87
  - !ruby/object:Gem::Version
74
- version: '3.0'
88
+ version: '0'
75
89
  description:
76
90
  email:
77
91
  - jakob.nielsen@amedia.no
@@ -107,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
121
  version: '0'
108
122
  requirements: []
109
123
  rubyforge_project:
110
- rubygems_version: 2.5.1
124
+ rubygems_version: 2.7.3
111
125
  signing_key:
112
126
  specification_version: 4
113
127
  summary: Jekyll generator that will convert special block quotes into message boxes.