asciidoctor-templates-compiler 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +97 -4
- data/asciidoctor-templates-compiler.gemspec +13 -8
- data/lib/asciidoctor-templates-compiler.rb +1 -0
- data/lib/asciidoctor/templates_compiler.rb +1 -0
- data/lib/asciidoctor/templates_compiler/base.rb +11 -14
- data/lib/asciidoctor/templates_compiler/converter_generator.rb +23 -22
- data/lib/asciidoctor/templates_compiler/ruby_beautify.rb +31 -13
- data/lib/asciidoctor/templates_compiler/slim.rb +1 -0
- data/lib/asciidoctor/templates_compiler/version.rb +3 -1
- metadata +58 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 367bbbb5d5b7d7f38e994e845a65921592fe9036
|
4
|
+
data.tar.gz: f941a11c99f96177f4a251cc8f15820670c348b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc05c92e8548eb23e49de8a8d6dee7d67b985b0c5ce74af785c0d0f41d360f9ffb4c0d3708b5ccf3323db5c441bde2a6536a6de70cd67296923f21f3fbf0b2a0
|
7
|
+
data.tar.gz: c466abc187ea3d4d7b781caad7b061db1873f37cbaa0109538c1506f2c76ad268db7a5bcde865674af92e19c0a60c409470f951d2d0895361a3f8363fadc2a19
|
data/README.adoc
CHANGED
@@ -2,9 +2,15 @@
|
|
2
2
|
:source-language: ruby
|
3
3
|
// custom
|
4
4
|
:gem-name: asciidoctor-templates-compiler
|
5
|
-
:gem-version: 0.1.
|
5
|
+
:gem-version: 0.1.3
|
6
|
+
:gh-name: jirutka/{gem-name}
|
7
|
+
:gh-branch: master
|
8
|
+
:codacy-id: b23b8c6503474ea5b13537eaef0c73d5
|
6
9
|
|
7
10
|
ifdef::env-github[]
|
11
|
+
image:https://travis-ci.org/{gh-name}.svg?branch={gh-branch}[Build Status, link="https://travis-ci.org/{gh-name}"]
|
12
|
+
image:https://api.codacy.com/project/badge/Coverage/{codacy-id}["Test Coverage", link="https://www.codacy.com/app/{gh-name}"]
|
13
|
+
image:https://api.codacy.com/project/badge/Grade/{codacy-id}["Codacy Code quality", link="https://www.codacy.com/app/{gh-name}"]
|
8
14
|
image:https://img.shields.io/gem/v/{gem-name}.svg?style=flat[Gem Version, link="https://rubygems.org/gems/{gem-name}"]
|
9
15
|
endif::env-github[]
|
10
16
|
|
@@ -35,16 +41,49 @@ $ bundle install
|
|
35
41
|
|
36
42
|
== Usage
|
37
43
|
|
44
|
+
The main entry point is method `Asciidoctor::TemplatesCompiler::Slim#compile_converter` (for Slim) that accepts the following keyword arguments.
|
45
|
+
|
46
|
+
templates_dir::
|
47
|
+
Path of the directory where to look for templates (`*.slim` files not starting with `_`, in the case of Slim) and (optional) `helpers.rb`.
|
48
|
+
This argument is **required**.
|
49
|
+
|
50
|
+
class_name::
|
51
|
+
Full name of the converter class to generate (e.g. `My::HTML::Converter`).
|
52
|
+
This argument is **required**.
|
53
|
+
|
54
|
+
delegate_backend::
|
55
|
+
Name of the backend (converter) to use as a fallback for AST nodes not supported by your converter.
|
56
|
+
If not specified (default), no fallback will be used and converter will raise `NoMethodError` when it try to convert an unsupported node.
|
57
|
+
|
58
|
+
register_for::
|
59
|
+
An array of backend names that the generated converter should be registered in Asciidoctor to handle.
|
60
|
+
Default is empty.
|
61
|
+
|
62
|
+
backend_info::
|
63
|
+
A hash of keys for `backend_info`: `basebackend`, `outfilesuffix`, `filetype`, `htmlsyntax`.
|
64
|
+
|
65
|
+
pretty::
|
66
|
+
Enable pretty-formatting of the generated Ruby code (generated by Slim/Temple)?
|
67
|
+
Default is `false`.
|
68
|
+
|
69
|
+
output::
|
70
|
+
An output stream (`IO` object like opened file, `$stdout`, …) to write the generated converter into.
|
71
|
+
Default is `StringIO.new` (it’s the return value of `#compile_converter`).
|
72
|
+
|
73
|
+
|
74
|
+
=== Examples
|
75
|
+
|
38
76
|
[source, subs="+attributes"]
|
77
|
+
.Minimal example
|
39
78
|
----
|
40
79
|
require '{gem-name}'
|
41
80
|
|
42
|
-
File.open('
|
81
|
+
File.open('converter.rb', 'w') do |file|
|
43
82
|
Asciidoctor::TemplatesCompiler::Slim.compile_converter(
|
44
83
|
templates_dir: 'data/templates',
|
45
|
-
class_name: '
|
84
|
+
class_name: 'ShinyHtml::Converter',
|
46
85
|
delegate_backend: 'html5',
|
47
|
-
register_for: ['html
|
86
|
+
register_for: ['shiny-html'],
|
48
87
|
backend_info: {
|
49
88
|
basebackend: 'html',
|
50
89
|
outfilesuffix: '.html',
|
@@ -55,6 +94,60 @@ File.open('html_custom_converter.rb', 'w') do |file|
|
|
55
94
|
end
|
56
95
|
----
|
57
96
|
|
97
|
+
[source, subs="+attributes"]
|
98
|
+
.Example of usage in Rakefile
|
99
|
+
----
|
100
|
+
#!/usr/bin/env rake
|
101
|
+
|
102
|
+
CONVERTER_FILE = 'lib/asciidoctor/shiny_html/converter.rb'
|
103
|
+
TEMPLATES_DIR = 'data/templates'
|
104
|
+
|
105
|
+
namespace :build do
|
106
|
+
|
107
|
+
file CONVERTER_FILE, [:mode] => FileList["#{TEMPLATES_DIR}/*"] do |t, args|
|
108
|
+
require '{gem-name}'
|
109
|
+
|
110
|
+
File.open(CONVERTER_FILE, 'w') do |file|
|
111
|
+
$stderr.puts "Generating #{file.path}."
|
112
|
+
Asciidoctor::TemplatesCompiler::Slim.compile_converter(
|
113
|
+
templates_dir: TEMPLATES_DIR,
|
114
|
+
class_name: 'Asciidoctor::ShinyHtml::Converter',
|
115
|
+
delegate_backend: 'html5',
|
116
|
+
register_for: ['shiny-html'],
|
117
|
+
backend_info: {
|
118
|
+
basebackend: 'html',
|
119
|
+
outfilesuffix: '.html',
|
120
|
+
filetype: 'html',
|
121
|
+
},
|
122
|
+
pretty: (args[:mode] == :pretty),
|
123
|
+
output: file)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
namespace :converter do
|
128
|
+
desc 'Compile Slim templates and generate converter.rb (pretty mode)'
|
129
|
+
task :pretty do
|
130
|
+
Rake::Task[CONVERTER_FILE].invoke(:pretty)
|
131
|
+
end
|
132
|
+
|
133
|
+
desc 'Compile Slim templates and generate converter.rb (fast mode)'
|
134
|
+
task :fast do
|
135
|
+
Rake::Task[CONVERTER_FILE].invoke
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
task :converter => 'converter:pretty'
|
140
|
+
end
|
141
|
+
|
142
|
+
task :build => 'build:converter:pretty'
|
143
|
+
|
144
|
+
task :clean do
|
145
|
+
rm_rf CONVERTER_FILE
|
146
|
+
end
|
147
|
+
----
|
148
|
+
|
149
|
+
You can also look into https://github.com/jirutka/asciidoctor-html5s/[asciidoctor-html5s] for a real-world example including integration with https://github.com/asciidoctor/asciidoctor-doctest/[Asciidoctor::DocTest].
|
150
|
+
|
58
151
|
|
59
152
|
== License
|
60
153
|
|
@@ -1,16 +1,16 @@
|
|
1
1
|
require File.expand_path('../lib/asciidoctor/templates_compiler/version', __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.version
|
6
|
-
s.author
|
7
|
-
s.email
|
8
|
-
s.homepage
|
9
|
-
s.license
|
4
|
+
s.name = 'asciidoctor-templates-compiler'
|
5
|
+
s.version = Asciidoctor::TemplatesCompiler::VERSION
|
6
|
+
s.author = 'Jakub Jirutka'
|
7
|
+
s.email = 'jakub@jirutka.cz'
|
8
|
+
s.homepage = 'https://github.com/jirutka/asciidoctor-templates-compiler'
|
9
|
+
s.license = 'MIT'
|
10
10
|
|
11
|
-
s.summary
|
11
|
+
s.summary = 'Compile templates-based Asciidoctor converter (backend) into a single Ruby file'
|
12
12
|
|
13
|
-
s.files
|
13
|
+
s.files = Dir['lib/**/*', '*.gemspec', 'LICENSE*', 'README*']
|
14
14
|
|
15
15
|
s.required_ruby_version = '>= 2.3'
|
16
16
|
|
@@ -18,4 +18,9 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_runtime_dependency 'corefines', '~> 1.2'
|
19
19
|
s.add_runtime_dependency 'slim', '>= 2.1', '< 4.0'
|
20
20
|
s.add_runtime_dependency 'ruby-beautify', '~> 0.97'
|
21
|
+
|
22
|
+
s.add_development_dependency 'rake', '~> 12.0'
|
23
|
+
s.add_development_dependency 'rspec', '~> 3.6'
|
24
|
+
s.add_development_dependency 'rubocop', '~> 0.49.0'
|
25
|
+
s.add_development_dependency 'simplecov', '~> 0.14'
|
21
26
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'asciidoctor/templates_compiler/version'
|
2
3
|
require 'asciidoctor/templates_compiler/converter_generator'
|
3
4
|
require 'asciidoctor/templates_compiler/ruby_beautify'
|
@@ -5,19 +6,17 @@ require 'stringio'
|
|
5
6
|
|
6
7
|
module Asciidoctor::TemplatesCompiler
|
7
8
|
class Base
|
8
|
-
|
9
9
|
class << self
|
10
10
|
def compile_converter(**opts)
|
11
11
|
new.compile_converter(**opts)
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
alias call compile_converter
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
17
|
def compile_converter(output: StringIO.new, templates_dir:, pretty: false, **opts)
|
19
|
-
unless Dir.
|
20
|
-
|
18
|
+
unless Dir.exist? templates_dir
|
19
|
+
raise "Templates directory '#{templates_dir}' does not exist"
|
21
20
|
end
|
22
21
|
|
23
22
|
backend_info = opts[:backend_info] || {}
|
@@ -25,23 +24,21 @@ module Asciidoctor::TemplatesCompiler
|
|
25
24
|
transforms_code = compile_templates(templates, backend_info: backend_info, pretty: pretty)
|
26
25
|
|
27
26
|
generate_class(output: output, transforms_code: transforms_code,
|
28
|
-
|
27
|
+
helpers_code: read_helpers(templates_dir), **opts)
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
alias call compile_converter
|
33
31
|
|
34
32
|
protected
|
35
33
|
|
34
|
+
# @abstract
|
36
35
|
def compile_template(filename, backend_info: {})
|
37
|
-
fail NotImplementedError
|
38
36
|
end
|
39
37
|
|
38
|
+
# @abstract
|
40
39
|
def find_templates(dirname)
|
41
|
-
fail NotImplementedError
|
42
40
|
end
|
43
41
|
|
44
|
-
|
45
42
|
def beautify_code(code, **opts)
|
46
43
|
RubyBeautify.call(code, **opts)
|
47
44
|
end
|
@@ -61,13 +58,13 @@ module Asciidoctor::TemplatesCompiler
|
|
61
58
|
|
62
59
|
def read_helpers(templates_dir)
|
63
60
|
path = File.join(templates_dir, 'helpers.rb')
|
64
|
-
IO.read(path) if File.
|
61
|
+
IO.read(path) if File.exist? path
|
65
62
|
end
|
66
63
|
|
67
64
|
def transform_name_from_tmpl_name(filename)
|
68
65
|
File.basename(filename)
|
69
|
-
|
70
|
-
|
66
|
+
.sub(/\..*$/, '')
|
67
|
+
.sub(/^block_/, '')
|
71
68
|
end
|
72
69
|
end
|
73
70
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'asciidoctor/templates_compiler/version'
|
2
3
|
require 'corefines'
|
3
4
|
require 'stringio'
|
@@ -7,16 +8,15 @@ module Asciidoctor::TemplatesCompiler
|
|
7
8
|
using Corefines::String::indent
|
8
9
|
|
9
10
|
class << self
|
10
|
-
def generate(output:
|
11
|
+
def generate(output: StringIO.new, **opts)
|
11
12
|
new(**opts).call(output)
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
+
alias call generate
|
15
16
|
end
|
16
17
|
|
17
|
-
|
18
18
|
def initialize(class_name:, transforms_code:, helpers_code: nil,
|
19
|
-
register_for: [], backend_info: {}, delegate_backend: nil, **
|
19
|
+
register_for: [], backend_info: {}, delegate_backend: nil, **)
|
20
20
|
@class_name = class_name
|
21
21
|
@transforms_code = transforms_code
|
22
22
|
@helpers_code = helpers_code
|
@@ -36,16 +36,16 @@ module Asciidoctor::TemplatesCompiler
|
|
36
36
|
out
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
alias call generate
|
40
40
|
|
41
41
|
protected
|
42
42
|
|
43
43
|
def head_code
|
44
44
|
init_modules = @class_name
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
.split('::')[0..-2]
|
46
|
+
.map { |name| "module #{name};" }
|
47
|
+
.tap { |ary| ary.push('end ' * ary.size) }
|
48
|
+
.join(' ').strip
|
49
49
|
|
50
50
|
<<~EOF
|
51
51
|
# This file has been generated!
|
@@ -70,8 +70,9 @@ module Asciidoctor::TemplatesCompiler
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def initialization_code
|
73
|
-
setup_backend_info =
|
74
|
-
|
73
|
+
setup_backend_info = if !@backend_info.empty?
|
74
|
+
@backend_info.map { |k, v| " #{k} #{v.inspect}" }.join("\n")
|
75
|
+
end
|
75
76
|
|
76
77
|
if !@register_for.empty?
|
77
78
|
register_for = "register_for #{@register_for.map(&:inspect).join(', ')}\n"
|
@@ -85,10 +86,10 @@ module Asciidoctor::TemplatesCompiler
|
|
85
86
|
|
86
87
|
converter = factory.create(delegate_backend, backend_info)
|
87
88
|
@delegate_converter = if converter == self
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
factory.new.create(delegate_backend, backend_info)
|
90
|
+
else
|
91
|
+
converter
|
92
|
+
end
|
92
93
|
EOF
|
93
94
|
end
|
94
95
|
|
@@ -96,8 +97,8 @@ module Asciidoctor::TemplatesCompiler
|
|
96
97
|
register_for,
|
97
98
|
'def initialize(backend, opts = {})',
|
98
99
|
' super',
|
99
|
-
|
100
|
-
|
100
|
+
setup_backend_info,
|
101
|
+
delegate_converter,
|
101
102
|
'end',
|
102
103
|
'',
|
103
104
|
].compact.join("\n").indent(2, ' ')
|
@@ -105,10 +106,10 @@ module Asciidoctor::TemplatesCompiler
|
|
105
106
|
|
106
107
|
def convert_method_code
|
107
108
|
converter = if @delegate_backend
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
'respond_to?(transform) ? self : @delegate_converter'
|
110
|
+
else
|
111
|
+
'self'
|
112
|
+
end
|
112
113
|
|
113
114
|
<<~EOF.indent(2, ' ')
|
114
115
|
def convert(node, transform = nil, opts = {})
|
@@ -144,7 +145,7 @@ module Asciidoctor::TemplatesCompiler
|
|
144
145
|
node.extend(Helpers)
|
145
146
|
node.instance_eval do
|
146
147
|
converter.set_local_variables(binding, opts) unless opts.empty?
|
147
|
-
#{code.indent(
|
148
|
+
#{code.indent(6, ' ')}
|
148
149
|
end
|
149
150
|
end
|
150
151
|
EOF
|
@@ -1,27 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'asciidoctor/templates_compiler/version'
|
2
3
|
require 'ruby-beautify'
|
3
4
|
|
4
5
|
module Asciidoctor::TemplatesCompiler
|
5
6
|
module RubyBeautify
|
6
|
-
|
7
|
+
include ::RubyBeautify
|
8
|
+
extend self # rubocop:disable Style/ModuleFunction
|
9
|
+
|
10
|
+
alias pretty_string_orig pretty_string
|
11
|
+
private :pretty_string_orig
|
7
12
|
|
8
13
|
def pretty_string(code, indent_count: 2)
|
9
|
-
new_lines_old =
|
10
|
-
|
14
|
+
new_lines_old = NEW_LINES
|
15
|
+
NEW_LINES.push(:on_semicolon) # XXX: sandbox somehow?
|
11
16
|
|
12
|
-
s = "
|
13
|
-
s.gsub!
|
14
|
-
s.gsub!
|
15
|
-
s.replace
|
16
|
-
s.gsub!
|
17
|
-
s.gsub!
|
18
|
-
s.
|
19
|
-
s.sub!
|
17
|
+
s = +"module M_\n#{code}\nend\n"
|
18
|
+
s.gsub!(/^[ \t]*;/, '') # remove leading semicolons
|
19
|
+
s.gsub!(/;\s*$/, '') # remove trailing semicolons
|
20
|
+
s.replace(pretty_string_orig(s, indent_token: "\1", indent_count: indent_count))
|
21
|
+
s.gsub!(";\1", "\n\1") # remove trailing semicolons after formatting
|
22
|
+
s.gsub!(/^#{"\1" * indent_count}/, '') # remove redundant indentation level
|
23
|
+
s.tr!("\1", ' ') # replace placeholder indent char with space
|
24
|
+
s.sub!(/\Amodule M_\n/, '') # remove wrapper module
|
25
|
+
s.sub!(/\nend\n\z/, '') # remove wrapper module
|
20
26
|
|
21
|
-
|
27
|
+
NEW_LINES.replace(new_lines_old) # XXX: not thread-safe
|
22
28
|
s
|
23
29
|
end
|
24
30
|
|
25
|
-
alias
|
31
|
+
alias call pretty_string
|
32
|
+
|
33
|
+
# XXX: Remove after https://github.com/erniebrodeur/ruby-beautify/pull/43 is merged.
|
34
|
+
# Overwrite this method from ::RubyBeautify with implementation that does
|
35
|
+
# not execute ruby subprocess.
|
36
|
+
def syntax_ok?(string)
|
37
|
+
catch :good do
|
38
|
+
eval "BEGIN { throw :good }; #{string}" # rubocop:disable Security/Eval
|
39
|
+
end
|
40
|
+
true
|
41
|
+
rescue SyntaxError
|
42
|
+
false
|
43
|
+
end
|
26
44
|
end
|
27
45
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciidoctor-templates-compiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Jirutka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -72,6 +72,62 @@ dependencies:
|
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0.97'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rake
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '12.0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '12.0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '3.6'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '3.6'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rubocop
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.49.0
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 0.49.0
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: simplecov
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0.14'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.14'
|
75
131
|
description:
|
76
132
|
email: jakub@jirutka.cz
|
77
133
|
executables: []
|