jekyll-l10n 2.0.0 → 3.0.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.md +44 -0
- data/lib/jekyll-l10n/configuration/schema.rb +308 -0
- data/lib/jekyll-l10n/configuration.rb +165 -0
- data/lib/jekyll-l10n/constants.rb +45 -10
- data/lib/jekyll-l10n/errors.rb +7 -0
- data/lib/jekyll-l10n/extraction/compendium_merger.rb +9 -11
- data/lib/jekyll-l10n/extraction/compendium_translator.rb +27 -11
- data/lib/jekyll-l10n/extraction/config_loader.rb +4 -4
- data/lib/jekyll-l10n/extraction/coverage_report.rb +129 -0
- data/lib/jekyll-l10n/extraction/dom_text_extractor.rb +2 -31
- data/lib/jekyll-l10n/extraction/extractor.rb +48 -28
- data/lib/jekyll-l10n/extraction/html_string_extractor.rb +24 -10
- data/lib/jekyll-l10n/extraction/logger.rb +6 -5
- data/lib/jekyll-l10n/extraction/result_saver.rb +5 -10
- data/lib/jekyll-l10n/instrumentation.rb +172 -139
- data/lib/jekyll-l10n/jekyll/generator.rb +10 -22
- data/lib/jekyll-l10n/jekyll/localized_page.rb +27 -49
- data/lib/jekyll-l10n/jekyll/post_write_html_reprocessor.rb +42 -25
- data/lib/jekyll-l10n/jekyll/post_write_processor.rb +2 -1
- data/lib/jekyll-l10n/jekyll/regeneration_checker.rb +16 -10
- data/lib/jekyll-l10n/jekyll/url_filter.rb +8 -7
- data/lib/jekyll-l10n/po_file/entry_parser.rb +155 -0
- data/lib/jekyll-l10n/po_file/fuzzy_matcher.rb +67 -53
- data/lib/jekyll-l10n/po_file/loader.rb +20 -11
- data/lib/jekyll-l10n/po_file/manager.rb +32 -17
- data/lib/jekyll-l10n/po_file/merger.rb +2 -1
- data/lib/jekyll-l10n/po_file/path_builder.rb +11 -1
- data/lib/jekyll-l10n/po_file/reader.rb +40 -508
- data/lib/jekyll-l10n/po_file/writer.rb +31 -16
- data/lib/jekyll-l10n/translation/block_text_extractor.rb +3 -7
- data/lib/jekyll-l10n/translation/html_translator.rb +136 -157
- data/lib/jekyll-l10n/translation/libre_translate_languages.rb +73 -0
- data/lib/jekyll-l10n/translation/libre_translator.rb +134 -78
- data/lib/jekyll-l10n/translation/request_slots.rb +69 -0
- data/lib/jekyll-l10n/translation/translation_progress.rb +77 -0
- data/lib/jekyll-l10n/translation/translator.rb +20 -17
- data/lib/jekyll-l10n/utils/baseurl_normalizer.rb +108 -0
- data/lib/jekyll-l10n/utils/debug_logger.rb +4 -51
- data/lib/jekyll-l10n/utils/error_handler.rb +9 -24
- data/lib/jekyll-l10n/utils/external_link_icon_preserver.rb +5 -62
- data/lib/jekyll-l10n/utils/html_parser.rb +24 -31
- data/lib/jekyll-l10n/utils/html_text_utils.rb +146 -91
- data/lib/jekyll-l10n/utils/logger_formatter.rb +6 -4
- data/lib/jekyll-l10n/utils/msgstr_validator.rb +74 -0
- data/lib/jekyll-l10n/utils/page_locales_config.rb +126 -107
- data/lib/jekyll-l10n/utils/po_entry_converter.rb +0 -43
- data/lib/jekyll-l10n/utils/site_config_accessor.rb +56 -54
- data/lib/jekyll-l10n/utils/translation_resolver.rb +56 -6
- data/lib/jekyll-l10n/utils/url_path_builder.rb +5 -27
- data/lib/jekyll-l10n/utils/url_transformer.rb +5 -11
- data/lib/jekyll-l10n/version.rb +1 -1
- data/lib/jekyll-l10n.rb +9 -6
- metadata +12 -3
|
@@ -1,103 +1,105 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../configuration'
|
|
4
|
+
require_relative 'page_locales_config'
|
|
5
|
+
|
|
3
6
|
module Jekyll
|
|
4
7
|
module L10n
|
|
5
|
-
# Reads
|
|
8
|
+
# Reads the plugin's settings from the site and its pages.
|
|
6
9
|
#
|
|
7
10
|
# The plugin reads settings in two ways, and this class holds both:
|
|
8
11
|
# - Per-page settings: {.page_locales_data} merges the page's front matter
|
|
9
12
|
# over the `_config.yml` defaults that match the page. Read page settings
|
|
10
13
|
# through it (or {.effective_page_data}), never from `page.data` directly.
|
|
11
|
-
# - Site-wide settings: {.
|
|
12
|
-
#
|
|
14
|
+
# - Site-wide settings: {.site_settings} returns the top-level `jekyll_l10n`
|
|
15
|
+
# settings, and {.site_config} wraps them, with the site's locales, in a
|
|
16
|
+
# PageLocalesConfig for the build-wide steps.
|
|
13
17
|
#
|
|
14
18
|
# Methods that take a site also accept a Hash, so specs can pass a plain
|
|
15
19
|
# hash instead of a Jekyll::Site.
|
|
16
20
|
#
|
|
17
21
|
# @example
|
|
18
22
|
# SiteConfigAccessor.page_locales_data(page)['locales'] # => ["es", "fr"]
|
|
19
|
-
# SiteConfigAccessor.
|
|
23
|
+
# SiteConfigAccessor.site_config(site).update_compendium? # => true
|
|
20
24
|
class SiteConfigAccessor
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
+
# The checked top-level `jekyll_l10n` settings, which apply to the whole
|
|
26
|
+
# build. See Configuration.site.
|
|
27
|
+
#
|
|
28
|
+
# @param site [Jekyll::Site, Hash] The site, or a hash in specs
|
|
29
|
+
# @return [Hash] The settings (frozen), or {} when `jekyll_l10n` is not set
|
|
30
|
+
def self.site_settings(site)
|
|
31
|
+
Configuration.site(site_config_hash(site) || {})
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Settings for the steps that run once per build (extraction summary,
|
|
35
|
+
# compendium merge, machine translation): the {.site_settings} merged
|
|
36
|
+
# over the first `defaults` entry's `with_locales_data`, which gives the
|
|
37
|
+
# site's `locales` and `locales_dir`.
|
|
38
|
+
#
|
|
39
|
+
# @param site [Jekyll::Site, Hash] The site, or a hash in specs
|
|
40
|
+
# @param all_locales [Boolean] Use {.all_configured_locales} as the
|
|
41
|
+
# locale list, so locales that only some pages add are covered too
|
|
42
|
+
# @return [PageLocalesConfig]
|
|
43
|
+
def self.site_config(site, all_locales: false)
|
|
44
|
+
data = extract_locales_data(site)
|
|
45
|
+
data = data.merge('locales' => all_configured_locales(site)) if all_locales
|
|
46
|
+
PageLocalesConfig.new(Configuration::PAGE_DATA_KEY => Jekyll::Utils.deep_merge_hashes(data, site_settings(site)))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The first `defaults` entry's `with_locales_data`, whatever pages it
|
|
50
|
+
# matches, checked by Schema. Its `locales` and `locales_dir` are the
|
|
51
|
+
# site's own; prefer {.site_config}, which adds the `jekyll_l10n`
|
|
52
|
+
# settings.
|
|
25
53
|
#
|
|
26
54
|
# @param site [Jekyll::Site, Hash] The site, or a hash in specs
|
|
27
55
|
# @return [Hash] The settings, or {} when no entry has them
|
|
28
56
|
def self.extract_locales_data(site)
|
|
29
|
-
config = site
|
|
57
|
+
config = site_config_hash(site)
|
|
58
|
+
Configuration.check_defaults(config)
|
|
30
59
|
defaults = config['defaults'] || []
|
|
31
|
-
entry = defaults.find { |d| d.dig('values',
|
|
32
|
-
entry&.dig('values',
|
|
60
|
+
entry = defaults.find { |d| d.is_a?(Hash) && d.dig('values', Configuration::PAGE_DATA_KEY) }
|
|
61
|
+
Configuration::Schema.normalize(entry&.dig('values', Configuration::PAGE_DATA_KEY), source: nil)
|
|
33
62
|
end
|
|
34
63
|
|
|
35
64
|
# The page's `with_locales_data`, merged over the `_config.yml` defaults
|
|
36
|
-
# that match the page.
|
|
37
|
-
#
|
|
38
|
-
# We need this because Jekyll's `page.data` fills in defaults one
|
|
39
|
-
# top-level key at a time: as soon as a page sets any `with_locales_data`
|
|
40
|
-
# key, `page.data` loses all the site defaults for it. This method gives
|
|
41
|
-
# the same result Liquid templates see. Nested hashes merge key by key;
|
|
42
|
-
# lists such as `locales` are replaced, not combined.
|
|
65
|
+
# that match the page. See Configuration.page.
|
|
43
66
|
#
|
|
44
67
|
# @param page [Jekyll::Page] The page. Any other object gets only its own value.
|
|
45
|
-
# @return [Hash] The page's settings
|
|
68
|
+
# @return [Hash] The page's settings (frozen)
|
|
46
69
|
def self.page_locales_data(page)
|
|
47
|
-
|
|
48
|
-
own = {} unless own.is_a?(Hash)
|
|
49
|
-
deep_merge(defaults_locales_data_for(page), own)
|
|
70
|
+
Configuration.page(page)
|
|
50
71
|
end
|
|
51
72
|
|
|
52
|
-
# Like Jekyll::Utils.deep_merge_hashes: nested hashes merge, and any other
|
|
53
|
-
# value from `override` (lists included) wins. Returns a new hash.
|
|
54
|
-
def self.deep_merge(base, override)
|
|
55
|
-
base.merge(override) do |_key, base_value, override_value|
|
|
56
|
-
if base_value.is_a?(Hash) && override_value.is_a?(Hash)
|
|
57
|
-
deep_merge(base_value, override_value)
|
|
58
|
-
else
|
|
59
|
-
override_value
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
private_class_method :deep_merge
|
|
64
|
-
|
|
65
73
|
# The page's data with `with_locales_data` replaced by
|
|
66
74
|
# {.page_locales_data}. Pass this to PageLocalesConfig.new.
|
|
67
75
|
#
|
|
68
76
|
# @param page [Jekyll::Page] The page
|
|
69
77
|
# @return [Hash] Page data with merged `with_locales_data`
|
|
70
78
|
def self.effective_page_data(page)
|
|
71
|
-
page.data.merge(
|
|
79
|
+
page.data.merge(Configuration::PAGE_DATA_KEY => page_locales_data(page))
|
|
72
80
|
end
|
|
73
81
|
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
site = page.site
|
|
80
|
-
return {} unless site.respond_to?(:frontmatter_defaults)
|
|
81
|
-
|
|
82
|
-
value = site.frontmatter_defaults.all(page.relative_path, :pages)['with_locales_data']
|
|
83
|
-
value.is_a?(Hash) ? value : {}
|
|
84
|
-
end
|
|
85
|
-
private_class_method :defaults_locales_data_for
|
|
86
|
-
|
|
87
|
-
# Every locale the site uses: the site-wide list plus any list a page sets
|
|
88
|
-
# in its front matter. Extraction uses it to skip localized output
|
|
89
|
-
# folders, and the compendium steps use it to cover locales that only one
|
|
90
|
-
# page adds.
|
|
82
|
+
# Every locale the site uses: the site-wide list plus each page's own
|
|
83
|
+
# list, read through {.page_locales_data} so a page also brings the
|
|
84
|
+
# locales of the defaults entries that match it. Extraction uses it to
|
|
85
|
+
# skip localized output folders, and the compendium steps use it to
|
|
86
|
+
# cover locales that only one page adds.
|
|
91
87
|
#
|
|
92
88
|
# @param site [Jekyll::Site, Hash] The site, or a hash in specs
|
|
93
89
|
# @return [Array<String>] Unique locale codes
|
|
94
90
|
def self.all_configured_locales(site)
|
|
95
91
|
site_wide_locales = extract_locales_data(site)['locales'] || []
|
|
96
92
|
pages = site.is_a?(Hash) ? site['pages'] : site.pages
|
|
97
|
-
page_locales = pages.flat_map { |p| p
|
|
93
|
+
page_locales = pages.flat_map { |p| page_locales_data(p)['locales'] || [] }
|
|
98
94
|
(site_wide_locales + page_locales).uniq
|
|
99
95
|
end
|
|
100
96
|
|
|
97
|
+
# @param site [Jekyll::Site, Hash] The site, or a hash in specs
|
|
98
|
+
# @return [Hash, nil] The site configuration
|
|
99
|
+
def self.site_config_hash(site)
|
|
100
|
+
site.is_a?(Hash) ? site['config'] : site.config
|
|
101
|
+
end
|
|
102
|
+
|
|
101
103
|
# @param site [Jekyll::Site, Hash] The site, or a hash in specs
|
|
102
104
|
# @return [String] The site source directory
|
|
103
105
|
def self.source(site)
|
|
@@ -27,17 +27,46 @@ module Jekyll
|
|
|
27
27
|
# If not found, checks if the text is part of a block element with
|
|
28
28
|
# a block-level translation and returns that.
|
|
29
29
|
#
|
|
30
|
+
# Text inside an inline element of a content element that has a msgid is
|
|
31
|
+
# translated only through that msgid (see {.covered_by_block?}), so a
|
|
32
|
+
# translation of the same text elsewhere does not translate it alone.
|
|
33
|
+
#
|
|
30
34
|
# @param node [Nokogiri::XML::Node] Text node being translated
|
|
31
35
|
# @param text [String] Normalized text content
|
|
32
36
|
# @param translations [Hash] Translation hash mapping text to translations
|
|
37
|
+
# @param block_texts [Hash, nil] (keyword) Identity-keyed cache for block text
|
|
38
|
+
# extraction results ({}.compare_by_identity), or nil to bypass caching.
|
|
39
|
+
# Pass the per-document cache from HtmlTranslator to avoid redundant
|
|
40
|
+
# BlockTextExtractor calls across multiple text nodes in the same ancestor.
|
|
33
41
|
# @return [String, nil] Translated text if found, nil otherwise
|
|
34
|
-
def self.resolve(node, text, translations)
|
|
42
|
+
def self.resolve(node, text, translations, block_texts: nil)
|
|
35
43
|
return nil unless node && text && translations
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
unless covered_by_block?(node, text, block_texts)
|
|
46
|
+
direct_translation = translations[text]
|
|
47
|
+
return direct_translation if direct_translation
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
try_block_level_translation(node, text, translations, block_texts: block_texts)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Check whether a text node sits inside an inline element of a content
|
|
54
|
+
# element that has a msgid of its own. Extraction gives such text no msgid
|
|
55
|
+
# (HtmlStringExtractor), so it is translated only as part of the block.
|
|
56
|
+
# Text directly inside the content element keeps its direct lookup, for
|
|
57
|
+
# msgstrs that hold the element's markup (a heading with an anchor).
|
|
58
|
+
#
|
|
59
|
+
# @param node [Nokogiri::XML::Node] Text node being translated
|
|
60
|
+
# @param text [String] Normalized text of the node
|
|
61
|
+
# @param block_texts [Hash, nil] Identity-keyed cache, see {.block_text_for}
|
|
62
|
+
# @return [Boolean]
|
|
63
|
+
def self.covered_by_block?(node, text, block_texts = nil)
|
|
64
|
+
ancestor = find_content_element_ancestor(node)
|
|
65
|
+
return false if ancestor.nil? || node.parent == ancestor
|
|
66
|
+
return false if contains_protected_elements?(ancestor)
|
|
39
67
|
|
|
40
|
-
|
|
68
|
+
block_text = block_text_for(ancestor, block_texts)
|
|
69
|
+
!block_text.nil? && block_text != text
|
|
41
70
|
end
|
|
42
71
|
|
|
43
72
|
# Attempt block-level translation for text nodes that are part of larger blocks.
|
|
@@ -52,24 +81,45 @@ module Jekyll
|
|
|
52
81
|
# @param node [Nokogiri::XML::Node] Text node being translated
|
|
53
82
|
# @param text [String] Normalized text of the node
|
|
54
83
|
# @param translations [Hash] Translation hash mapping text to translations
|
|
84
|
+
# @param block_texts [Hash, nil] (keyword) Identity-keyed cache for block text
|
|
85
|
+
# results, or nil to bypass caching. See {.block_text_for}.
|
|
55
86
|
# @return [String, nil] Block-level translation if available, nil otherwise
|
|
56
87
|
#
|
|
57
88
|
# @example
|
|
58
89
|
# # For text "text" in "<p><script>...</script> text</p>"
|
|
59
90
|
# # Returns nil (protected element present, prevents block translation)
|
|
60
91
|
# TranslationResolver.try_block_level_translation(node, "text", translations)
|
|
61
|
-
def self.try_block_level_translation(node, text, translations)
|
|
92
|
+
def self.try_block_level_translation(node, text, translations, block_texts: nil)
|
|
62
93
|
ancestor = find_content_element_ancestor(node)
|
|
63
94
|
return nil unless ancestor
|
|
64
95
|
|
|
65
96
|
return nil if contains_protected_elements?(ancestor)
|
|
66
97
|
|
|
67
|
-
block_text =
|
|
98
|
+
block_text = block_text_for(ancestor, block_texts)
|
|
68
99
|
return nil unless block_text && block_text != text
|
|
69
100
|
|
|
70
101
|
translations[block_text]
|
|
71
102
|
end
|
|
72
103
|
|
|
104
|
+
# Return the extracted block text for a content element, using the supplied
|
|
105
|
+
# cache when available.
|
|
106
|
+
#
|
|
107
|
+
# When a cache is given (an identity-keyed hash), the result is stored on
|
|
108
|
+
# the first call and returned directly on subsequent calls for the same
|
|
109
|
+
# ancestor object — nil results are cached too, so a non-extractable
|
|
110
|
+
# ancestor is not retried. When no cache is given, delegates directly to
|
|
111
|
+
# BlockTextExtractor every time.
|
|
112
|
+
#
|
|
113
|
+
# @param ancestor [Nokogiri::XML::Element] Content element to extract from
|
|
114
|
+
# @param cache [Hash, nil] Identity-keyed cache ({}.compare_by_identity),
|
|
115
|
+
# or nil to bypass caching
|
|
116
|
+
# @return [String, nil] Extracted block text, or nil if not extractable
|
|
117
|
+
def self.block_text_for(ancestor, cache = nil)
|
|
118
|
+
return BlockTextExtractor.extract(ancestor) if cache.nil?
|
|
119
|
+
|
|
120
|
+
cache.fetch(ancestor) { cache[ancestor] = BlockTextExtractor.extract(ancestor) }
|
|
121
|
+
end
|
|
122
|
+
|
|
73
123
|
def self.content_element?(node)
|
|
74
124
|
return false unless node
|
|
75
125
|
return false unless node.element?
|
|
@@ -2,21 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
module Jekyll
|
|
4
4
|
module L10n
|
|
5
|
-
# Builds
|
|
5
|
+
# Builds paths from Jekyll URLs.
|
|
6
6
|
#
|
|
7
|
-
# UrlPathBuilder
|
|
8
|
-
#
|
|
9
|
-
# both regular URLs and PO page paths used for translation files.
|
|
7
|
+
# UrlPathBuilder converts Jekyll URLs to the page paths used for translation
|
|
8
|
+
# files, handling root paths specially and normalizing separators.
|
|
10
9
|
#
|
|
11
10
|
# Key responsibilities:
|
|
12
11
|
# * Normalize URLs (strip leading/trailing slashes)
|
|
13
|
-
# * Convert URLs to file paths
|
|
14
12
|
# * Convert URLs to PO page paths
|
|
15
13
|
# * Calculate relative paths from absolute paths
|
|
16
14
|
#
|
|
17
15
|
# @example
|
|
18
|
-
#
|
|
19
|
-
# # Returns 'docs/
|
|
16
|
+
# po_page_path = UrlPathBuilder.url_to_po_page_path('/docs/guide/')
|
|
17
|
+
# # Returns 'docs/guide/index.html'
|
|
20
18
|
module UrlPathBuilder
|
|
21
19
|
module_function
|
|
22
20
|
|
|
@@ -28,26 +26,6 @@ module Jekyll
|
|
|
28
26
|
url.sub(%r{^/}, '').sub(%r{/$}, '')
|
|
29
27
|
end
|
|
30
28
|
|
|
31
|
-
# Convert a URL to a file system path.
|
|
32
|
-
#
|
|
33
|
-
# Converts Jekyll URL to the path it would be written to on disk.
|
|
34
|
-
# For URLs with file extensions (assets), preserves the extension.
|
|
35
|
-
# For directory-style URLs, uses index.html.
|
|
36
|
-
#
|
|
37
|
-
# @param url [String] Jekyll URL (e.g., '/docs/page.html' or '/assets/style.css')
|
|
38
|
-
# @return [String] File path (e.g., 'docs/page.html/index.html' or 'assets/style.css')
|
|
39
|
-
def url_to_file_path(url)
|
|
40
|
-
normalized = normalize_url(url)
|
|
41
|
-
|
|
42
|
-
# Preserve file extensions for assets (css, js, etc.)
|
|
43
|
-
# Only add /index.html for directory-style URLs
|
|
44
|
-
if /\.[a-zA-Z0-9]+$/.match?(normalized)
|
|
45
|
-
normalized
|
|
46
|
-
else
|
|
47
|
-
"#{normalized}/index.html"
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
29
|
# Convert a URL to a PO page path for translation files.
|
|
52
30
|
#
|
|
53
31
|
# Handles root path specially (converts to 'index'). Used when saving
|
|
@@ -11,7 +11,7 @@ module Jekyll
|
|
|
11
11
|
#
|
|
12
12
|
# UrlTransformer modifies href attributes in links to prefix them with
|
|
13
13
|
# the target locale in BCP 47 hyphenated form (e.g., /docs/page.html becomes
|
|
14
|
-
# /es-
|
|
14
|
+
# /es-es/docs/page.html for a canonical "es_ES" locale).
|
|
15
15
|
# It preserves external links, anchors, mailto, tel links, and links
|
|
16
16
|
# already containing locale prefixes. Skips English locale (default language).
|
|
17
17
|
#
|
|
@@ -26,7 +26,7 @@ module Jekyll
|
|
|
26
26
|
# @example
|
|
27
27
|
# html = '<a href="/docs/page.html">Link</a>'
|
|
28
28
|
# transformed = UrlTransformer.transform(html, 'es_ES', '/baseurl')
|
|
29
|
-
# # Returns '<a href="/baseurl/es-
|
|
29
|
+
# # Returns '<a href="/baseurl/es-es/docs/page.html">Link</a>'
|
|
30
30
|
class UrlTransformer
|
|
31
31
|
class << self
|
|
32
32
|
# Transform all relative URLs in HTML to include locale prefix.
|
|
@@ -46,17 +46,11 @@ module Jekyll
|
|
|
46
46
|
|
|
47
47
|
return html if should_skip_transform?(locale)
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
# DOCTYPE, html tag, and document structure. Auto-inserted meta tags are
|
|
51
|
-
# removed via regex post-processing (same approach as HtmlTranslator).
|
|
52
|
-
# See: spec/regression/nokogiri_meta_tag_spec.rb for regression tests
|
|
53
|
-
doc = Nokogiri::HTML(html)
|
|
49
|
+
doc = HtmlParser.parse_document(html)
|
|
54
50
|
|
|
55
51
|
transform_document(doc, locale, baseurl)
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
HtmlParser.remove_meta_charset(result)
|
|
53
|
+
doc.to_html
|
|
60
54
|
end
|
|
61
55
|
|
|
62
56
|
# Transform URLs in a parsed HTML document.
|
|
@@ -64,7 +58,7 @@ module Jekyll
|
|
|
64
58
|
# Modifies href attributes of links in the parsed document in place.
|
|
65
59
|
# Useful when document is already parsed to avoid re-parsing.
|
|
66
60
|
#
|
|
67
|
-
# @param doc [Nokogiri::
|
|
61
|
+
# @param doc [Nokogiri::HTML5::Document] Parsed HTML document
|
|
68
62
|
# @param locale [String] Target locale code (canonical or BCP 47 form)
|
|
69
63
|
# @param baseurl [String] Base URL for site
|
|
70
64
|
# @return [void]
|
data/lib/jekyll-l10n/version.rb
CHANGED
|
@@ -6,6 +6,6 @@ module Jekyll
|
|
|
6
6
|
# Regenerated alongside the gemspec on every `make jekyll-l10n.gemspec`
|
|
7
7
|
# run (locally or in CI), so it always matches spec.version in the built
|
|
8
8
|
# gem. Any hand edit is overwritten on the next run.
|
|
9
|
-
VERSION = '
|
|
9
|
+
VERSION = '3.0.0'
|
|
10
10
|
end
|
|
11
11
|
end
|
data/lib/jekyll-l10n.rb
CHANGED
|
@@ -41,12 +41,13 @@ require 'gettext/po'
|
|
|
41
41
|
#
|
|
42
42
|
# ## Settings
|
|
43
43
|
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
44
|
+
# Per-page settings live in `with_locales_data`, in `_config.yml` defaults
|
|
45
|
+
# and page front matter. A page's value is merged over the defaults that
|
|
46
|
+
# match it (SiteConfigAccessor.page_locales_data). Settings that apply to the
|
|
47
|
+
# whole build, such as `incremental`, `update_compendium` and the
|
|
48
|
+
# LibreTranslate settings, live under the top-level `jekyll_l10n` key
|
|
49
|
+
# (SiteConfigAccessor.site_settings). Configuration::Schema gives each
|
|
50
|
+
# setting's scope; a setting in the wrong place is ignored with a warning.
|
|
50
51
|
#
|
|
51
52
|
# ```yaml
|
|
52
53
|
# defaults:
|
|
@@ -59,6 +60,7 @@ require 'gettext/po'
|
|
|
59
60
|
#
|
|
60
61
|
# jekyll_l10n:
|
|
61
62
|
# incremental: true
|
|
63
|
+
# update_compendium: true
|
|
62
64
|
# ```
|
|
63
65
|
#
|
|
64
66
|
# ## Files
|
|
@@ -79,6 +81,7 @@ require 'gettext/po'
|
|
|
79
81
|
require_relative 'jekyll-l10n/version'
|
|
80
82
|
require_relative 'jekyll-l10n/instrumentation'
|
|
81
83
|
require_relative 'jekyll-l10n/constants'
|
|
84
|
+
require_relative 'jekyll-l10n/configuration'
|
|
82
85
|
require_relative 'jekyll-l10n/errors'
|
|
83
86
|
require_relative 'jekyll-l10n/po_file/reader'
|
|
84
87
|
require_relative 'jekyll-l10n/po_file/fuzzy_matcher'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-l10n
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alain Reguera Delgado
|
|
@@ -75,7 +75,7 @@ dependencies:
|
|
|
75
75
|
requirements:
|
|
76
76
|
- - ">="
|
|
77
77
|
- !ruby/object:Gem::Version
|
|
78
|
-
version: '1.
|
|
78
|
+
version: '1.13'
|
|
79
79
|
- - "<"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
81
|
version: '2.0'
|
|
@@ -85,7 +85,7 @@ dependencies:
|
|
|
85
85
|
requirements:
|
|
86
86
|
- - ">="
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '1.
|
|
88
|
+
version: '1.13'
|
|
89
89
|
- - "<"
|
|
90
90
|
- !ruby/object:Gem::Version
|
|
91
91
|
version: '2.0'
|
|
@@ -253,11 +253,14 @@ files:
|
|
|
253
253
|
- LICENSE
|
|
254
254
|
- README.md
|
|
255
255
|
- lib/jekyll-l10n.rb
|
|
256
|
+
- lib/jekyll-l10n/configuration.rb
|
|
257
|
+
- lib/jekyll-l10n/configuration/schema.rb
|
|
256
258
|
- lib/jekyll-l10n/constants.rb
|
|
257
259
|
- lib/jekyll-l10n/errors.rb
|
|
258
260
|
- lib/jekyll-l10n/extraction/compendium_merger.rb
|
|
259
261
|
- lib/jekyll-l10n/extraction/compendium_translator.rb
|
|
260
262
|
- lib/jekyll-l10n/extraction/config_loader.rb
|
|
263
|
+
- lib/jekyll-l10n/extraction/coverage_report.rb
|
|
261
264
|
- lib/jekyll-l10n/extraction/dom_attribute_extractor.rb
|
|
262
265
|
- lib/jekyll-l10n/extraction/dom_text_extractor.rb
|
|
263
266
|
- lib/jekyll-l10n/extraction/extractor.rb
|
|
@@ -271,6 +274,7 @@ files:
|
|
|
271
274
|
- lib/jekyll-l10n/jekyll/post_write_processor.rb
|
|
272
275
|
- lib/jekyll-l10n/jekyll/regeneration_checker.rb
|
|
273
276
|
- lib/jekyll-l10n/jekyll/url_filter.rb
|
|
277
|
+
- lib/jekyll-l10n/po_file/entry_parser.rb
|
|
274
278
|
- lib/jekyll-l10n/po_file/fuzzy_matcher.rb
|
|
275
279
|
- lib/jekyll-l10n/po_file/loader.rb
|
|
276
280
|
- lib/jekyll-l10n/po_file/manager.rb
|
|
@@ -280,9 +284,13 @@ files:
|
|
|
280
284
|
- lib/jekyll-l10n/po_file/writer.rb
|
|
281
285
|
- lib/jekyll-l10n/translation/block_text_extractor.rb
|
|
282
286
|
- lib/jekyll-l10n/translation/html_translator.rb
|
|
287
|
+
- lib/jekyll-l10n/translation/libre_translate_languages.rb
|
|
283
288
|
- lib/jekyll-l10n/translation/libre_translator.rb
|
|
284
289
|
- lib/jekyll-l10n/translation/page_translation_loader.rb
|
|
290
|
+
- lib/jekyll-l10n/translation/request_slots.rb
|
|
291
|
+
- lib/jekyll-l10n/translation/translation_progress.rb
|
|
285
292
|
- lib/jekyll-l10n/translation/translator.rb
|
|
293
|
+
- lib/jekyll-l10n/utils/baseurl_normalizer.rb
|
|
286
294
|
- lib/jekyll-l10n/utils/debug_logger.rb
|
|
287
295
|
- lib/jekyll-l10n/utils/error_handler.rb
|
|
288
296
|
- lib/jekyll-l10n/utils/external_link_icon_preserver.rb
|
|
@@ -293,6 +301,7 @@ files:
|
|
|
293
301
|
- lib/jekyll-l10n/utils/locale_name_resolver.rb
|
|
294
302
|
- lib/jekyll-l10n/utils/locale_url_formatter.rb
|
|
295
303
|
- lib/jekyll-l10n/utils/logger_formatter.rb
|
|
304
|
+
- lib/jekyll-l10n/utils/msgstr_validator.rb
|
|
296
305
|
- lib/jekyll-l10n/utils/page_locales_config.rb
|
|
297
306
|
- lib/jekyll-l10n/utils/po_entry_converter.rb
|
|
298
307
|
- lib/jekyll-l10n/utils/site_config_accessor.rb
|