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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +44 -0
  3. data/lib/jekyll-l10n/configuration/schema.rb +308 -0
  4. data/lib/jekyll-l10n/configuration.rb +165 -0
  5. data/lib/jekyll-l10n/constants.rb +45 -10
  6. data/lib/jekyll-l10n/errors.rb +7 -0
  7. data/lib/jekyll-l10n/extraction/compendium_merger.rb +9 -11
  8. data/lib/jekyll-l10n/extraction/compendium_translator.rb +27 -11
  9. data/lib/jekyll-l10n/extraction/config_loader.rb +4 -4
  10. data/lib/jekyll-l10n/extraction/coverage_report.rb +129 -0
  11. data/lib/jekyll-l10n/extraction/dom_text_extractor.rb +2 -31
  12. data/lib/jekyll-l10n/extraction/extractor.rb +48 -28
  13. data/lib/jekyll-l10n/extraction/html_string_extractor.rb +24 -10
  14. data/lib/jekyll-l10n/extraction/logger.rb +6 -5
  15. data/lib/jekyll-l10n/extraction/result_saver.rb +5 -10
  16. data/lib/jekyll-l10n/instrumentation.rb +172 -139
  17. data/lib/jekyll-l10n/jekyll/generator.rb +10 -22
  18. data/lib/jekyll-l10n/jekyll/localized_page.rb +27 -49
  19. data/lib/jekyll-l10n/jekyll/post_write_html_reprocessor.rb +42 -25
  20. data/lib/jekyll-l10n/jekyll/post_write_processor.rb +2 -1
  21. data/lib/jekyll-l10n/jekyll/regeneration_checker.rb +16 -10
  22. data/lib/jekyll-l10n/jekyll/url_filter.rb +8 -7
  23. data/lib/jekyll-l10n/po_file/entry_parser.rb +155 -0
  24. data/lib/jekyll-l10n/po_file/fuzzy_matcher.rb +67 -53
  25. data/lib/jekyll-l10n/po_file/loader.rb +20 -11
  26. data/lib/jekyll-l10n/po_file/manager.rb +32 -17
  27. data/lib/jekyll-l10n/po_file/merger.rb +2 -1
  28. data/lib/jekyll-l10n/po_file/path_builder.rb +11 -1
  29. data/lib/jekyll-l10n/po_file/reader.rb +40 -508
  30. data/lib/jekyll-l10n/po_file/writer.rb +31 -16
  31. data/lib/jekyll-l10n/translation/block_text_extractor.rb +3 -7
  32. data/lib/jekyll-l10n/translation/html_translator.rb +136 -157
  33. data/lib/jekyll-l10n/translation/libre_translate_languages.rb +73 -0
  34. data/lib/jekyll-l10n/translation/libre_translator.rb +134 -78
  35. data/lib/jekyll-l10n/translation/request_slots.rb +69 -0
  36. data/lib/jekyll-l10n/translation/translation_progress.rb +77 -0
  37. data/lib/jekyll-l10n/translation/translator.rb +20 -17
  38. data/lib/jekyll-l10n/utils/baseurl_normalizer.rb +108 -0
  39. data/lib/jekyll-l10n/utils/debug_logger.rb +4 -51
  40. data/lib/jekyll-l10n/utils/error_handler.rb +9 -24
  41. data/lib/jekyll-l10n/utils/external_link_icon_preserver.rb +5 -62
  42. data/lib/jekyll-l10n/utils/html_parser.rb +24 -31
  43. data/lib/jekyll-l10n/utils/html_text_utils.rb +146 -91
  44. data/lib/jekyll-l10n/utils/logger_formatter.rb +6 -4
  45. data/lib/jekyll-l10n/utils/msgstr_validator.rb +74 -0
  46. data/lib/jekyll-l10n/utils/page_locales_config.rb +126 -107
  47. data/lib/jekyll-l10n/utils/po_entry_converter.rb +0 -43
  48. data/lib/jekyll-l10n/utils/site_config_accessor.rb +56 -54
  49. data/lib/jekyll-l10n/utils/translation_resolver.rb +56 -6
  50. data/lib/jekyll-l10n/utils/url_path_builder.rb +5 -27
  51. data/lib/jekyll-l10n/utils/url_transformer.rb +5 -11
  52. data/lib/jekyll-l10n/version.rb +1 -1
  53. data/lib/jekyll-l10n.rb +9 -6
  54. 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 `with_locales_data` settings from the site and its pages.
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: {.extract_locales_data} returns the first `defaults`
12
- # entry that has `with_locales_data`, whatever its scope.
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.extract_locales_data(site)['update_compendium']
23
+ # SiteConfigAccessor.site_config(site).update_compendium? # => true
20
24
  class SiteConfigAccessor
21
- # Site-wide `with_locales_data`: the value from the first `defaults` entry
22
- # that has one, whatever pages it matches. Used for settings that apply
23
- # to the whole build, such as `update_compendium` and
24
- # `logging.show_statistics`.
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.is_a?(Hash) ? site['config'] : site.config
57
+ config = site_config_hash(site)
58
+ Configuration.check_defaults(config)
30
59
  defaults = config['defaults'] || []
31
- entry = defaults.find { |d| d.dig('values', 'with_locales_data') }
32
- entry&.dig('values', 'with_locales_data') || {}
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
- own = page.data['with_locales_data']
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('with_locales_data' => page_locales_data(page))
79
+ page.data.merge(Configuration::PAGE_DATA_KEY => page_locales_data(page))
72
80
  end
73
81
 
74
- # `with_locales_data` from the defaults that match the page, or {} when
75
- # the page has no site to look them up in (as in some specs).
76
- def self.defaults_locales_data_for(page)
77
- return {} unless page.is_a?(Jekyll::Page)
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.data.dig('with_locales_data', 'locales') || [] }
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
- direct_translation = translations[text]
38
- return direct_translation if direct_translation
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
- try_block_level_translation(node, text, translations)
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 = BlockTextExtractor.extract(ancestor)
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 file paths from URLs and vice versa.
5
+ # Builds paths from Jekyll URLs.
6
6
  #
7
- # UrlPathBuilder provides conversions between Jekyll URLs and file system
8
- # paths, handling root paths specially and normalizing separators. It supports
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
- # file_path = UrlPathBuilder.url_to_file_path('/docs/page.html')
19
- # # Returns 'docs/page.html/index.html'
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-ES/docs/page.html for a canonical "es_ES" locale).
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-ES/docs/page.html">Link</a>'
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
- # Use Nokogiri::HTML to properly parse full HTML documents while preserving
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
- result = doc.to_html
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::HTML::Document] Parsed HTML document
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]
@@ -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 = '2.0.0'
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
- # Localization settings live in `with_locales_data`, in `_config.yml`
45
- # defaults and page front matter. A page's value is merged over the defaults
46
- # that match it (SiteConfigAccessor.page_locales_data). A few settings apply
47
- # to the whole build and come from the first defaults entry instead
48
- # (SiteConfigAccessor.extract_locales_data). The only build-level setting,
49
- # `incremental`, lives under the top-level `jekyll_l10n` key.
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: 2.0.0
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.12'
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.12'
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