asciidoctor-templates-compiler 0.2.0 → 0.3.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 +4 -4
- data/README.adoc +1 -1
- data/asciidoctor-templates-compiler.gemspec +3 -1
- data/bin/asciidoctor-templates-compiler +110 -0
- data/lib/asciidoctor/templates_compiler/base.rb +28 -1
- data/lib/asciidoctor/templates_compiler/converter_generator.rb +50 -19
- data/lib/asciidoctor/templates_compiler/ruby_beautify.rb +1 -1
- data/lib/asciidoctor/templates_compiler/string_ext.rb +19 -0
- data/lib/asciidoctor/templates_compiler/version.rb +1 -1
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51590b253d877005f5760f154c14346665e1722c
|
4
|
+
data.tar.gz: 9d98b848da5104228aa0c8918e9646b12ec06805
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c6d38f6a691c349843ca8fd9d9569e6ac125bc81cb3732a45d3af1c4b651d7d953b8d759151823dbb6f1f3cb7802330719bab51e472fa04e0529674ca5c638a
|
7
|
+
data.tar.gz: 675c48c88d2c797049857cc70bedb7e3e56f9ec666ae8f2fa3181aafdfea67cc51fb949cd31f20240f27867d899b1dac0cfeb4b752188a026562c7104e1d667f
|
data/README.adoc
CHANGED
@@ -11,11 +11,13 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = 'Compile templates-based Asciidoctor converter (backend) into a single Ruby file'
|
12
12
|
|
13
13
|
s.files = Dir['lib/**/*', '*.gemspec', 'LICENSE*', 'README*']
|
14
|
+
s.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
14
15
|
|
15
|
-
s.required_ruby_version = '>= 2.
|
16
|
+
s.required_ruby_version = '>= 2.1'
|
16
17
|
|
17
18
|
s.add_runtime_dependency 'asciidoctor', '~> 1.5'
|
18
19
|
s.add_runtime_dependency 'corefines', '~> 1.2'
|
20
|
+
s.add_runtime_dependency 'docopt', '~> 0.6'
|
19
21
|
s.add_runtime_dependency 'slim', '>= 2.1', '< 4.0'
|
20
22
|
s.add_runtime_dependency 'ruby-beautify', '~> 0.97'
|
21
23
|
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
require 'asciidoctor/templates_compiler'
|
4
|
+
require 'docopt'
|
5
|
+
require 'corefines'
|
6
|
+
|
7
|
+
using Corefines::Hash::rekey
|
8
|
+
using Corefines::String::unindent
|
9
|
+
|
10
|
+
PROG_NAME = 'asciidoctor-templates-compiler'
|
11
|
+
BUGS_URL = "https://github.com/jirutka/#{PROG_NAME}/issues"
|
12
|
+
|
13
|
+
HELP_MSG = <<-EOF.unindent
|
14
|
+
Usage:
|
15
|
+
#{PROG_NAME} [options...] TEMPLATES_DIR
|
16
|
+
#{PROG_NAME} --help | --version
|
17
|
+
|
18
|
+
Arguments:
|
19
|
+
TEMPLATES_DIR Path of the directory where to look for templates ("*.slim"
|
20
|
+
files not starting with "_", in the case of Slim) and
|
21
|
+
(optional) "helpers.rb".
|
22
|
+
|
23
|
+
Options:
|
24
|
+
-b --backend-info KEY=VAL[,...] Parameters for backend_info: basebackend, outfilesuffix,
|
25
|
+
filetype, and htmlsyntax.
|
26
|
+
|
27
|
+
-n --class-name NAME Full name of the converter class to generate (e.g.
|
28
|
+
My::HTML::Converter) [default: Converter].
|
29
|
+
|
30
|
+
-d --delegate-backend BACKEND Name of the backend (converter) to use as a fallback for AST
|
31
|
+
nodes not supported by your converter. If not specified
|
32
|
+
(default), no fallback will be used and converter will raise
|
33
|
+
"NoMethodError" when it try to convert an unsupported node.
|
34
|
+
|
35
|
+
-o --output FILE Where to write the output. Use "-" for stdout. [default: -]
|
36
|
+
|
37
|
+
-P --no-pretty Do not format generated Ruby code.
|
38
|
+
|
39
|
+
-r --register-for BACKEND[,...] Backend name(s) that the generated converter should be
|
40
|
+
registered in Asciidoctor to handle.
|
41
|
+
|
42
|
+
-V --version Print version and exit.
|
43
|
+
|
44
|
+
-h --help Show this message and exit.
|
45
|
+
|
46
|
+
Please report bugs at <#{BUGS_URL}>.
|
47
|
+
EOF
|
48
|
+
|
49
|
+
def die(message, status: 1)
|
50
|
+
$stderr.puts("#{PROG_NAME}: #{message}")
|
51
|
+
exit status
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_kw_list(list)
|
55
|
+
list
|
56
|
+
.flat_map { |arg| arg.split(/\s*,\s*/) }
|
57
|
+
.map { |item| item.split('=', 2) }
|
58
|
+
.to_h
|
59
|
+
rescue ArgumentError
|
60
|
+
raise ArgumentError, 'not a list of key=word arguments'
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_option_value(name, value)
|
64
|
+
case name
|
65
|
+
when :backend_info
|
66
|
+
parse_kw_list(value)
|
67
|
+
when :class_name, :delegate_backend, :output
|
68
|
+
value.last
|
69
|
+
when :pretty
|
70
|
+
value.zero?
|
71
|
+
else
|
72
|
+
value
|
73
|
+
end
|
74
|
+
rescue ArgumentError => e
|
75
|
+
raise ArgumentError, "Invalid option --#{name}: #{e.message}"
|
76
|
+
end
|
77
|
+
|
78
|
+
opts = begin
|
79
|
+
Docopt::docopt(HELP_MSG, help: false)
|
80
|
+
.rekey { |key| key.sub(/^--/, '').tr('-', '_').downcase.to_sym }
|
81
|
+
.rekey(:no_pretty => :pretty) # rubocop:disable Style/HashSyntax
|
82
|
+
.map { |k, v| [k, parse_option_value(k, v)] }.to_h
|
83
|
+
rescue Docopt::Exit => e
|
84
|
+
$stderr.puts(e.message)
|
85
|
+
exit 1
|
86
|
+
rescue ArgumentError => e
|
87
|
+
die e.message
|
88
|
+
end
|
89
|
+
|
90
|
+
if opts[:help]
|
91
|
+
puts HELP_MSG.strip
|
92
|
+
|
93
|
+
elsif opts[:version]
|
94
|
+
puts [PROG_NAME, Asciidoctor::TemplatesCompiler::VERSION].join(' ')
|
95
|
+
|
96
|
+
else
|
97
|
+
output = if opts[:output] == '-'
|
98
|
+
$stdout
|
99
|
+
else
|
100
|
+
File.open(opts[:output], 'w')
|
101
|
+
end
|
102
|
+
|
103
|
+
begin
|
104
|
+
Asciidoctor::TemplatesCompiler::Slim.compile_converter(**opts, output: output)
|
105
|
+
rescue RuntimeError => e
|
106
|
+
die e.message
|
107
|
+
ensure
|
108
|
+
output.close if output != $stdout
|
109
|
+
end
|
110
|
+
end
|
@@ -5,8 +5,12 @@ require 'asciidoctor/templates_compiler/ruby_beautify'
|
|
5
5
|
require 'stringio'
|
6
6
|
|
7
7
|
module Asciidoctor::TemplatesCompiler
|
8
|
+
##
|
9
|
+
# Base class for templates compilers.
|
8
10
|
class Base
|
9
11
|
class << self
|
12
|
+
##
|
13
|
+
# An "alias" for {#compile_converter}.
|
10
14
|
def compile_converter(**opts)
|
11
15
|
new.compile_converter(**opts)
|
12
16
|
end
|
@@ -14,9 +18,23 @@ module Asciidoctor::TemplatesCompiler
|
|
14
18
|
alias call compile_converter
|
15
19
|
end
|
16
20
|
|
21
|
+
##
|
22
|
+
# (see ConverterGenerator.generate)
|
23
|
+
#
|
24
|
+
# Compiles templates found in _templates_dir_ to Ruby and generates an Asciidoctor converter
|
25
|
+
# class from them.
|
26
|
+
#
|
27
|
+
# @param templates_dir [String] path of the directory where to look for templates
|
28
|
+
# and (optional) +helpers.rb+.
|
29
|
+
# @param engine_opts [Hash] a hash of options to pass into the templating engine.
|
30
|
+
# Default is empty.
|
31
|
+
# @param pretty [Boolean] enable pretty-formatting of the generated Ruby code?
|
32
|
+
#
|
33
|
+
# @raise [ArgumentError] if the given _templates_dir_ does not exist.
|
34
|
+
#
|
17
35
|
def compile_converter(templates_dir:, engine_opts: {}, pretty: false, **opts)
|
18
36
|
unless Dir.exist? templates_dir
|
19
|
-
raise "Templates directory '#{templates_dir}' does not exist"
|
37
|
+
raise ArgumentError, "Templates directory '#{templates_dir}' does not exist"
|
20
38
|
end
|
21
39
|
|
22
40
|
templates = find_templates(templates_dir)
|
@@ -30,11 +48,20 @@ module Asciidoctor::TemplatesCompiler
|
|
30
48
|
|
31
49
|
protected
|
32
50
|
|
51
|
+
##
|
33
52
|
# @abstract
|
53
|
+
# @param filename [String] path of the template file to compile.
|
54
|
+
# @param engine_opts [Hash] a hash of options to pass into the templating engine.
|
55
|
+
# @return [String] a Ruby code of the compiled template.
|
56
|
+
#
|
34
57
|
def compile_template(filename, engine_opts = {})
|
35
58
|
end
|
36
59
|
|
60
|
+
##
|
37
61
|
# @abstract
|
62
|
+
# @param dirname [String] path of the directory where to look for templates.
|
63
|
+
# @return [Array<String>] paths of the found template files.
|
64
|
+
#
|
38
65
|
def find_templates(dirname)
|
39
66
|
end
|
40
67
|
|
@@ -1,21 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'asciidoctor/templates_compiler/version'
|
3
|
+
require 'asciidoctor/templates_compiler/string_ext'
|
3
4
|
require 'corefines'
|
4
5
|
require 'stringio'
|
5
6
|
|
6
7
|
module Asciidoctor::TemplatesCompiler
|
8
|
+
##
|
9
|
+
# Source-code generator of Asciidoctor converter classes.
|
7
10
|
class ConverterGenerator
|
8
|
-
using Corefines::String
|
11
|
+
using Corefines::String[:indent, :unindent]
|
9
12
|
using Corefines::Object::blank?
|
13
|
+
using StringExt::reindent
|
10
14
|
|
11
15
|
class << self
|
16
|
+
##
|
17
|
+
# (see #initialize)
|
18
|
+
# @param output [#<<] output stream where to write the generated class.
|
19
|
+
# Defaults to {StringIO}.
|
20
|
+
# @return the given _output_ stream.
|
21
|
+
#
|
12
22
|
def generate(output: StringIO.new, **opts)
|
13
23
|
new(**opts).call(output)
|
14
24
|
end
|
15
25
|
|
26
|
+
# An alias for {.generate}.
|
16
27
|
alias call generate
|
17
28
|
end
|
18
29
|
|
30
|
+
##
|
31
|
+
# @param class_name [String] full name of the converter class to generate
|
32
|
+
# (e.g. +My::HTML::Converter+).
|
33
|
+
# @param transforms_code [#each] enumerable that yields pair: transform name ()
|
34
|
+
# @param helpers_code [String, nil] source code to include in the generated class. It must
|
35
|
+
# contain a module named +Helpers+.
|
36
|
+
# @param register_for [Array<String>] an array of backend names that the generated converter
|
37
|
+
# should be registered for to handle. Default is empty.
|
38
|
+
# @param backend_info [Hash] a hash of parameters for +backend_info+: +basebackend+,
|
39
|
+
# +outfilesuffix+, +filetype+, +htmlsyntax+. Default is empty.
|
40
|
+
# @param delegate_backend [String, nil] name of the backend (converter) to use as a fallback
|
41
|
+
# for AST nodes not supported by the generated converter. If not specified, no fallback will
|
42
|
+
# be used and converter will raise +NoMethodError+ when it try to convert unsupported node.
|
43
|
+
#
|
44
|
+
# @raise [ArgumentError] if _helpers_code_ is not blank and does not contain module +Helpers+.
|
45
|
+
#
|
19
46
|
def initialize(class_name:, transforms_code:, helpers_code: nil,
|
20
47
|
register_for: [], backend_info: {}, delegate_backend: nil, **)
|
21
48
|
@class_name = class_name
|
@@ -30,6 +57,12 @@ module Asciidoctor::TemplatesCompiler
|
|
30
57
|
end
|
31
58
|
end
|
32
59
|
|
60
|
+
##
|
61
|
+
# Generates source code of a converter class for Asciidoctor.
|
62
|
+
#
|
63
|
+
# @param out [#<<] output stream where to write the generated class.
|
64
|
+
# @return the given _out_ stream.
|
65
|
+
#
|
33
66
|
def generate(out = StringIO.new)
|
34
67
|
out << head_code << "\n"
|
35
68
|
out << helpers_code << "\n" unless @helpers_code.blank?
|
@@ -52,7 +85,7 @@ module Asciidoctor::TemplatesCompiler
|
|
52
85
|
.tap { |ary| ary.push('end ' * ary.size) }
|
53
86
|
.join(' ').strip
|
54
87
|
|
55
|
-
|
88
|
+
<<-EOF.unindent
|
56
89
|
# This file has been generated!
|
57
90
|
|
58
91
|
#{init_modules}
|
@@ -61,9 +94,9 @@ module Asciidoctor::TemplatesCompiler
|
|
61
94
|
end
|
62
95
|
|
63
96
|
def helpers_code
|
64
|
-
|
97
|
+
<<-EOF.unindent.%(@helpers_code).indent(2)
|
65
98
|
#{separator 'Begin of Helpers'}
|
66
|
-
|
99
|
+
%s
|
67
100
|
|
68
101
|
# Make Helpers' constants accessible from transform methods.
|
69
102
|
Helpers.constants.each do |const|
|
@@ -84,7 +117,7 @@ module Asciidoctor::TemplatesCompiler
|
|
84
117
|
end
|
85
118
|
|
86
119
|
if @delegate_backend
|
87
|
-
delegate_converter =
|
120
|
+
delegate_converter = <<-EOF.reindent(2).rstrip
|
88
121
|
|
89
122
|
delegate_backend = (opts[:delegate_backend] || #{@delegate_backend.inspect}).to_s
|
90
123
|
factory = ::Asciidoctor::Converter::Factory
|
@@ -106,7 +139,7 @@ module Asciidoctor::TemplatesCompiler
|
|
106
139
|
delegate_converter,
|
107
140
|
'end',
|
108
141
|
'',
|
109
|
-
].compact.join("\n").indent(2
|
142
|
+
].compact.join("\n").indent(2)
|
110
143
|
end
|
111
144
|
|
112
145
|
def convert_method_code
|
@@ -116,7 +149,7 @@ module Asciidoctor::TemplatesCompiler
|
|
116
149
|
'self'
|
117
150
|
end
|
118
151
|
|
119
|
-
|
152
|
+
<<-EOF.reindent(2)
|
120
153
|
def convert(node, transform = nil, opts = {})
|
121
154
|
transform ||= node.node_name
|
122
155
|
converter = #{converter}
|
@@ -131,7 +164,7 @@ module Asciidoctor::TemplatesCompiler
|
|
131
164
|
end
|
132
165
|
|
133
166
|
def support_methods_code
|
134
|
-
|
167
|
+
<<-EOF.reindent(2)
|
135
168
|
def set_local_variables(binding, vars)
|
136
169
|
vars.each do |key, val|
|
137
170
|
binding.local_variable_set(key.to_sym, val)
|
@@ -141,19 +174,17 @@ module Asciidoctor::TemplatesCompiler
|
|
141
174
|
end
|
142
175
|
|
143
176
|
def transform_methods_code(out)
|
144
|
-
out << " #{separator 'Begin of generated transformation methods'}"
|
177
|
+
out << " #{separator 'Begin of generated transformation methods'}\n"
|
145
178
|
|
146
179
|
@transforms_code.each do |name, code|
|
147
|
-
out <<
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
end
|
156
|
-
EOF
|
180
|
+
out << "\n"
|
181
|
+
out << " def #{name}(node, opts = {})\n"
|
182
|
+
out << " node.extend(Helpers)\n" unless @helpers_code.blank?
|
183
|
+
out << " node.instance_eval do\n"
|
184
|
+
out << " converter.set_local_variables(binding, opts) unless opts.empty?\n"
|
185
|
+
out << code.indent(6, ' ') << "\n"
|
186
|
+
out << " end\n"
|
187
|
+
out << " end\n"
|
157
188
|
end
|
158
189
|
|
159
190
|
out << " #{separator 'End of generated transformation methods'}\n"
|
@@ -14,7 +14,7 @@ module Asciidoctor::TemplatesCompiler
|
|
14
14
|
new_lines_old = NEW_LINES
|
15
15
|
NEW_LINES.push(:on_semicolon) # XXX: sandbox somehow?
|
16
16
|
|
17
|
-
s =
|
17
|
+
s = "module M_\n#{code}\nend\n".dup
|
18
18
|
s.gsub!(/^[ \t]*;/, '') # remove leading semicolons
|
19
19
|
s.gsub!(/;\s*$/, '') # remove trailing semicolons
|
20
20
|
s.replace(pretty_string_orig(s, indent_token: "\1", indent_count: indent_count))
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'corefines'
|
3
|
+
|
4
|
+
module Asciidoctor::TemplatesCompiler
|
5
|
+
# @private
|
6
|
+
module StringExt
|
7
|
+
module Reindent
|
8
|
+
refine ::String do
|
9
|
+
using ::Corefines::String[:indent, :unindent]
|
10
|
+
|
11
|
+
def reindent(level, indent_str = ' ')
|
12
|
+
unindent.indent!(level, indent_str)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
include ::Corefines::Support::AliasSubmodules
|
18
|
+
end
|
19
|
+
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.
|
4
|
+
version: 0.3.0
|
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-09-
|
11
|
+
date: 2017-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: docopt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.6'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.6'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: slim
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -130,19 +144,22 @@ dependencies:
|
|
130
144
|
version: '0.14'
|
131
145
|
description:
|
132
146
|
email: jakub@jirutka.cz
|
133
|
-
executables:
|
147
|
+
executables:
|
148
|
+
- asciidoctor-templates-compiler
|
134
149
|
extensions: []
|
135
150
|
extra_rdoc_files: []
|
136
151
|
files:
|
137
152
|
- LICENSE
|
138
153
|
- README.adoc
|
139
154
|
- asciidoctor-templates-compiler.gemspec
|
155
|
+
- bin/asciidoctor-templates-compiler
|
140
156
|
- lib/asciidoctor-templates-compiler.rb
|
141
157
|
- lib/asciidoctor/templates_compiler.rb
|
142
158
|
- lib/asciidoctor/templates_compiler/base.rb
|
143
159
|
- lib/asciidoctor/templates_compiler/converter_generator.rb
|
144
160
|
- lib/asciidoctor/templates_compiler/ruby_beautify.rb
|
145
161
|
- lib/asciidoctor/templates_compiler/slim.rb
|
162
|
+
- lib/asciidoctor/templates_compiler/string_ext.rb
|
146
163
|
- lib/asciidoctor/templates_compiler/temple_ext.rb
|
147
164
|
- lib/asciidoctor/templates_compiler/version.rb
|
148
165
|
homepage: https://github.com/jirutka/asciidoctor-templates-compiler
|
@@ -157,7 +174,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
157
174
|
requirements:
|
158
175
|
- - ">="
|
159
176
|
- !ruby/object:Gem::Version
|
160
|
-
version: '2.
|
177
|
+
version: '2.1'
|
161
178
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
179
|
requirements:
|
163
180
|
- - ">="
|