asciidoctor-templates-compiler 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|