jekyll-antex 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: acb00f8957a33f86919174a4e9ddf0371b285e50
4
+ data.tar.gz: 45f2fb9e89254c85dbe0f593c18ae6bc03f13060
5
+ SHA512:
6
+ metadata.gz: 29d722d3b106e2c7ec4c8cfd15c8ee0faa66d6c89e6d5cc6d1dca38acc8ad58fb500995c668af6d875896b7431174f736ca4fded6149a970f11d8cc41f0325cb
7
+ data.tar.gz: 7f38caaac8717756d3cf18c714fb91a5ba17b25c68848bd42d7e1ff79cb54ba161424719bcd0a26b8ce89398c451a60f623048aab79a0d36a45fce768d49d06f
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Paolo Brasolin
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,10 @@
1
+ # jekyll-antex
2
+
3
+ [![Build Status](https://travis-ci.org/paolobrasolin/jekyll-antex.svg?branch=master)](https://travis-ci.org/paolobrasolin/jekyll-antex)
4
+ [![Gem Version](https://badge.fury.io/rb/jekyll-antex.svg)](https://badge.fury.io/rb/jekyll-antex)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ [![Code Climate](https://codeclimate.com/github/paolobrasolin/jekyll-antex/badges/gpa.svg)](https://codeclimate.com/github/paolobrasolin/jekyll-antex)
8
+ [![Test Coverage](https://codeclimate.com/github/paolobrasolin/jekyll-antex/badges/coverage.svg)](https://codeclimate.com/github/paolobrasolin/jekyll-antex/coverage)
9
+ [![Inline docs](http://inch-ci.org/github/paolobrasolin/jekyll-antex.svg?branch=master)](http://inch-ci.org/github/paolobrasolin/jekyll-antex)
10
+ [![Issue Count](https://codeclimate.com/github/paolobrasolin/jekyll-antex/badges/issue_count.svg)](https://codeclimate.com/github/paolobrasolin/jekyll-antex)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll/antex/error'
4
+
5
+ module Jekyll
6
+ module Antex
7
+ class Alias
8
+ class InvalidRegexp < Error; end
9
+
10
+ attr_reader :priority, :regexp, :options
11
+
12
+ def initialize(priority:, regexp:, options: {})
13
+ @priority = priority.to_i
14
+ @regexp = Regexp.new regexp
15
+ validate_regexp!
16
+ @options = options.to_h
17
+ end
18
+
19
+ private
20
+
21
+ def validate_regexp!
22
+ return if @regexp.names.include? 'code'
23
+ raise InvalidRegexp, <<~MESSAGE
24
+ The regexp #{@regexp.inspect} is missing the required named matching group "code".
25
+ MESSAGE
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require 'liquid'
5
+ require 'antex'
6
+ require 'yaml'
7
+
8
+ require 'jekyll/antex/options'
9
+
10
+ module Jekyll
11
+ module Antex
12
+ class Block < Liquid::Block
13
+ def initialize(tag, markup, tokens)
14
+ @markup = markup
15
+ super
16
+ end
17
+
18
+ def render(context)
19
+ options = build_options registers: context.registers, markup: @markup
20
+ job = ::Antex::Job.new snippet: super, options: options
21
+ job.run!
22
+ add_static_file context.registers[:site], job
23
+ render_html job
24
+ end
25
+
26
+ private
27
+
28
+ def render_html(job)
29
+ _, dir, name = static_file_paths job
30
+ img_tag = render_img_tag src: File.join(dir, name),
31
+ set_box: job.set_box
32
+ classes = job.options['classes'].join(' ')
33
+ "<span class='#{classes}'>#{img_tag}</span>"
34
+ end
35
+
36
+ def render_img_tag(src:, set_box:, precision: 3)
37
+ <<~IMG_TAG.gsub(/(\s\s+)/m, ' ').strip!
38
+ <img style='margin: #{set_box.mt.round(precision)}ex
39
+ #{set_box.mr.round(precision)}ex
40
+ #{set_box.mb.round(precision)}ex
41
+ #{set_box.ml.round(precision)}ex;
42
+ height: #{set_box.th.round(precision)}ex;
43
+ width: #{set_box.wd.round(precision)}ex;'
44
+ src='#{src}' />
45
+ IMG_TAG
46
+ end
47
+
48
+ def add_static_file(site, job)
49
+ site.static_files << Jekyll::StaticFile.new(
50
+ site, *static_file_paths(job)
51
+ )
52
+ end
53
+
54
+ def static_file_paths(job)
55
+ work_dir_prefix = %r{^#{Regexp.escape job.dirs['work']}(?=\/|$)}
56
+ # base, dir, name
57
+ [
58
+ job.dirs['work'],
59
+ job.dirs['dest'].sub(work_dir_prefix, '').sub(%r{^\/}, ''),
60
+ File.basename(job.files['svg'])
61
+ ]
62
+ end
63
+
64
+ def build_options(registers:, markup:)
65
+ Jekyll::Antex::Options.build Jekyll::Antex::Options::DEFAULTS,
66
+ registers[:site].config['antex'] || {},
67
+ registers[:page]['antex'] || {},
68
+ YAML.safe_load(markup) || {}
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ Liquid::Template.register_tag('antex', Jekyll::Antex::Block)
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ require 'jekyll/antex/options'
6
+
7
+ module Jekyll
8
+ module Antex
9
+ class Dealiaser
10
+ attr_reader :aliases
11
+
12
+ def initialize(tag: 'antex')
13
+ @aliases = []
14
+ @stash = {}
15
+ @tag = tag
16
+ end
17
+
18
+ def add_aliases(aliases)
19
+ @aliases.concat(aliases).sort_by!(&:priority).reverse!
20
+ end
21
+
22
+ def parse(content)
23
+ @content = content.dup
24
+ @stash = {}
25
+ stash_aliases
26
+ render_stashed_aliases_as_tags
27
+ unstash_tags
28
+ @content
29
+ end
30
+
31
+ private
32
+
33
+ def stash_aliases
34
+ @aliases.each do |aliaz|
35
+ @content.gsub!(aliaz.regexp) do
36
+ uuid = SecureRandom.uuid
37
+ @stash.store uuid, match: Regexp.last_match, options: aliaz.options
38
+ uuid
39
+ end
40
+ end
41
+ end
42
+
43
+ def render_stashed_aliases_as_tags
44
+ @stash.each do |key, value|
45
+ @stash[key] = render_matched_alias_as_tag(**value)
46
+ end
47
+ end
48
+
49
+ def unstash_tags
50
+ @stash.each do |uuid, rendered_tag|
51
+ @content.gsub! uuid, rendered_tag
52
+ end
53
+ end
54
+
55
+ def render_matched_alias_as_tag(match:, options:)
56
+ markup = YAML.safe_load match[:markup] if match.names.include?('markup')
57
+ markup = YAML.dump Options.build(options || {}, markup || {})
58
+ code = match['code']
59
+ "{% #{@tag} #{markup} %}#{code}{% end#{@tag} %}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,120 @@
1
+ preamble: |
2
+ \usepackage{mathtools, amssymb}
3
+ \usepackage{tikz}
4
+ template: |
5
+ \documentclass{article}
6
+ \pagestyle{empty}
7
+ {{ preamble }}
8
+ \newsavebox\snippet
9
+ \begin{lrbox}{\snippet}{{ prepend }}{{ snippet }}{{ append }}\end{lrbox}
10
+ \newwrite\file
11
+ \immediate\openout\file=\jobname.yml
12
+ \immediate\write\file{em: \the\dimexpr1em}
13
+ \immediate\write\file{ex: \the\dimexpr1ex}
14
+ \immediate\write\file{ht: \the\ht\snippet}
15
+ \immediate\write\file{dp: \the\dp\snippet}
16
+ \immediate\write\file{wd: \the\wd\snippet}
17
+ \closeout\file
18
+ \begin{document}\usebox{\snippet}\end{document}
19
+ classes: [antex]
20
+ pipeline:
21
+ - latexmk
22
+ - dvisvgm_tfm
23
+ - dvisvgm_fit
24
+ - cp_to_dest
25
+ dirs:
26
+ work: .antex-cache
27
+ dest: .antex-cache/antex
28
+ files:
29
+ tex: "{{ dir.work }}/{{ hash }}.tex"
30
+ dvi: "{{ dir.work }}/{{ hash }}.dvi"
31
+ yml: "{{ dir.work }}/{{ hash }}.yml"
32
+ tfm: "{{ dir.work }}/{{ hash }}.tfm.svg"
33
+ fit: "{{ dir.work }}/{{ hash }}.fit.svg"
34
+ svg: "{{ dir.dest }}/{{ hash }}.svg"
35
+ commands:
36
+ latexmk:
37
+ command:
38
+ - "latexmk"
39
+ - "-output-directory={{ dir.work }}"
40
+ - "{{ file.tex }}"
41
+ sources:
42
+ - "{{ file.tex }}"
43
+ targets:
44
+ - "{{ file.dvi }}"
45
+ - "{{ file.yml }}"
46
+ dvisvgm_tfm:
47
+ command:
48
+ - "dvisvgm"
49
+ - "--no-fonts"
50
+ - "{{ file.dvi }}"
51
+ - "--output={{ file.tfm }}"
52
+ sources:
53
+ - "{{ file.dvi }}"
54
+ targets:
55
+ - "{{ file.tfm }}"
56
+ dvisvgm_fit:
57
+ command:
58
+ - "dvisvgm"
59
+ - "--no-fonts"
60
+ - "--exact"
61
+ - "{{ file.dvi }}"
62
+ - "--output={{ file.fit }}"
63
+ sources:
64
+ - "{{ file.dvi }}"
65
+ targets:
66
+ - "{{ file.fit }}"
67
+ cp_to_dest:
68
+ command:
69
+ - "cp"
70
+ - "{{ file.fit }}"
71
+ - "{{ file.svg }}"
72
+ sources:
73
+ - "{{ file.fit }}"
74
+ targets:
75
+ - "{{ file.svg }}"
76
+ aliases:
77
+ # 'internal' must have the highest priority;
78
+ # it is the liquid tag all other aliases are rendered to.
79
+ internal:
80
+ priority: 1000
81
+ regexp: !ruby/regexp
82
+ /{%\s*antex\s*(?<markup>.*?)%}(?<code>.*?){%\s*endantex\s*%}/m
83
+ # 'default' is the standard generic purpose alias.
84
+ # Since it can contain tikz pictures,
85
+ # it must have higher priority than 'tikzpicture' alias.
86
+ default:
87
+ priority: 100
88
+ regexp: !ruby/regexp
89
+ /{%\s*tex\s*(?<markup>.*?)%}(?<code>.*?){%\s*endtex\s*%}/m
90
+ tikzpicture:
91
+ priority: 90
92
+ regexp: !ruby/regexp
93
+ /{%\s*tikz\s*(?<markup>.*?)%}(?<code>.*?){%\s*endtikz\s*%}/m
94
+ options:
95
+ prepend: '\\begin{tikzpicture}'
96
+ append: '\\end{tikzpicture}'
97
+ classes: [antex, tikz]
98
+ # 'display_math' must have a higher priority than 'inline_math'
99
+ # since the respective deliniters are double and single dollars.
100
+ display_math:
101
+ priority: 20
102
+ regexp: !ruby/regexp /\$\$(?<code>.*?)\$\$/m
103
+ options:
104
+ prepend: '$\\displaystyle'
105
+ append: $
106
+ classes: [antex, display]
107
+ inline_math:
108
+ priority: 10
109
+ regexp: !ruby/regexp /\$(?<code>.*?)\$/
110
+ options:
111
+ prepend: $
112
+ append: $
113
+ classes: [antex, inline]
114
+ # 'inline_macro' must have the lowest priority
115
+ # to avoid interference with others aliases.
116
+ inline_macro:
117
+ priority: 0
118
+ regexp: !ruby/regexp /(?<code>\\[A-z]+)/
119
+ options:
120
+ classes: [antex, inline]
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Antex
5
+ class Error < StandardError; end
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require 'jekyll/utils'
5
+
6
+ require 'jekyll/antex/alias'
7
+ require 'jekyll/antex/dealiaser'
8
+
9
+ module Jekyll
10
+ module Antex
11
+ class Generator < Jekyll::Generator
12
+ def generate(site)
13
+ site.pages.each do |page|
14
+ dealiaser = build_dealiaser site: site, resource: page
15
+ page.content = dealiaser.parse page.content
16
+ end
17
+
18
+ # site.documents.each do |document|
19
+ # TODO
20
+ # end
21
+
22
+ # site.posts.docs.each do |post|
23
+ # TODO
24
+ # end
25
+ end
26
+
27
+ private
28
+
29
+ def build_dealiaser(site:, resource:)
30
+ options = build_options(site: site, resource: resource)
31
+ dealiaser = Jekyll::Antex::Dealiaser.new
32
+ dealiaser.add_aliases build_aliases(options['aliases'])
33
+ dealiaser
34
+ end
35
+
36
+ def build_options(site:, resource:)
37
+ Jekyll::Antex::Options.build Jekyll::Antex::Options::DEFAULTS,
38
+ site.config['antex'] || {},
39
+ resource.data['antex'] || {}
40
+ end
41
+
42
+ def build_aliases(options_hash)
43
+ options_hash.values.map do |args|
44
+ Alias.new Jekyll::Utils.symbolize_hash_keys(args)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'jekyll/utils'
5
+
6
+ module Jekyll
7
+ module Antex
8
+ module Options
9
+ DEFAULTS =
10
+ YAML.load_file(File.join(File.dirname(__FILE__), 'defaults.yml')).freeze
11
+
12
+ def self.build(*hashes)
13
+ hashes.reduce({}) do |result, hash|
14
+ Jekyll::Utils.deep_merge_hashes result, hash
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Antex
5
+ VERSION = '0.1.0'
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'antex'
4
+
5
+ require 'jekyll/antex/version'
6
+ require 'jekyll/antex/error'
7
+ require 'jekyll/antex/options'
8
+ require 'jekyll/antex/alias'
9
+ require 'jekyll/antex/dealiaser'
10
+ require 'jekyll/antex/generator'
11
+ require 'jekyll/antex/block'
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-antex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Paolo Brasolin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-01 00:00:00.000000000 Z
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.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: antex
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '9.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '9.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.14'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.15'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.15'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.6'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.50'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.50'
125
+ - !ruby/object:Gem::Dependency
126
+ name: yard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.9'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.9'
139
+ description: 'Jekyll-anTeX implements universal TeX support in Jekyll to embed and
140
+ render arbitrary code using any engine and dialect. '
141
+ email: paolo.brasolin@gmail.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - LICENSE.txt
147
+ - README.md
148
+ - lib/jekyll/antex.rb
149
+ - lib/jekyll/antex/alias.rb
150
+ - lib/jekyll/antex/block.rb
151
+ - lib/jekyll/antex/dealiaser.rb
152
+ - lib/jekyll/antex/defaults.yml
153
+ - lib/jekyll/antex/error.rb
154
+ - lib/jekyll/antex/generator.rb
155
+ - lib/jekyll/antex/options.rb
156
+ - lib/jekyll/antex/version.rb
157
+ homepage: https://github.com/paolobrasolin/antex
158
+ licenses:
159
+ - MIT
160
+ metadata: {}
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '2.3'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubyforge_project:
177
+ rubygems_version: 2.6.13
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: Universal TeX integration for Jekyll
181
+ test_files: []