klenod-build 0.0.1

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +29 -0
  3. data/lib/klenod/build/asset.rb +235 -0
  4. data/lib/klenod/build/asset_compression.rb +58 -0
  5. data/lib/klenod/build/asset_generation_queue.rb +50 -0
  6. data/lib/klenod/build/cli/application.rb +108 -0
  7. data/lib/klenod/build/cli.rb +3 -0
  8. data/lib/klenod/build/config.rb +142 -0
  9. data/lib/klenod/build/context.rb +370 -0
  10. data/lib/klenod/build/dependency.rb +21 -0
  11. data/lib/klenod/build/errors.rb +175 -0
  12. data/lib/klenod/build/filesystem_resolver.rb +147 -0
  13. data/lib/klenod/build/graph/invalidator.rb +246 -0
  14. data/lib/klenod/build/graph.rb +864 -0
  15. data/lib/klenod/build/graphviz.rb +282 -0
  16. data/lib/klenod/build/hashing.rb +21 -0
  17. data/lib/klenod/build/invalidation_result.rb +55 -0
  18. data/lib/klenod/build/load_result.rb +7 -0
  19. data/lib/klenod/build/loaded_module.rb +38 -0
  20. data/lib/klenod/build/module_id.rb +100 -0
  21. data/lib/klenod/build/module_record.rb +22 -0
  22. data/lib/klenod/build/plugin.rb +35 -0
  23. data/lib/klenod/build/plugins/class_names_runtime.rb +125 -0
  24. data/lib/klenod/build/plugins/component_defaults.rb +12 -0
  25. data/lib/klenod/build/plugins/data_plugin.rb +117 -0
  26. data/lib/klenod/build/plugins/gem_import_plugin.rb +125 -0
  27. data/lib/klenod/build/plugins/google_fonts_plugin/font_metrics.json +17687 -0
  28. data/lib/klenod/build/plugins/google_fonts_plugin/font_metrics.rb +105 -0
  29. data/lib/klenod/build/plugins/google_fonts_plugin/font_metrics.txt +31 -0
  30. data/lib/klenod/build/plugins/google_fonts_plugin.rb +387 -0
  31. data/lib/klenod/build/plugins/haml_plugin/companions.rb +40 -0
  32. data/lib/klenod/build/plugins/haml_plugin/errors.rb +114 -0
  33. data/lib/klenod/build/plugins/haml_plugin/helper_source.rb +123 -0
  34. data/lib/klenod/build/plugins/haml_plugin/parser.rb +85 -0
  35. data/lib/klenod/build/plugins/haml_plugin/transformer/ruby_builder.rb +1039 -0
  36. data/lib/klenod/build/plugins/haml_plugin/transformer.rb +766 -0
  37. data/lib/klenod/build/plugins/haml_plugin.rb +369 -0
  38. data/lib/klenod/build/plugins/image_plugin.rb +401 -0
  39. data/lib/klenod/build/plugins/intl_plugin.rb +34 -0
  40. data/lib/klenod/build/plugins/markdown_compiler.rb +180 -0
  41. data/lib/klenod/build/plugins/markdown_plugin.rb +161 -0
  42. data/lib/klenod/build/plugins/router_plugin.rb +942 -0
  43. data/lib/klenod/build/plugins/ruby_plugin.rb +34 -0
  44. data/lib/klenod/build/plugins/svg_plugin.rb +197 -0
  45. data/lib/klenod/build/plugins.rb +22 -0
  46. data/lib/klenod/build/profiler.rb +79 -0
  47. data/lib/klenod/build/resolution_error_formatter.rb +42 -0
  48. data/lib/klenod/build/resolver.rb +95 -0
  49. data/lib/klenod/build/ruby_import_rewriter.rb +436 -0
  50. data/lib/klenod/build/source_map/editor.rb +110 -0
  51. data/lib/klenod/build/source_map/map.rb +168 -0
  52. data/lib/klenod/build/source_map/vlq.rb +68 -0
  53. data/lib/klenod/build/source_map.rb +12 -0
  54. data/lib/klenod/build/transform_result.rb +12 -0
  55. data/lib/klenod/build/version.rb +7 -0
  56. data/lib/klenod/build/watched_pattern.rb +11 -0
  57. data/lib/klenod/build/watcher.rb +141 -0
  58. data/lib/klenod/build.rb +15 -0
  59. metadata +310 -0
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "klenod/runtime/source_map"
4
+ require "date"
5
+ require "yaml"
6
+
7
+ require_relative "../dependency"
8
+ require_relative "../module_id"
9
+ require_relative "../plugin"
10
+ require_relative "../transform_result"
11
+ require_relative "../watched_pattern"
12
+ require_relative "class_names_runtime"
13
+ require_relative "component_defaults"
14
+ require_relative "haml_plugin"
15
+ require_relative "markdown_compiler"
16
+
17
+ module Klenod
18
+ module Build
19
+ module Plugins
20
+ module MarkdownPlugin
21
+ def self.new(...)
22
+ Plugin.new(...)
23
+ end
24
+
25
+ class Plugin < Klenod::Build::Plugin
26
+ include ClassNamesRuntime
27
+
28
+ DEFAULT_COMPONENT_BASE_CLASS = ComponentDefaults::DEFAULT_COMPONENT_BASE_CLASS
29
+ DEFAULT_FACTORY = ComponentDefaults::DEFAULT_FACTORY
30
+ COMPONENTS_MODULE_ID = ModuleId.new("markdown-components.rb", nil)
31
+ COMPONENTS_DEPENDENCY_ID_SUFFIX = "markdown_components"
32
+
33
+ def initialize(
34
+ component_base_class: DEFAULT_COMPONENT_BASE_CLASS,
35
+ factory: DEFAULT_FACTORY
36
+ )
37
+ @component_base_class = component_base_class
38
+ @factory = factory
39
+ end
40
+
41
+ def resolve(dependency, _context)
42
+ resolve_class_names_runtime(dependency)
43
+ end
44
+
45
+ def load(module_id, _context)
46
+ load_class_names_runtime(module_id)
47
+ end
48
+
49
+ def transform(module_id, code, context)
50
+ return super unless module_id.extname == ".md"
51
+
52
+ frontmatter, markdown_source = parse_frontmatter(code)
53
+ builder = HamlPlugin::Transformer::RubyBuilder.new(profiler: context.profiler)
54
+ dependency = markdown_components_dependency(module_id, context)
55
+ class_names_dependency = class_names_runtime_dependency(module_id)
56
+ components_source = components_source_for(dependency)
57
+ render_source = MarkdownCompiler.new(factory: @factory, components_source: components_source).compile(markdown_source)
58
+ component_class_name = component_class_name(module_id)
59
+ class_names_source = "#{builder.import_call(class_names_dependency.id).source}.new({}.freeze)"
60
+ generated =
61
+ builder.component_source(
62
+ component_class_name: component_class_name,
63
+ component_base_class: @component_base_class,
64
+ translations_source: "{}.freeze",
65
+ ruby_source: "",
66
+ render_source: render_source,
67
+ styles_source: class_names_source
68
+ )
69
+ generated = "#{generated}\nDefault.const_set(:Frontmatter, #{frontmatter.inspect}.freeze)\n"
70
+
71
+ TransformResult.new(
72
+ generated,
73
+ [dependency, class_names_dependency].compact,
74
+ Runtime::SourceMap::SourceMap.parse(code, generated),
75
+ [],
76
+ [WatchedPattern.new(module_id, COMPONENTS_MODULE_ID.path, :markdown_components, {})],
77
+ {}
78
+ )
79
+ end
80
+
81
+ def import_value(resolved_dependency, record, context)
82
+ class_names_import = class_names_runtime_import_value(resolved_dependency, record, context)
83
+ return class_names_import if class_names_import
84
+ return nil unless record.id.extname == ".md"
85
+
86
+ context.mods.fetch(record.id).const_get(:Exports)::Default
87
+ end
88
+
89
+ def runtime_import_value(resolved_dependency, record, _context)
90
+ class_names_import = class_names_runtime_runtime_import_value(resolved_dependency, record)
91
+ return class_names_import if class_names_import
92
+ return Runtime::DefaultImport.new(:Default) if record.id.extname == ".md"
93
+
94
+ super
95
+ end
96
+
97
+ private
98
+
99
+ def parse_frontmatter(source)
100
+ match = source.match(/\A---[ \t]*\r?\n(?<frontmatter>.*?\r?\n)---[ \t]*(?:\r?\n|\z)/m)
101
+ return [{}, source] unless match
102
+
103
+ frontmatter = YAML.safe_load(match[:frontmatter], permitted_classes: [Date, Time, Symbol], aliases: false, symbolize_names: true) || {}
104
+
105
+ unless frontmatter.is_a?(Hash)
106
+ raise ArgumentError, "Markdown frontmatter must be a mapping"
107
+ end
108
+
109
+ [normalize_frontmatter(frontmatter), source.byteslice(match.end(0)..) || ""]
110
+ end
111
+
112
+ def normalize_frontmatter(value)
113
+ case value
114
+ when Hash
115
+ value.transform_values { normalize_frontmatter(it) }
116
+ when Array
117
+ value.map { normalize_frontmatter(it) }
118
+ when Date, Time
119
+ value.iso8601
120
+ else
121
+ value
122
+ end
123
+ end
124
+
125
+ def markdown_components_dependency(module_id, context)
126
+ return unless context.absolute_path(COMPONENTS_MODULE_ID).file?
127
+
128
+ Dependency
129
+ .create(
130
+ specifier: "/markdown-components",
131
+ importer_id: module_id,
132
+ kind: :markdown_components,
133
+ metadata: {optional: true}
134
+ )
135
+ .with(id: dependency_id(module_id))
136
+ end
137
+
138
+ def components_source_for(dependency)
139
+ dependency ? "__klenod_import__(#{dependency.id.inspect})::Default" : "{}"
140
+ end
141
+
142
+ def dependency_id(module_id)
143
+ "#{module_id}:#{COMPONENTS_DEPENDENCY_ID_SUFFIX}"
144
+ end
145
+
146
+ def component_class_name(module_id)
147
+ parts =
148
+ module_id
149
+ .path
150
+ .delete_suffix(module_id.extname)
151
+ .split(/[^A-Za-z0-9]+/)
152
+ .reject(&:empty?)
153
+
154
+ name = parts.map { it[0].upcase + it[1..] }.join
155
+ name.empty? ? "Markdown" : name
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end