premonition 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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.