klenod-build 0.0.31 → 0.0.33

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 138e1ff7f2bde9f495d98443509718767e179b5e0c7c2a95e92edcd40e3e028a
4
- data.tar.gz: 927ea94c5136765c21b25e7b95fe9fb59ecbf3e2b9d697a35a0f457297186c51
3
+ metadata.gz: c8d75c7c0abc58318ff254e605f618ba14399b9df7fab791e2de204c5546774f
4
+ data.tar.gz: 86117e7ef465f1a39c59eb25d937eaad3ce0d25096f5a569c396b298db9beccf
5
5
  SHA512:
6
- metadata.gz: 9c0d70321556eef5ed84c1c96da47ce50dc3a0ed8c940b268cdfa58736a47380f511104cd8385398dff4b4da4757582f447058c1b888a4b04e4edfc550668157
7
- data.tar.gz: a0ad06933426e2a03814ed459e52c9d0506825f6ba71e0fc8bf8a6b4e39c681df37f8317d25e812cb84f035b4617bb4dde39001bfc7c67be1c5208050eaef103
6
+ metadata.gz: a4213e39362700cb1a30e741a48f5e26220b7e00ad77f4cd4f52fddb0ed13ccf5e7bf54f9661da232d3da47f831004169e9217a5e2fe4d5bc8bf654198fde4cb
7
+ data.tar.gz: 8c1377e40417a5bb09eccca2a167c14883054debd8a9cc010726e748fccc77e9e962243bdd36bb30137b219f487a522404a7d2dc1130630d053326734c13875c
@@ -6,6 +6,7 @@ require "toml-rb"
6
6
  require "yaml"
7
7
 
8
8
  require_relative "../plugin"
9
+ require_relative "../ruby_literal"
9
10
  require_relative "../source_error"
10
11
  require_relative "../transform_result"
11
12
 
@@ -64,42 +65,9 @@ module Klenod
64
65
 
65
66
  def module_source(data)
66
67
  <<~RUBY
67
- Default = #{ruby_literal(data)}
68
+ Default = #{RubyLiteral.frozen(data)}
68
69
  RUBY
69
70
  end
70
-
71
- # `inspect` is not Ruby source for every parsed value: dates, times,
72
- # and non-finite floats need constructor calls instead.
73
- def ruby_literal(value)
74
- case value
75
- when Hash
76
- entries = value.map { |key, entry| "#{ruby_literal(key)} => #{ruby_literal(entry)}" }
77
- "{#{entries.join(", ")}}"
78
- when Array
79
- "[#{value.map { ruby_literal(it) }.join(", ")}]"
80
- when Float
81
- float_literal(value)
82
- when Time
83
- zone = value.utc? ? "UTC" : value.utc_offset
84
- "::Time.at(#{value.to_i}, #{value.nsec}, :nsec, in: #{zone.inspect})"
85
- when Date
86
- "::Date.new(#{value.year}, #{value.month}, #{value.day})"
87
- when nil, true, false, String, Symbol, Integer
88
- value.inspect
89
- else
90
- raise TypeError, "Cannot write #{value.class} as data module source"
91
- end
92
- end
93
-
94
- def float_literal(value)
95
- if value.nan?
96
- "::Float::NAN"
97
- elsif value.infinite?
98
- value.positive? ? "::Float::INFINITY" : "-::Float::INFINITY"
99
- else
100
- value.inspect
101
- end
102
- end
103
71
  end
104
72
  end
105
73
 
@@ -3167,6 +3167,15 @@
3167
3167
  "unitsPerEm": 1000,
3168
3168
  "xWidthAvg": 589
3169
3169
  },
3170
+ "Clarity City": {
3171
+ "familyName": "Clarity City",
3172
+ "category": "sans-serif",
3173
+ "ascent": 994,
3174
+ "descent": -306,
3175
+ "lineGap": 0,
3176
+ "unitsPerEm": 1000,
3177
+ "xWidthAvg": 479
3178
+ },
3170
3179
  "Clicker Script": {
3171
3180
  "familyName": "Clicker Script",
3172
3181
  "category": "handwriting",
@@ -6461,6 +6470,15 @@
6461
6470
  "unitsPerEm": 1000,
6462
6471
  "xWidthAvg": 288
6463
6472
  },
6473
+ "Isometra": {
6474
+ "familyName": "Isometra",
6475
+ "category": "serif",
6476
+ "ascent": 1050,
6477
+ "descent": -250,
6478
+ "lineGap": 0,
6479
+ "unitsPerEm": 1000,
6480
+ "xWidthAvg": 683
6481
+ },
6464
6482
  "Istok Web": {
6465
6483
  "familyName": "Istok Web",
6466
6484
  "category": "sans-serif",
@@ -7307,6 +7325,15 @@
7307
7325
  "unitsPerEm": 1000,
7308
7326
  "xWidthAvg": 412
7309
7327
  },
7328
+ "Kripa": {
7329
+ "familyName": "Kripa",
7330
+ "category": "sans-serif",
7331
+ "ascent": 1080,
7332
+ "descent": -390,
7333
+ "lineGap": 0,
7334
+ "unitsPerEm": 1000,
7335
+ "xWidthAvg": 481
7336
+ },
7310
7337
  "Kristi": {
7311
7338
  "familyName": "Kristi",
7312
7339
  "category": "handwriting",
@@ -7802,6 +7829,15 @@
7802
7829
  "unitsPerEm": 1000,
7803
7830
  "xWidthAvg": 450
7804
7831
  },
7832
+ "Libre Caslon Condensed": {
7833
+ "familyName": "Libre Caslon Condensed",
7834
+ "category": "serif",
7835
+ "ascent": 2061,
7836
+ "descent": -539,
7837
+ "lineGap": 0,
7838
+ "unitsPerEm": 2000,
7839
+ "xWidthAvg": 767
7840
+ },
7805
7841
  "Libre Caslon Display": {
7806
7842
  "familyName": "Libre Caslon Display",
7807
7843
  "category": "serif",
@@ -5,7 +5,7 @@ Update them to the latest Capsize revision from the Klenod repository root:
5
5
  bundle exec rake google_fonts:metrics:update
6
6
 
7
7
  Project: https://github.com/seek-oss/capsize
8
- Commit: 8df97f098adc19d8a6d33df301757d7e9670bae6
8
+ Commit: 51946f815deeef7d9d97e0149659abdb50348099
9
9
  Source: packages/metrics/src/entireMetricsCollection.json
10
10
 
11
11
  MIT License
@@ -100,7 +100,9 @@ module Klenod
100
100
  end
101
101
 
102
102
  if (old_attributes = attribute_hashes[:old])
103
- literal.concat(literal_class_names_from_old_attributes(old_attributes))
103
+ folded_shorthand, folded_literal = folded_class_names_from_old_attributes(old_attributes)
104
+ shorthand.concat(folded_shorthand)
105
+ literal.concat(folded_literal)
104
106
  end
105
107
 
106
108
  {shorthand: shorthand, literal: literal}
@@ -222,20 +224,26 @@ module Klenod
222
224
  attribute_sequence?(rest)
223
225
  end
224
226
 
225
- def literal_class_names_from_old_attributes(source)
226
- parsed = ::Haml::AttributeParser.parse(source)
227
- return [] unless parsed&.key?("class")
227
+ # Haml folds an old-style hash into the tag's static attributes only
228
+ # when `parse_static_hash` accepts it (hashrocket pairs of literals),
229
+ # and then drops the hash source. Any other hash, such as
230
+ # `{class: "plain"}`, stays a dynamic attribute that the transformer
231
+ # compiles itself, so only folded classes are recorded here. String
232
+ # classes stay literal and symbol classes stay scoped, matching how
233
+ # dynamic class values render.
234
+ def folded_class_names_from_old_attributes(source)
235
+ return [[], []] unless parse_static_hash(source)
228
236
 
229
- value = static_string_literal_value(parsed.fetch("class"))
230
- value ? value.split : []
231
- end
237
+ parsed = ::Haml::AttributeParser.parse(source)
238
+ return [[], []] unless parsed&.key?("class")
232
239
 
233
- def static_string_literal_value(source)
234
- case Ripper.sexp(source)
240
+ case Ripper.sexp(parsed.fetch("class"))
235
241
  in [:program, [[:string_literal, [:string_content, [:@tstring_content, String => value, _location]]]]]
236
- value
242
+ [[], value.split]
243
+ in [:program, [[:symbol_literal, [:symbol, [_type, String => name, _location]]]]]
244
+ [[name], []]
237
245
  else
238
- nil
246
+ [[], []]
239
247
  end
240
248
  end
241
249
  end
@@ -203,10 +203,6 @@ module Klenod
203
203
  Fragment.new(literal_source(value))
204
204
  end
205
205
 
206
- def frozen_literal(value)
207
- Fragment.new(frozen_literal_source(value))
208
- end
209
-
210
206
  def import_call(dependency_id)
211
207
  Fragment.new("__klenod_import__(#{literal_source(dependency_id)})")
212
208
  end
@@ -443,13 +439,16 @@ module Klenod
443
439
  # Whether the script opens a literal block for its Haml children.
444
440
  # Calls, `super`, and zsuper can take one; lambdas cannot.
445
441
  def block_script?(source)
446
- node = parse_expression(fix_syntax_by_adding_missing_pairs(source), context: :block_script)
447
-
448
- node.respond_to?(:block) && node.block.is_a?(Prism::BlockNode)
442
+ !script_block_node(source).nil?
449
443
  end
450
444
 
451
445
  private
452
446
 
447
+ def script_block_node(source)
448
+ node = parse_expression(fix_syntax_by_adding_missing_pairs(source), context: :block_script)
449
+ node.block if node.respond_to?(:block) && node.block.is_a?(Prism::BlockNode)
450
+ end
451
+
453
452
  def rewrite_ruby_source(source, line_no)
454
453
  source = rewrite_line_constant(source, line_no)
455
454
  rewrite_variables(source)
@@ -580,7 +579,9 @@ module Klenod
580
579
  def block_source(source, body)
581
580
  body_source = to_source(body)
582
581
 
583
- if source.include?("{") && !source.end_with?(" do")
582
+ # Hash arguments, strings, and parameter defaults can contain
583
+ # braces without opening the block that owns the Haml children.
584
+ if script_block_node(source)&.opening_loc&.slice == "{"
584
585
  "#{source} #{body_source} }"
585
586
  else
586
587
  [source, indent(body_source, 2), "end"].join("\n")
@@ -630,17 +631,6 @@ module Klenod
630
631
  "#{symbol_source(name)} =>"
631
632
  end
632
633
 
633
- def frozen_literal_source(value)
634
- case value
635
- when Hash
636
- "{#{value.map { |key, child| "#{literal_source(key)} => #{frozen_literal_source(child)}" }.join(", ")}}.freeze"
637
- when Array
638
- "[#{value.map { |child| frozen_literal_source(child) }.join(", ")}].freeze"
639
- else
640
- literal_source(value)
641
- end
642
- end
643
-
644
634
  def literal_source(value)
645
635
  case value
646
636
  when String
@@ -6,6 +6,7 @@ require_relative "../plugin"
6
6
  require_relative "../dependency"
7
7
  require_relative "../module_id"
8
8
  require_relative "../ruby_import_rewriter"
9
+ require_relative "../ruby_literal"
9
10
  require_relative "../transform_result"
10
11
  require_relative "../watched_pattern"
11
12
  require_relative "intl_plugin"
@@ -176,7 +177,7 @@ module Klenod
176
177
  styles_source = styles_source_for(builder, style_dependencies, class_names_runtime_dependency: class_names_runtime_dependency)
177
178
  haml_helper_dependency = haml_helper_dependency(module_id)
178
179
  dependencies << haml_helper_dependency
179
- translations_source = builder.frozen_literal(translations_for(context, module_id)).source
180
+ translations_source = RubyLiteral.frozen(translations_for(context, module_id))
180
181
  component_class_name = component_class_name(module_id)
181
182
  import_rewriter =
182
183
  lambda do |source, source_line_offset: 0, source_column_offset: 0|
@@ -4,6 +4,7 @@ require_relative "../dependency"
4
4
  require_relative "../errors"
5
5
  require_relative "../module_id"
6
6
  require_relative "../plugin"
7
+ require_relative "../ruby_literal"
7
8
  require "klenod/runtime/source_map"
8
9
  require_relative "../transform_result"
9
10
  require_relative "../watched_pattern"
@@ -376,11 +377,17 @@ module Klenod
376
377
  def generate_router_source(manifest)
377
378
  imports = import_refs(manifest)
378
379
  <<~RUBY
380
+ require "uri"
381
+
379
382
  Segment = Data.define(:name, :kind, :param_name, :path_part)
380
383
  Param = Data.define(:name, :kind)
381
384
  #{import_definitions(imports)}
382
385
 
383
386
  module Default
387
+ # Raised for a request path with a malformed percent-encoding
388
+ # or an escape that does not decode to UTF-8.
389
+ MalformedPathError = Class.new(StandardError)
390
+
384
391
  Route = Data.define(:path, :page_module_id, :handler_module_id, :segments, :match_parts, :layout_module_ids, :slot_layout_module_id, :page_ref, :handler_ref, :layout_refs) do
385
392
  def params
386
393
  segments
@@ -528,7 +535,7 @@ module Klenod
528
535
  end
529
536
 
530
537
  def self.match(path)
531
- parts = normalize_path(path)
538
+ parts = request_parts(path)
532
539
  route = main_route_for(parts)
533
540
  return nil unless route
534
541
 
@@ -553,6 +560,22 @@ module Klenod
553
560
  normalized.split("/").reject(&:empty?)
554
561
  end
555
562
 
563
+ # Request path segments, each percent-decoded after splitting so
564
+ # an encoded slash stays inside its segment. `.` and `..` are
565
+ # kept as ordinary segments; nothing is normalized.
566
+ def self.request_parts(path)
567
+ normalize_path(path).map do |part|
568
+ decoded = begin
569
+ URI.decode_uri_component(part)
570
+ rescue ArgumentError
571
+ nil
572
+ end
573
+ raise MalformedPathError, "Malformed percent-encoding in path segment \#{part.inspect}" unless decoded&.valid_encoding?
574
+
575
+ decoded
576
+ end
577
+ end
578
+
556
579
  def self.build_tree(routes)
557
580
  root = RouteNode.new(segment: nil, path: "/")
558
581
 
@@ -632,7 +655,7 @@ module Klenod
632
655
  end
633
656
 
634
657
  def self.special_match(views, path)
635
- parts = normalize_path(path)
658
+ parts = request_parts(path)
636
659
  view = special_view_for(views, parts)
637
660
  return nil unless view
638
661
 
@@ -742,7 +765,7 @@ module Klenod
742
765
  " #{route.handler_module_id&.path.inspect},",
743
766
  " #{segments_source(route.segments)},",
744
767
  " #{match_parts_source(route.segments)},",
745
- " #{route.layout_module_ids.map(&:path).inspect},",
768
+ " #{RubyLiteral.frozen(route.layout_module_ids.map(&:path))},",
746
769
  " #{route.slot_layout_module_id&.path.inspect},",
747
770
  " #{route.page_module_id ? imports.fetch(route.page_module_id.to_s) : "nil"},",
748
771
  " #{route.handler_module_id ? imports.fetch(route.handler_module_id.to_s) : "nil"},",
@@ -763,7 +786,7 @@ module Klenod
763
786
  " #{view.view_module_id.path.inspect},",
764
787
  " #{segments_source(view.segments)},",
765
788
  " #{match_parts_source(view.segments)},",
766
- " #{view.layout_module_ids.map(&:path).inspect},",
789
+ " #{RubyLiteral.frozen(view.layout_module_ids.map(&:path))},",
767
790
  " #{imports.fetch(view.view_module_id.to_s)},",
768
791
  " #{layouts_source(layouts)}",
769
792
  " )"
@@ -841,11 +864,11 @@ module Klenod
841
864
  end
842
865
 
843
866
  def segments_source(segments)
844
- "[#{segments.map { |segment| segment_source(segment) }.join(", ")}]"
867
+ "[#{segments.map { |segment| segment_source(segment) }.join(", ")}].freeze"
845
868
  end
846
869
 
847
870
  def match_parts_source(segments)
848
- route_match_parts_for(segments).inspect
871
+ RubyLiteral.frozen(route_match_parts_for(segments))
849
872
  end
850
873
 
851
874
  def segment_source(segment)
@@ -883,7 +906,7 @@ module Klenod
883
906
  end
884
907
 
885
908
  def layouts_source(layouts)
886
- "[#{layouts.join(", ")}]"
909
+ "[#{layouts.join(", ")}].freeze"
887
910
  end
888
911
 
889
912
  def route_handler_module_id?(module_id, context)
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ module Klenod
6
+ module Build
7
+ # Writes parsed data as Ruby source for generated modules. Every hash,
8
+ # array, time, and date is frozen; string literals are frozen because
9
+ # modules are evaluated with `frozen_string_literal: true`.
10
+ module RubyLiteral
11
+ module_function
12
+
13
+ # `inspect` is not Ruby source for every parsed value: dates, times,
14
+ # and non-finite floats need constructor calls instead.
15
+ def frozen(value)
16
+ case value
17
+ when Hash
18
+ entries = value.map { |key, entry| "#{frozen(key)} => #{frozen(entry)}" }
19
+ "{#{entries.join(", ")}}.freeze"
20
+ when Array
21
+ "[#{value.map { frozen(it) }.join(", ")}].freeze"
22
+ when Float
23
+ float(value)
24
+ when Time
25
+ zone = value.utc? ? "UTC" : value.utc_offset
26
+ "::Time.at(#{value.to_i}, #{value.nsec}, :nsec, in: #{zone.inspect}).freeze"
27
+ when Date
28
+ "::Date.new(#{value.year}, #{value.month}, #{value.day}).freeze"
29
+ when nil, true, false, String, Symbol, Integer
30
+ value.inspect
31
+ else
32
+ raise TypeError, "Cannot write #{value.class} as Ruby literal source"
33
+ end
34
+ end
35
+
36
+ def float(value)
37
+ if value.nan?
38
+ "::Float::NAN"
39
+ elsif value.infinite?
40
+ value.positive? ? "::Float::INFINITY" : "-::Float::INFINITY"
41
+ else
42
+ value.inspect
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Klenod
4
4
  module Build
5
- VERSION = "0.0.31"
5
+ VERSION = "0.0.33"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: klenod-build
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.31
4
+ version: 0.0.33
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrés Alin
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.0.31
18
+ version: 0.0.33
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.0.31
25
+ version: 0.0.33
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: async
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -299,6 +299,7 @@ files:
299
299
  - lib/klenod/build/resolution_error_formatter.rb
300
300
  - lib/klenod/build/resolver.rb
301
301
  - lib/klenod/build/ruby_import_rewriter.rb
302
+ - lib/klenod/build/ruby_literal.rb
302
303
  - lib/klenod/build/source_error.rb
303
304
  - lib/klenod/build/source_excerpt.rb
304
305
  - lib/klenod/build/source_map.rb