translatomatic 0.1.3 → 0.2.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 +5 -5
- data/.gitattributes +20 -20
- data/.gitignore +19 -15
- data/.rspec +3 -3
- data/.rubocop.yml +28 -0
- data/.translatomatic/config.yml +4 -0
- data/.travis.yml +4 -6
- data/.yardopts +9 -9
- data/Gemfile +8 -4
- data/Guardfile +4 -5
- data/README.de.md +55 -50
- data/README.en.md +177 -0
- data/README.es.md +53 -48
- data/README.fr.md +53 -48
- data/README.it.md +54 -49
- data/README.ja.md +63 -58
- data/README.ko.md +59 -54
- data/README.md +17 -13
- data/README.ms.md +50 -45
- data/README.pt.md +54 -49
- data/README.ru.md +57 -52
- data/README.sv.md +51 -46
- data/README.zh.md +60 -55
- data/Rakefile +3 -3
- data/TODO.txt +6 -0
- data/bin/console +3 -3
- data/bin/translatomatic +4 -2
- data/config/i18n-tasks.yml +130 -0
- data/config/locales/translatomatic/de.yml +141 -99
- data/config/locales/translatomatic/en.yml +129 -89
- data/config/locales/translatomatic/es.yml +136 -99
- data/config/locales/translatomatic/fr.yml +139 -100
- data/config/locales/translatomatic/it.yml +135 -97
- data/config/locales/translatomatic/ja.yml +137 -98
- data/config/locales/translatomatic/ko.yml +138 -98
- data/config/locales/translatomatic/ms.yml +138 -100
- data/config/locales/translatomatic/pt.yml +137 -101
- data/config/locales/translatomatic/ru.yml +136 -98
- data/config/locales/translatomatic/sv.yml +134 -96
- data/config/locales/translatomatic/zh.yml +136 -97
- data/db/migrate/201712170000_initial.rb +2 -3
- data/lib/translatomatic.rb +40 -25
- data/lib/translatomatic/cli.rb +5 -1
- data/lib/translatomatic/cli/base.rb +61 -58
- data/lib/translatomatic/cli/common_options.rb +14 -11
- data/lib/translatomatic/cli/config.rb +96 -91
- data/lib/translatomatic/cli/database.rb +85 -23
- data/lib/translatomatic/cli/main.rb +158 -104
- data/lib/translatomatic/cli/thor.rb +29 -0
- data/lib/translatomatic/cli/translate.rb +134 -157
- data/lib/translatomatic/config.rb +10 -301
- data/lib/translatomatic/config/display.rb +78 -0
- data/lib/translatomatic/config/files.rb +60 -0
- data/lib/translatomatic/config/location_settings.rb +133 -0
- data/lib/translatomatic/config/options.rb +68 -0
- data/lib/translatomatic/config/selector.rb +127 -0
- data/lib/translatomatic/config/settings.rb +148 -0
- data/lib/translatomatic/converter.rb +40 -28
- data/lib/translatomatic/database.rb +127 -110
- data/lib/translatomatic/define_options.rb +4 -5
- data/lib/translatomatic/escaped_unicode.rb +86 -76
- data/lib/translatomatic/extractor.rb +5 -2
- data/lib/translatomatic/extractor/base.rb +12 -12
- data/lib/translatomatic/extractor/ruby.rb +7 -6
- data/lib/translatomatic/file_translator.rb +101 -244
- data/lib/translatomatic/flattenation.rb +39 -0
- data/lib/translatomatic/http.rb +13 -0
- data/lib/translatomatic/http/client.rb +144 -0
- data/lib/translatomatic/http/exception.rb +43 -0
- data/lib/translatomatic/http/file_param.rb +27 -0
- data/lib/translatomatic/http/param.rb +37 -0
- data/lib/translatomatic/http/request.rb +91 -0
- data/lib/translatomatic/i18n.rb +43 -0
- data/lib/translatomatic/locale.rb +71 -59
- data/lib/translatomatic/logger.rb +43 -28
- data/lib/translatomatic/metadata.rb +58 -0
- data/lib/translatomatic/model.rb +4 -2
- data/lib/translatomatic/model/locale.rb +5 -5
- data/lib/translatomatic/model/text.rb +5 -5
- data/lib/translatomatic/option.rb +57 -34
- data/lib/translatomatic/path_utils.rb +126 -0
- data/lib/translatomatic/progress_updater.rb +13 -16
- data/lib/translatomatic/provider.rb +101 -0
- data/lib/translatomatic/provider/base.rb +136 -0
- data/lib/translatomatic/provider/frengly.rb +55 -0
- data/lib/translatomatic/provider/google.rb +78 -0
- data/lib/translatomatic/provider/google_web.rb +50 -0
- data/lib/translatomatic/provider/microsoft.rb +144 -0
- data/lib/translatomatic/provider/my_memory.rb +75 -0
- data/lib/translatomatic/provider/yandex.rb +61 -0
- data/lib/translatomatic/resource_file.rb +59 -53
- data/lib/translatomatic/resource_file/base.rb +171 -237
- data/lib/translatomatic/resource_file/csv.rb +176 -24
- data/lib/translatomatic/resource_file/html.rb +21 -42
- data/lib/translatomatic/resource_file/key_value_support.rb +117 -0
- data/lib/translatomatic/resource_file/markdown.rb +36 -38
- data/lib/translatomatic/resource_file/plist.rb +121 -126
- data/lib/translatomatic/resource_file/po.rb +104 -82
- data/lib/translatomatic/resource_file/properties.rb +48 -77
- data/lib/translatomatic/resource_file/properties.treetop +87 -0
- data/lib/translatomatic/resource_file/resw.rb +56 -41
- data/lib/translatomatic/resource_file/subtitle.rb +86 -54
- data/lib/translatomatic/resource_file/text.rb +18 -18
- data/lib/translatomatic/resource_file/xcode_strings.rb +32 -63
- data/lib/translatomatic/resource_file/xcode_strings.treetop +85 -0
- data/lib/translatomatic/resource_file/xml.rb +94 -81
- data/lib/translatomatic/resource_file/yaml.rb +54 -68
- data/lib/translatomatic/retry_executor.rb +37 -0
- data/lib/translatomatic/slurp.rb +32 -0
- data/lib/translatomatic/string_batcher.rb +50 -0
- data/lib/translatomatic/string_escaping.rb +61 -0
- data/lib/translatomatic/text.rb +263 -0
- data/lib/translatomatic/text_collection.rb +66 -0
- data/lib/translatomatic/tmx.rb +5 -3
- data/lib/translatomatic/tmx/document.rb +107 -82
- data/lib/translatomatic/tmx/translation_unit.rb +19 -18
- data/lib/translatomatic/translation.rb +8 -28
- data/lib/translatomatic/translation/collection.rb +199 -0
- data/lib/translatomatic/translation/fetcher.rb +123 -0
- data/lib/translatomatic/translation/munging.rb +112 -0
- data/lib/translatomatic/translation/result.rb +50 -0
- data/lib/translatomatic/translation/sharer.rb +32 -0
- data/lib/translatomatic/translation/stats.rb +44 -0
- data/lib/translatomatic/translator.rb +91 -88
- data/lib/translatomatic/type_cast.rb +63 -0
- data/lib/translatomatic/util.rb +37 -33
- data/lib/translatomatic/version.rb +2 -2
- data/translatomatic.gemspec +57 -46
- metadata +136 -59
- data/lib/translatomatic/http_request.rb +0 -162
- data/lib/translatomatic/string.rb +0 -188
- data/lib/translatomatic/translation_result.rb +0 -86
- data/lib/translatomatic/translation_stats.rb +0 -31
- data/lib/translatomatic/translator/base.rb +0 -128
- data/lib/translatomatic/translator/frengly.rb +0 -62
- data/lib/translatomatic/translator/google.rb +0 -37
- data/lib/translatomatic/translator/microsoft.rb +0 -41
- data/lib/translatomatic/translator/my_memory.rb +0 -68
- data/lib/translatomatic/translator/yandex.rb +0 -56
@@ -1,37 +1,189 @@
|
|
1
1
|
require 'csv'
|
2
2
|
|
3
|
-
module Translatomatic
|
4
|
-
|
5
|
-
|
3
|
+
module Translatomatic
|
4
|
+
module ResourceFile
|
5
|
+
# CSV resource file
|
6
|
+
class CSV < Base
|
7
|
+
# (see Base.extensions)
|
8
|
+
def self.extensions
|
9
|
+
%w[csv]
|
10
|
+
end
|
6
11
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
# (see Base#set)
|
13
|
+
def set(key, value)
|
14
|
+
super(key, value)
|
15
|
+
if @cellmap.include?(key)
|
16
|
+
@cellmap[key].value = value
|
17
|
+
else
|
18
|
+
add_row(key, value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# (see Base#save)
|
23
|
+
def save(target = path, options = {})
|
24
|
+
use_headers = @options[:csv_headers]
|
25
|
+
csv_options = { write_headers: use_headers }
|
26
|
+
csv_options[:headers] = @headers if use_headers
|
11
27
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
csv << [key, value]
|
28
|
+
::CSV.open(target, 'wb', csv_options) do |csv|
|
29
|
+
@rows.each do |row|
|
30
|
+
csv << row.collect(&:value)
|
31
|
+
end
|
17
32
|
end
|
18
33
|
end
|
19
|
-
end
|
20
34
|
|
21
|
-
|
35
|
+
private
|
22
36
|
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
DEFAULT_KEY_COLUMN = 'key'.freeze
|
38
|
+
DEFAULT_VALUE_COLUMN = 'value'.freeze
|
39
|
+
DEFAULT_COMMENT_COLUMN = 'comments'.freeze
|
40
|
+
CONTEXT_COLUMN = 'tm.context'.freeze
|
41
|
+
|
42
|
+
define_option :csv_headers, type: :boolean, default: false,
|
43
|
+
desc: t('file.csv.headers')
|
44
|
+
define_option :csv_translate_columns, type: :array,
|
45
|
+
desc: t('file.csv.translate_columns')
|
46
|
+
define_option :csv_key_column, default: DEFAULT_KEY_COLUMN,
|
47
|
+
desc: t('file.csv.key_column')
|
48
|
+
define_option :csv_value_column, default: DEFAULT_VALUE_COLUMN,
|
49
|
+
desc: t('file.csv.value_column')
|
50
|
+
define_option :csv_comment_column, default: DEFAULT_COMMENT_COLUMN,
|
51
|
+
desc: t('file.csv.comment_column')
|
52
|
+
|
53
|
+
# @private
|
54
|
+
Cell = Struct.new(:header, :key, :value, :translate)
|
26
55
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@
|
56
|
+
def init
|
57
|
+
@rows = []
|
58
|
+
@cellmap = {} # map of String key -> Cell
|
59
|
+
@rownum = 0
|
60
|
+
@key_column = option(:csv_key_column, DEFAULT_KEY_COLUMN)
|
61
|
+
@value_column = option(:csv_value_column, DEFAULT_VALUE_COLUMN)
|
62
|
+
@comments_column = option(:csv_comment_column, DEFAULT_COMMENT_COLUMN)
|
63
|
+
@translate = option(:csv_translate_columns)
|
64
|
+
end
|
65
|
+
|
66
|
+
def option(key, default = nil)
|
67
|
+
@options[key] || default
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_row(key, value)
|
71
|
+
@rows << load_row(@key_column => key, @value_column => value)
|
72
|
+
end
|
73
|
+
|
74
|
+
def load
|
75
|
+
contents = read_contents(@path)
|
76
|
+
csv_options = { headers: @options[:csv_headers] }
|
77
|
+
|
78
|
+
@rows = []
|
79
|
+
@rownum = 0
|
80
|
+
|
81
|
+
csv = ::CSV.parse(contents, csv_options)
|
82
|
+
csv.each do |row|
|
83
|
+
@rows << load_row(row)
|
84
|
+
end
|
85
|
+
|
86
|
+
init_properties
|
87
|
+
end
|
88
|
+
|
89
|
+
# initialise properties and cellmap from @rows
|
90
|
+
def init_properties
|
91
|
+
@properties = {}
|
92
|
+
@cellmap = {}
|
93
|
+
@rows.each do |row|
|
94
|
+
row.each do |cell|
|
95
|
+
@properties[cell.key] = cell.value if cell.translate
|
96
|
+
@cellmap[cell.key] = cell
|
97
|
+
end
|
98
|
+
end
|
33
99
|
end
|
34
|
-
end
|
35
100
|
|
101
|
+
# @param row [Array<Cell>] row to convert to hash
|
102
|
+
def row_to_hash(row)
|
103
|
+
hash = {}
|
104
|
+
row.each do |cell|
|
105
|
+
hash[cell.header] = cell.value
|
106
|
+
end
|
107
|
+
hash
|
108
|
+
end
|
109
|
+
|
110
|
+
def load_row(row)
|
111
|
+
@rownum += 1
|
112
|
+
if row.is_a?(::CSV::Row)
|
113
|
+
@headers = row.headers
|
114
|
+
load_hash_row(row.to_h)
|
115
|
+
elsif row.is_a?(Hash)
|
116
|
+
load_hash_row(row)
|
117
|
+
elsif row.is_a?(Array)
|
118
|
+
load_array_row(row)
|
119
|
+
else
|
120
|
+
raise "invalid row data: #{row}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# row is an array of values
|
125
|
+
# @return [Array<Cell>] cells
|
126
|
+
def load_array_row(row)
|
127
|
+
cells = []
|
128
|
+
row.each_with_index do |value, i|
|
129
|
+
translate = translate_column?((i + 1).to_s)
|
130
|
+
key = "key#{@rownum},#{i + 1}"
|
131
|
+
cells << Cell.new("column#{i + 1}", key, value, translate)
|
132
|
+
end
|
133
|
+
parse_metadata(cells)
|
134
|
+
cells
|
135
|
+
end
|
136
|
+
|
137
|
+
# row is a hash of column -> value
|
138
|
+
# @return [Array<Cell>] cells
|
139
|
+
def load_hash_row(row)
|
140
|
+
cells = []
|
141
|
+
# add a property for each column
|
142
|
+
colnum = 0
|
143
|
+
row.each do |column, value|
|
144
|
+
colnum += 1
|
145
|
+
translate = translate_column?(column)
|
146
|
+
key = "key#{@rownum},#{colnum}"
|
147
|
+
cells << Cell.new(column, key, value, translate)
|
148
|
+
end
|
149
|
+
parse_metadata(cells)
|
150
|
+
cells
|
151
|
+
end
|
152
|
+
|
153
|
+
def translate_column?(column)
|
154
|
+
if @translate.present?
|
155
|
+
# translation columns specified
|
156
|
+
@translate.include?(column)
|
157
|
+
elsif have_target_locale_column?
|
158
|
+
# if there is a column matching the target locale, translate that
|
159
|
+
# column only.
|
160
|
+
column == @target_locale.to_s
|
161
|
+
else
|
162
|
+
# translate if it's not the key column or comments column
|
163
|
+
column != @key_column && column != @comments_column
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def have_target_locale_column?
|
168
|
+
@have_target_locale_column ||= begin
|
169
|
+
@target_locale && @headers &&
|
170
|
+
@headers.include?(@target_locale.to_s)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def parse_metadata(row)
|
175
|
+
comments_cell = find_cell(row, @comments_column)
|
176
|
+
return unless comments_cell
|
177
|
+
@metadata.parse_comment(comments_cell.value)
|
178
|
+
row.each do |cell|
|
179
|
+
@metadata.assign_key(cell.key, keep_context: true) if cell.translate
|
180
|
+
end
|
181
|
+
@metadata.clear_context
|
182
|
+
end
|
183
|
+
|
184
|
+
def find_cell(row, column_name)
|
185
|
+
row.find { |i| i.header == column_name }
|
186
|
+
end
|
187
|
+
end
|
36
188
|
end
|
37
189
|
end
|
@@ -1,55 +1,34 @@
|
|
1
|
-
module Translatomatic
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
# (see Translatomatic::ResourceFile::Base#locale_path)
|
11
|
-
def locale_path(locale)
|
12
|
-
extlist = extension_list
|
13
|
-
if extlist.length >= 2 && loc_idx = find_locale(extlist)
|
14
|
-
# part of the extension is the locale
|
15
|
-
# replace that part with the new locale
|
16
|
-
extlist[loc_idx] = locale.to_s
|
17
|
-
new_extension = extlist.join(".")
|
18
|
-
return strip_extensions.sub_ext("." + new_extension)
|
19
|
-
else
|
20
|
-
# add locale extension
|
21
|
-
ext = path.extname
|
22
|
-
# TODO: need configurable order for locale & ext here?
|
23
|
-
#path.sub_ext("#{ext}." + locale.to_s)
|
24
|
-
path.sub_ext("." + locale.to_s + ext)
|
1
|
+
module Translatomatic
|
2
|
+
module ResourceFile
|
3
|
+
# HTML resource file
|
4
|
+
class HTML < XML
|
5
|
+
# (see Base.extensions)
|
6
|
+
def self.extensions
|
7
|
+
%w[html htm shtml]
|
25
8
|
end
|
26
|
-
end
|
27
9
|
|
28
|
-
|
29
|
-
|
30
|
-
|
10
|
+
# (see Base#save)
|
11
|
+
def save(target = path, options = {})
|
12
|
+
return unless @doc
|
31
13
|
add_created_by unless options[:no_created_by]
|
32
14
|
target.write(@doc.to_html)
|
33
15
|
end
|
34
|
-
end
|
35
16
|
|
36
|
-
|
17
|
+
private
|
37
18
|
|
38
|
-
|
39
|
-
|
40
|
-
|
19
|
+
def read_doc
|
20
|
+
doc = Nokogiri::HTML(@path.open, &:noblanks)
|
21
|
+
parse_error(doc.errors[0]) if doc.errors.present?
|
22
|
+
doc
|
41
23
|
end
|
42
|
-
parse_error(doc.errors[0]) if doc.errors.present?
|
43
|
-
doc
|
44
|
-
end
|
45
24
|
|
46
|
-
|
47
|
-
|
48
|
-
|
25
|
+
def empty_doc
|
26
|
+
Nokogiri::HTML('<html><body></body></html>')
|
27
|
+
end
|
49
28
|
|
50
|
-
|
51
|
-
|
29
|
+
def text_nodes_xpath
|
30
|
+
'//*[not(self::code)]/text()|//comment()'
|
31
|
+
end
|
52
32
|
end
|
53
|
-
|
54
33
|
end
|
55
34
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Translatomatic
|
2
|
+
module ResourceFile
|
3
|
+
# @private
|
4
|
+
module KeyValueSupport
|
5
|
+
# (see Base.key_value?)
|
6
|
+
def self.key_value?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
# (see Base#set)
|
11
|
+
def set(key, value)
|
12
|
+
super(key, value)
|
13
|
+
if @map.include?(key)
|
14
|
+
@map[key].value = value
|
15
|
+
else
|
16
|
+
element = Definition.new(key, value)
|
17
|
+
@elements << element
|
18
|
+
@map[key] = element
|
19
|
+
@properties[key] = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# (see Base#save)
|
24
|
+
def save(target = path, options = {})
|
25
|
+
add_created_by unless options[:no_created_by] || created_by?
|
26
|
+
content = @elements.collect { |i| render_element(i) }.join
|
27
|
+
content = content.gsub(/[\r\n]+\Z/, '') + "\n"
|
28
|
+
target.write(content)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def init
|
34
|
+
@elements = [] # key/values or comment elements
|
35
|
+
@map = {} # map key to elements
|
36
|
+
end
|
37
|
+
|
38
|
+
def load
|
39
|
+
@metadata.reset
|
40
|
+
@doc = read_doc
|
41
|
+
@elements = init_elements
|
42
|
+
@properties = {}
|
43
|
+
@elements.each do |element|
|
44
|
+
if element.is_a?(Comment)
|
45
|
+
@metadata.parse_comment(element.text)
|
46
|
+
elsif element.is_a?(Definition)
|
47
|
+
@metadata.assign_key(element.key)
|
48
|
+
@properties[element.key] = element.value
|
49
|
+
@map[element.key] = element
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# parse document to a list of elements
|
55
|
+
def read_doc
|
56
|
+
content = read_contents(@path)
|
57
|
+
document = parse_doc(content)
|
58
|
+
raise t('file.invalid') unless document
|
59
|
+
document
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_doc(_content)
|
63
|
+
raise 'parse_doc must be implemented by subclass'
|
64
|
+
end
|
65
|
+
|
66
|
+
def render_element(_element)
|
67
|
+
raise 'render_element must be implemented by subclass'
|
68
|
+
end
|
69
|
+
|
70
|
+
def init_elements
|
71
|
+
# convert to a list of elements
|
72
|
+
@doc.content.collect do |item|
|
73
|
+
case item[0]
|
74
|
+
when :comment
|
75
|
+
content_to_comment(item)
|
76
|
+
when :definition
|
77
|
+
content_to_definition(item)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def content_to_definition(item)
|
83
|
+
key = unescape(item[1])
|
84
|
+
value = unescape(item[2])
|
85
|
+
# remove line continuations
|
86
|
+
value = value.gsub(/\\\n\s*/, '')
|
87
|
+
Definition.new(key, value)
|
88
|
+
end
|
89
|
+
|
90
|
+
def content_to_comment(item)
|
91
|
+
text = unescape(item[1])
|
92
|
+
Comment.new(text, item[2])
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_created_by
|
96
|
+
@created_by ||= begin
|
97
|
+
created_by = Comment.new(created_by)
|
98
|
+
@elements.unshift(created_by)
|
99
|
+
created_by
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def escape(value)
|
104
|
+
Translatomatic::StringEscaping.escape(value)
|
105
|
+
end
|
106
|
+
|
107
|
+
def unescape(value)
|
108
|
+
Translatomatic::StringEscaping.unescape_all(value)
|
109
|
+
end
|
110
|
+
|
111
|
+
# @private
|
112
|
+
Definition = Struct.new(:key, :value)
|
113
|
+
# @private
|
114
|
+
Comment = Struct.new(:text, :type)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -1,50 +1,48 @@
|
|
1
1
|
require 'kramdown'
|
2
2
|
require 'reverse_markdown'
|
3
3
|
|
4
|
-
module Translatomatic
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
module Translatomatic
|
5
|
+
module ResourceFile
|
6
|
+
# Markdown resource file
|
7
|
+
class Markdown < HTML
|
8
|
+
# (see Base.extensions)
|
9
|
+
def self.extensions
|
10
|
+
%w[md]
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
# (see Base#save)
|
14
|
+
def save(target = path, options = {})
|
15
|
+
if @doc
|
16
|
+
add_created_by unless options[:no_created_by]
|
17
|
+
html = @doc.to_html
|
18
|
+
# convert html back to markdown
|
19
|
+
markdown = ReverseMarkdown.convert(html, unknown_tags: :bypass)
|
20
|
+
target.write(markdown.chomp)
|
21
|
+
end
|
21
22
|
end
|
22
|
-
end
|
23
23
|
|
24
|
-
|
24
|
+
private
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def add_created_by
|
27
|
+
@created_by ||= begin
|
28
|
+
body = @doc.at('body')
|
29
|
+
body.add_child("<p><i>#{created_by}</i></p>")
|
30
|
+
end
|
30
31
|
end
|
31
|
-
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
def read_doc
|
34
|
+
# read markdown and convert to html
|
35
|
+
markdown = read_contents(@path)
|
36
|
+
if markdown.blank?
|
37
|
+
empty_doc
|
38
|
+
else
|
39
|
+
html = Kramdown::Document.new(markdown).to_html
|
40
|
+
# parse html with nokogiri
|
41
|
+
doc = Nokogiri::HTML(html, &:noblanks)
|
42
|
+
parse_error(doc.errors[0]) if doc.errors.present?
|
43
|
+
doc
|
43
44
|
end
|
44
|
-
parse_error(doc.errors[0]) if doc.errors.present?
|
45
|
-
doc
|
46
45
|
end
|
47
46
|
end
|
48
|
-
|
49
|
-
|
50
|
-
end # module
|
47
|
+
end
|
48
|
+
end
|