bookbindery 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bookbinder.rb +0 -4
- data/lib/bookbinder/archive.rb +12 -5
- data/lib/bookbinder/archive_menu_configuration.rb +4 -4
- data/lib/bookbinder/commands/bind.rb +29 -97
- data/lib/bookbinder/commands/bind/bind_options.rb +50 -0
- data/lib/bookbinder/commands/bind/directory_preparer.rb +13 -12
- data/lib/bookbinder/commands/build_and_push_tarball.rb +1 -8
- data/lib/bookbinder/commands/help.rb +1 -1
- data/lib/bookbinder/commands/run_publish_ci.rb +1 -3
- data/lib/bookbinder/commands/tag.rb +12 -9
- data/lib/bookbinder/commands/update_local_doc_repos.rb +23 -7
- data/lib/bookbinder/config/bind_config_factory.rb +5 -7
- data/lib/bookbinder/config/remote_bind_configuration.rb +23 -31
- data/lib/bookbinder/config/section_config.rb +56 -0
- data/lib/bookbinder/configuration.rb +58 -18
- data/lib/bookbinder/configuration_fetcher.rb +3 -5
- data/lib/bookbinder/configuration_validator.rb +1 -8
- data/lib/bookbinder/distributor.rb +1 -1
- data/lib/bookbinder/dita_command_creator.rb +60 -16
- data/lib/bookbinder/dita_html_to_middleman_formatter.rb +3 -2
- data/lib/bookbinder/errors/programmer_mistake.rb +5 -0
- data/lib/bookbinder/git_accessor.rb +36 -2
- data/lib/bookbinder/ingest/cloner_factory.rb +3 -3
- data/lib/bookbinder/ingest/destination_directory.rb +7 -1
- data/lib/bookbinder/ingest/{git_hub_repository_cloner.rb → git_cloner.rb} +3 -2
- data/lib/bookbinder/ingest/repo_identifier.rb +45 -0
- data/lib/bookbinder/local_file_system_accessor.rb +4 -9
- data/lib/bookbinder/middleman_runner.rb +5 -6
- data/lib/bookbinder/preprocessing/copy_to_site_gen_dir.rb +27 -0
- data/lib/bookbinder/preprocessing/dita_preprocessor.rb +103 -0
- data/lib/bookbinder/preprocessing/preprocessor.rb +26 -0
- data/lib/bookbinder/repositories/command_repository.rb +17 -21
- data/lib/bookbinder/repositories/section_repository.rb +24 -16
- data/lib/bookbinder/repositories/section_repository_factory.rb +19 -0
- data/lib/bookbinder/streams/{switchable_stdout_and_red_stderr.rb → colorized_stream.rb} +0 -17
- data/lib/bookbinder/time_fetcher.rb +7 -0
- data/lib/bookbinder/validation_checkers/dita_section_checker.rb +2 -2
- data/lib/bookbinder/values/output_locations.rb +13 -12
- data/lib/bookbinder/values/section.rb +22 -5
- data/master_middleman/bookbinder_helpers.rb +4 -11
- metadata +59 -75
- data/lib/bookbinder/book.rb +0 -59
- data/lib/bookbinder/config/local_bind_configuration.rb +0 -23
- data/lib/bookbinder/dita_preprocessor.rb +0 -68
- data/lib/bookbinder/dita_section_gatherer_factory.rb +0 -23
- data/lib/bookbinder/git_client.rb +0 -66
- data/lib/bookbinder/git_hub_repository.rb +0 -101
- data/lib/bookbinder/local_dita_section_gatherer.rb +0 -32
- data/lib/bookbinder/remote_dita_section_gatherer.rb +0 -35
- data/lib/bookbinder/validation_checkers/config_version_checker.rb +0 -91
- data/lib/bookbinder/values/code_example.rb +0 -7
- data/lib/bookbinder/values/dita_section.rb +0 -39
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative '../bookbinder/values/dita_section'
|
2
|
-
|
3
1
|
module Bookbinder
|
4
2
|
class DitaCommandCreator
|
3
|
+
MissingDitaOTFlagValue = Class.new(RuntimeError)
|
4
|
+
|
5
5
|
def initialize(path_to_dita_ot_library)
|
6
6
|
@path_to_dita_ot_library = path_to_dita_ot_library
|
7
7
|
end
|
8
8
|
|
9
|
-
def convert_to_html_command(dita_section, write_to: nil)
|
9
|
+
def convert_to_html_command(dita_section, dita_flags: nil, write_to: nil)
|
10
10
|
classpath = "#{path_to_dita_ot_library}/lib/xercesImpl.jar:" +
|
11
11
|
"#{path_to_dita_ot_library}/lib/xml-apis.jar:" +
|
12
12
|
"#{path_to_dita_ot_library}/lib/resolver.jar:" +
|
@@ -17,23 +17,67 @@ module Bookbinder
|
|
17
17
|
"#{path_to_dita_ot_library}:" +
|
18
18
|
"#{path_to_dita_ot_library}/lib/:" +
|
19
19
|
"#{path_to_dita_ot_library}/lib/dost.jar"
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
if dita_section.absolute_path_to_ditaval
|
30
|
-
command += "-Dargs.filter=#{dita_section.absolute_path_to_ditaval} "
|
31
|
-
end
|
32
|
-
command
|
20
|
+
|
21
|
+
"export CLASSPATH=#{classpath}; " +
|
22
|
+
"ant -f #{path_to_dita_ot_library} " +
|
23
|
+
unduplicated_flags(
|
24
|
+
write_to: write_to,
|
25
|
+
dita_flags: dita_flags,
|
26
|
+
ditamap_path: dita_section.path_to_preprocessor_attribute('ditamap_location'),
|
27
|
+
ditaval_path: dita_section.path_to_preprocessor_attribute('ditaval_location'),
|
28
|
+
)
|
33
29
|
end
|
34
30
|
|
35
31
|
private
|
36
32
|
|
33
|
+
def unduplicated_flags(write_to: nil, ditamap_path: nil, ditaval_path: nil, dita_flags: dita_flags)
|
34
|
+
arg_flags = {
|
35
|
+
'output.dir' => write_to,
|
36
|
+
'args.input' => ditamap_path,
|
37
|
+
}.merge(filter(ditaval_path))
|
38
|
+
all_flags = arg_flags.merge(base_flags.merge(optional_flags dita_flags))
|
39
|
+
format(all_flags)
|
40
|
+
end
|
41
|
+
|
42
|
+
def filter(ditaval_path)
|
43
|
+
if ditaval_path
|
44
|
+
{ 'args.filter' => ditaval_path }
|
45
|
+
else
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def base_flags
|
51
|
+
{
|
52
|
+
'basedir' => '/',
|
53
|
+
'transtype' => 'tocjs',
|
54
|
+
'dita.temp.dir' => '/tmp/bookbinder_dita',
|
55
|
+
'generate.copy.outer' => '2',
|
56
|
+
'outer.control' => 'warn'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def optional_flags(flags_str)
|
61
|
+
flags = flags_str ? flags_str.split(" ") : []
|
62
|
+
flags.inject({}) do |h, f|
|
63
|
+
k,v = f.split('=')
|
64
|
+
h[k] = v
|
65
|
+
raise MissingDitaOTFlagValue.new("The DITA-flag '#{k}' that you passed is missing a value. Please pass your DITA option in the format '#{k}=<value>'.") unless v
|
66
|
+
h
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def format(flags)
|
71
|
+
flags.inject("") do |res, f|
|
72
|
+
k,v = f
|
73
|
+
res += "-D#{k}='#{stripped_flag_value v}' "
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def stripped_flag_value(v)
|
78
|
+
v.to_s.gsub(/['|"]/, "")
|
79
|
+
end
|
80
|
+
|
37
81
|
attr_reader :path_to_dita_ot_library
|
38
82
|
end
|
39
83
|
end
|
@@ -29,11 +29,12 @@ module Bookbinder
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def format_subnav(
|
32
|
+
def format_subnav(path_to_dita_section,
|
33
33
|
subnav_template_text,
|
34
34
|
json_props_location,
|
35
35
|
unformatted_subnav_text)
|
36
|
-
formatted_json_links = subnav_formatter.get_links_as_json(unformatted_subnav_text,
|
36
|
+
formatted_json_links = subnav_formatter.get_links_as_json(unformatted_subnav_text,
|
37
|
+
path_to_dita_section)
|
37
38
|
|
38
39
|
nav_text = html_document_manipulator.set_attribute(document: subnav_template_text,
|
39
40
|
selector: 'div.nav-content',
|
@@ -2,6 +2,9 @@ require 'git'
|
|
2
2
|
|
3
3
|
module Bookbinder
|
4
4
|
class GitAccessor
|
5
|
+
TagExists = Class.new(RuntimeError)
|
6
|
+
InvalidTagRef = Class.new(RuntimeError)
|
7
|
+
|
5
8
|
def initialize
|
6
9
|
@cache = {}
|
7
10
|
end
|
@@ -12,12 +15,39 @@ module Bookbinder
|
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
18
|
+
def update(cloned_path)
|
19
|
+
Git.open(cloned_path).pull
|
20
|
+
end
|
21
|
+
|
15
22
|
def read_file(filename, from_repo: nil, checkout: 'master')
|
16
23
|
Dir.mktmpdir do |dir|
|
17
24
|
path = Pathname(dir)
|
18
|
-
git = _clone(from_repo, "read-file", path)
|
25
|
+
git = _clone(from_repo, temp_name("read-file"), path)
|
19
26
|
git.checkout(checkout)
|
20
|
-
path.join("read-file", filename).read
|
27
|
+
path.join(temp_name("read-file"), filename).read
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def remote_tag(url, tagname, commit_or_object)
|
32
|
+
Dir.mktmpdir do |dir|
|
33
|
+
path = Pathname(dir)
|
34
|
+
git = _clone(url, temp_name("tag"), path)
|
35
|
+
git.config('user.name', 'Bookbinder')
|
36
|
+
git.config('user.email', 'bookbinder@cloudfoundry.org')
|
37
|
+
begin
|
38
|
+
git.add_tag(tagname, "origin/#{commit_or_object}",
|
39
|
+
message: 'Tagged by Bookbinder')
|
40
|
+
rescue Git::GitExecuteError => e
|
41
|
+
case e.message
|
42
|
+
when /already exists/
|
43
|
+
raise TagExists
|
44
|
+
when /as a valid ref/
|
45
|
+
raise InvalidTagRef
|
46
|
+
else
|
47
|
+
raise
|
48
|
+
end
|
49
|
+
end
|
50
|
+
git.push("origin", "master", tags: true)
|
21
51
|
end
|
22
52
|
end
|
23
53
|
|
@@ -25,6 +55,10 @@ module Bookbinder
|
|
25
55
|
|
26
56
|
attr_reader :cache
|
27
57
|
|
58
|
+
def temp_name(purpose)
|
59
|
+
"bookbinder-git-accessor-#{purpose}"
|
60
|
+
end
|
61
|
+
|
28
62
|
def cached_clone(url, name, path)
|
29
63
|
cache[[url, name, path]] ||= _clone(url, name, path)
|
30
64
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'git_cloner'
|
2
2
|
require_relative 'local_filesystem_cloner'
|
3
3
|
|
4
4
|
module Bookbinder
|
@@ -10,11 +10,11 @@ module Bookbinder
|
|
10
10
|
@version_control_system = version_control_system
|
11
11
|
end
|
12
12
|
|
13
|
-
def produce(
|
13
|
+
def produce(user_repo_dir)
|
14
14
|
if user_repo_dir
|
15
15
|
LocalFilesystemCloner.new(logger, filesystem, user_repo_dir)
|
16
16
|
else
|
17
|
-
|
17
|
+
GitCloner.new(version_control_system)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -2,7 +2,13 @@ module Bookbinder
|
|
2
2
|
module Ingest
|
3
3
|
DestinationDirectory = Struct.new(:full_repo_name, :desired_destination_dir_name) do
|
4
4
|
def to_str
|
5
|
-
desired_destination_dir_name
|
5
|
+
if desired_destination_dir_name
|
6
|
+
desired_destination_dir_name.to_s
|
7
|
+
elsif full_repo_name
|
8
|
+
full_repo_name.split('/').last
|
9
|
+
else
|
10
|
+
""
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
14
|
alias :to_s :to_str
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require_relative 'destination_directory'
|
2
|
+
require_relative 'repo_identifier'
|
2
3
|
require_relative 'working_copy'
|
3
4
|
|
4
5
|
module Bookbinder
|
5
6
|
module Ingest
|
6
|
-
class
|
7
|
+
class GitCloner
|
7
8
|
def initialize(version_control_system)
|
8
9
|
@version_control_system = version_control_system
|
9
10
|
end
|
@@ -15,7 +16,7 @@ module Bookbinder
|
|
15
16
|
dest_dir = DestinationDirectory.new(source_repo_name, destination_dir_name)
|
16
17
|
copied_to = Pathname(destination_parent_dir).join(dest_dir)
|
17
18
|
version_control_system.clone(
|
18
|
-
|
19
|
+
RepoIdentifier.new(source_repo_name),
|
19
20
|
dest_dir,
|
20
21
|
path: destination_parent_dir,
|
21
22
|
checkout: source_ref
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
module Ingest
|
3
|
+
class RepoIdentifier
|
4
|
+
DEFAULT_VCS_PREFIX = 'git@github.com:'
|
5
|
+
|
6
|
+
def initialize(input_identifier)
|
7
|
+
@input_identifier = input_identifier
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_str
|
11
|
+
if input_identifier.nil?
|
12
|
+
""
|
13
|
+
elsif input_identifier.include?(':')
|
14
|
+
input_identifier
|
15
|
+
else
|
16
|
+
"#{DEFAULT_VCS_PREFIX}#{input_identifier}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
alias :to_s :to_str
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
%Q("#{to_s}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def split(*args)
|
27
|
+
input_identifier.split(*args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def hash
|
31
|
+
to_str.hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def ==(other)
|
35
|
+
to_str == other
|
36
|
+
end
|
37
|
+
|
38
|
+
alias :eql? :==
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_reader :input_identifier
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'find'
|
2
2
|
require 'pathname'
|
3
3
|
require 'nokogiri'
|
4
|
+
require_relative 'errors/programmer_mistake'
|
4
5
|
|
5
6
|
module Bookbinder
|
6
7
|
|
@@ -32,19 +33,13 @@ module Bookbinder
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def copy(src, dest)
|
35
|
-
|
36
|
-
FileUtils.mkdir_p(dest)
|
37
|
-
end
|
38
|
-
|
36
|
+
make_directory(dest)
|
39
37
|
FileUtils.cp_r src, dest
|
40
38
|
end
|
41
39
|
|
42
40
|
def copy_contents(src, dest)
|
43
|
-
unless
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
FileUtils.cp_r "#{src}/.", dest
|
41
|
+
raise Errors::ProgrammerMistake.new("The method copy_contents cannot copy the contents of the directory '#{src}' because it was not found.") unless Dir.exists?(src)
|
42
|
+
copy "#{src}/.", dest
|
48
43
|
end
|
49
44
|
|
50
45
|
def copy_including_intermediate_dirs(file, root, dest)
|
@@ -1,13 +1,12 @@
|
|
1
|
+
require 'git/lib'
|
1
2
|
require 'middleman-core'
|
2
3
|
require 'middleman-core/cli'
|
3
4
|
require 'middleman-core/profiling'
|
4
|
-
require_relative 'values/code_example'
|
5
5
|
require_relative 'code_example_reader'
|
6
6
|
|
7
7
|
class Middleman::Cli::BuildAction
|
8
8
|
def handle_error(file_name, response, e=Thor::Error.new(response))
|
9
|
-
our_errors = [Bookbinder::
|
10
|
-
Bookbinder::CodeExampleReader::InvalidSnippet,
|
9
|
+
our_errors = [Bookbinder::CodeExampleReader::InvalidSnippet,
|
11
10
|
QuicklinksRenderer::BadHeadingLevelError,
|
12
11
|
Git::GitExecuteError]
|
13
12
|
raise e if our_errors.include?(e.class)
|
@@ -46,10 +45,10 @@ module Bookbinder
|
|
46
45
|
|
47
46
|
within(output_locations.master_dir) do
|
48
47
|
invoke_against_current_dir(output_locations.workspace_dir,
|
49
|
-
config
|
48
|
+
config.public_host,
|
50
49
|
subnav_templates_by_directory,
|
51
|
-
config.
|
52
|
-
config
|
50
|
+
config.template_variables,
|
51
|
+
config.archive_menu,
|
53
52
|
verbose,
|
54
53
|
cloner)
|
55
54
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Bookbinder
|
2
|
+
module Preprocessing
|
3
|
+
class CopyToSiteGenDir
|
4
|
+
def initialize(filesystem)
|
5
|
+
@filesystem = filesystem
|
6
|
+
end
|
7
|
+
|
8
|
+
def applicable_to?(section)
|
9
|
+
section.subnav_template != 'dita_subnav' &&
|
10
|
+
filesystem.file_exist?(section.path_to_repository)
|
11
|
+
end
|
12
|
+
|
13
|
+
def preprocess(sections, output_locations, *_)
|
14
|
+
sections.each do |section|
|
15
|
+
filesystem.copy_contents(
|
16
|
+
section.path_to_repository,
|
17
|
+
output_locations.source_for_site_generator.join(section.desired_directory)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :filesystem
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require_relative '../values/subnav'
|
2
|
+
|
3
|
+
module Bookbinder
|
4
|
+
module Preprocessing
|
5
|
+
class DitaPreprocessor
|
6
|
+
DitaToHtmlLibraryFailure = Class.new(RuntimeError)
|
7
|
+
|
8
|
+
ACCEPTED_IMAGE_FORMATS = %w(png jpeg jpg svg gif bmp tif tiff eps)
|
9
|
+
|
10
|
+
def initialize(dita_formatter, local_fs_accessor, command_creator, sheller)
|
11
|
+
@dita_formatter = dita_formatter
|
12
|
+
@local_fs_accessor = local_fs_accessor
|
13
|
+
@command_creator = command_creator
|
14
|
+
@sheller = sheller
|
15
|
+
end
|
16
|
+
|
17
|
+
def applicable_to?(section)
|
18
|
+
section.subnav_template == 'dita_subnav'
|
19
|
+
end
|
20
|
+
|
21
|
+
def preprocess(dita_sections, output_locations, options: nil, output_streams: nil)
|
22
|
+
dita_sections.select { |dita_section| dita_section.path_to_preprocessor_attribute('ditamap_location') }.each do |dita_section|
|
23
|
+
command = command_creator.convert_to_html_command(
|
24
|
+
dita_section,
|
25
|
+
dita_flags: dita_flags(options),
|
26
|
+
write_to: output_locations.html_from_preprocessing_dir.join(dita_section.desired_directory)
|
27
|
+
)
|
28
|
+
status = sheller.run_command(command, output_streams.to_h)
|
29
|
+
unless status.success?
|
30
|
+
raise DitaToHtmlLibraryFailure.new 'The DITA-to-HTML conversion failed. ' +
|
31
|
+
'Please check that you have specified the path to your DITA-OT library in the ENV, ' +
|
32
|
+
'that your DITA-specific keys/values in config.yml are set, ' +
|
33
|
+
'and that your DITA toolkit is correctly configured.'
|
34
|
+
end
|
35
|
+
|
36
|
+
generate_subnav(dita_section.desired_directory,
|
37
|
+
output_locations,
|
38
|
+
output_locations.source_for_site_generator.join('subnavs', '_dita_subnav_template.erb'),
|
39
|
+
output_locations.subnavs_for_layout_dir)
|
40
|
+
end
|
41
|
+
|
42
|
+
dita_sections.each do |dita_section|
|
43
|
+
html_dir = output_locations.html_from_preprocessing_dir.join(dita_section.desired_directory)
|
44
|
+
formatted_dir = output_locations.formatted_dir.join(dita_section.desired_directory)
|
45
|
+
source_for_site_gen_dir = output_locations.source_for_site_generator.join(dita_section.desired_directory)
|
46
|
+
|
47
|
+
dita_formatter.format_html html_dir, formatted_dir
|
48
|
+
|
49
|
+
copy_images(dita_section.path_to_repository, formatted_dir)
|
50
|
+
|
51
|
+
local_fs_accessor.copy_contents(formatted_dir, source_for_site_gen_dir)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
attr_reader :dita_formatter, :local_fs_accessor, :command_creator, :sheller
|
58
|
+
|
59
|
+
def generate_subnav(dita_section_dir, output_locations, dita_subnav_template_path, subnavs_dir)
|
60
|
+
dita_subnav_template_text = local_fs_accessor.read(dita_subnav_template_path)
|
61
|
+
|
62
|
+
tocjs_text = local_fs_accessor.read(
|
63
|
+
File.join(
|
64
|
+
output_locations.html_from_preprocessing_dir.join(dita_section_dir),
|
65
|
+
'index.html')
|
66
|
+
)
|
67
|
+
json_props_location = File.join('dita-subnav-props.json')
|
68
|
+
props_file_location = File.join(subnavs_dir, json_props_location)
|
69
|
+
|
70
|
+
subnav = dita_formatter.format_subnav(dita_section_dir,
|
71
|
+
dita_subnav_template_text,
|
72
|
+
json_props_location,
|
73
|
+
tocjs_text)
|
74
|
+
|
75
|
+
local_fs_accessor.write text: subnav.json_links, to: props_file_location
|
76
|
+
|
77
|
+
local_fs_accessor.write text: subnav.text,
|
78
|
+
to: File.join(subnavs_dir, "dita_subnav.erb")
|
79
|
+
end
|
80
|
+
|
81
|
+
def copy_images(src, dest)
|
82
|
+
image_paths = ACCEPTED_IMAGE_FORMATS.map do |format|
|
83
|
+
local_fs_accessor.find_files_with_ext(format, src)
|
84
|
+
end.flatten
|
85
|
+
|
86
|
+
image_paths.each do |image_path|
|
87
|
+
local_fs_accessor.copy_including_intermediate_dirs(image_path,
|
88
|
+
src,
|
89
|
+
dest)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def dita_flags(opts)
|
94
|
+
matching_flags = opts.map {|o| o[flag_value_regex("dita-flags"), 1] }
|
95
|
+
matching_flags.compact.first
|
96
|
+
end
|
97
|
+
|
98
|
+
def flag_value_regex(flag_name)
|
99
|
+
Regexp.new(/--#{flag_name}=(.+)/)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|