From 4259b9915fe93296fa5c50724820c59e4352ac3a Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Sun, 9 Jun 2024 17:14:24 +0800 Subject: [PATCH] fix: make SchemaDocument work --- lib/suma/collection_manifest.rb | 62 ++++++++++++++++++++++---------- lib/suma/processor.rb | 41 +++++++-------------- lib/suma/schema_collection.rb | 43 ++++++++++++++++------ lib/suma/schema_config/config.rb | 53 +++++++++++++++++++++------ lib/suma/schema_config/schema.rb | 2 +- 5 files changed, 130 insertions(+), 71 deletions(-) diff --git a/lib/suma/collection_manifest.rb b/lib/suma/collection_manifest.rb index a134b12..0b40055 100644 --- a/lib/suma/collection_manifest.rb +++ b/lib/suma/collection_manifest.rb @@ -8,6 +8,8 @@ module Suma class CollectionManifest < Metanorma::Collection::Config::Manifest attribute :schemas_only, Shale::Type::Boolean attribute :entry, CollectionManifest, collection: true + attribute :schema_source, Shale::Type::String + attr_accessor :schema_config yaml do map "identifier", to: :identifier @@ -32,18 +34,25 @@ def docref_from_yaml(model, value) model.entry = CollectionManifest.from_yaml(value.to_yaml) end - def is_express_doc - type == "express_doc" + def export_schema_config(path) + export_config = @schema_config || Suma::SchemaConfig::Config.new + entry&.map do |x| + x.export_schema_config(path) + end.compact.each_with_object(export_config) do |x, acc| + acc.concat(x) + acc + end + export_config end - def all_express_docs - entry&.map(&:all_express_docs)&.flatten&.compact&.+ (is_express_doc ? [self] : []) + def lookup(attr_sym, match) + (entry.select do |e| + e.send(attr_sym) == match + end + [self.send(attr_sym) == match ? self.send(attr_sym) : nil]).compact end - attr_accessor :schema_xml_files - def expand_schemas_only(schema_output_path) - unless schemas_only + unless file entry or return [self] ret = entry.each_with_object([]) do |e, m| add = e.expand_schemas_only(schema_output_path) @@ -53,14 +62,22 @@ def expand_schemas_only(schema_output_path) return [self] end - # This is the collection.yml file path - # doc = YAML.safe_load(File.read(file)) - doc = CollectionConfig.from_file(file) - doc_id = doc.bibdata.id + if File.basename(file) == 'collection.yml' + schemas_yaml_path = File.join(File.dirname(file), "schemas.yaml") + if schemas_yaml_path && File.exist?(schemas_yaml_path) + @schema_config = Suma::SchemaConfig::Config.from_file(schemas_yaml_path) + end + end - # This is the schemas.yml file path - schemas_yaml_path = File.join(File.dirname(file), "schemas.yaml") - schema_config = SchemaConfig::Config.from_file(schemas_yaml_path) + unless schemas_only + entry or return [self] + ret = entry.each_with_object([]) do |e, m| + add = e.expand_schemas_only(schema_output_path) + add.each { |x| m << x } + end + self.entry = ret + return [self] + end # The schemas can't load if the file is removed # self.file = nil @@ -69,20 +86,27 @@ def expand_schemas_only(schema_output_path) #self.title = "Collection" #self.type = "collection" - entries = schema_config.schemas.map do |schema| + # This is the collection.yml file path + doc = CollectionConfig.from_file(file) + doc_id = doc.bibdata.id + + # pp @schema_config + + entries = @schema_config.schemas.map do |schema| # TODO: We compile these later, but where is the actual compile command? # Answer: in manifest_compile_adoc, on postprocess, end of initialisation of manifest object fname = [File.basename(schema.path, ".exp"), ".xml"].join + CollectionManifest.new( identifier: schema.id, title: schema.id, file: File.join(schema_output_path, "doc_#{schema.id}", fname), - type: "express_doc" # This means this schema is a SchemaDocument + type: "express_doc", # This means this schema is a SchemaDocument + schema_source: schema.path ) end # we need to separate this file from the following new entries - added = CollectionManifest.new( title: "Collection", type: "collection", @@ -93,8 +117,8 @@ def expand_schemas_only(schema_output_path) CollectionManifest.new( title: doc_id, type: "document", - entry: entries - ) + entry: entries, + ), ] [self, added] diff --git a/lib/suma/processor.rb b/lib/suma/processor.rb index 1e10941..be0ba05 100644 --- a/lib/suma/processor.rb +++ b/lib/suma/processor.rb @@ -12,31 +12,6 @@ module Suma class Processor class << self - # Can move to schema_config.rb - def write_all_schemas(schemas_all_path, collection_config) - # Gather all the inner (per-document) collection.yml files - document_paths = collection_config.manifest.entry.map(&:file).compact - - all_schemas = Suma::SchemaConfig::Config.new(path: schemas_all_path) - - document_paths.each do |path| - schemas_yaml = File.join(File.dirname(path), "schemas.yaml") - next unless File.exist?(schemas_yaml) - - schemas_config = Suma::SchemaConfig::Config.from_file(schemas_yaml) - all_schemas.concat(schemas_config) - end - - schemas_only_list = collection_config.manifest.all_express_docs - schemas_only_list.each do |mani| - all_schemas.set_schemas_only(mani.identifier) - end - - Utils.log "Writing #{schemas_all_path}..." - all_schemas.to_file - Utils.log "Done." - end - def run(metanorma_yaml_path:, schemas_all_path:, compile:, output_directory: "_site") Utils.log "Current directory: #{Dir.getwd}" @@ -49,12 +24,20 @@ def run(metanorma_yaml_path:, schemas_all_path:, compile:, output_directory: "_s collection_config.path = collection_config_path collection_config.manifest.expand_schemas_only("plain_schemas") - write_all_schemas(schemas_all_path, collection_config) + exported_schema_config = collection_config.manifest.export_schema_config(schemas_all_path) + exported_schema_config.path = schemas_all_path + + pp exported_schema_config + + Utils.log "Writing #{schemas_all_path}..." + exported_schema_config.to_file + Utils.log "Done." col = Suma::SchemaCollection.new( config_yaml: schemas_all_path, + manifest: collection_config.manifest, output_path_docs: "schema_docs", - output_path_schemas: "plain_schemas" + output_path_schemas: "plain_schemas", ) if compile @@ -111,9 +94,9 @@ def run(metanorma_yaml_path:, schemas_all_path:, compile:, output_directory: "_s format: [:html], output_folder: output_directory, compile: { - no_install_fonts: true + no_install_fonts: true, }, - coverpage: "cover.html" + coverpage: "cover.html", } metanorma_collection.render(collection_opts) diff --git a/lib/suma/schema_collection.rb b/lib/suma/schema_collection.rb index 4e01c11..200c401 100644 --- a/lib/suma/schema_collection.rb +++ b/lib/suma/schema_collection.rb @@ -8,11 +8,12 @@ module Suma class SchemaCollection - attr_accessor :config, :schemas, :docs, :output_path_docs, :output_path_schemas + attr_accessor :config, :schemas, :docs, :output_path_docs, :output_path_schemas, + :manifest - def initialize(config: nil, config_yaml: nil, output_path_docs: nil, output_path_schemas: nil) - @schemas = [] - @docs = [] + def initialize(config: nil, config_yaml: nil, output_path_docs: nil, output_path_schemas: nil, manifest: nil) + @schemas = {} + @docs = {} @schema_name_to_docs = {} @output_path_docs = if output_path_docs Pathname.new(output_path_docs).expand_path @@ -30,36 +31,56 @@ def initialize(config: nil, config_yaml: nil, output_path_docs: nil, output_path elsif config_yaml SchemaConfig::Config.from_file(config_yaml) end + + @manifest = manifest end def doc_from_schema_name(schema_name) @schema_name_to_docs[schema_name] end - def finalize - @config.schemas.each do |config_schema| + def process_schemas(schemas, klass) + schemas.each do |config_schema| s = ExpressSchema.new( id: config_schema.id, path: config_schema.path.to_s, output_path: @output_path_schemas.to_s ) - klass = config_schema.schemas_only ? SchemaDocument : SchemaAttachment doc = klass.new( schema: s, output_path: @output_path_docs.join(s.id) ) - @docs << doc - @schemas << s + @docs[s.id] = doc + @schemas[s.id] = s @schema_name_to_docs[s.id] = doc end end + def finalize + # Process each schema in @config.schemas + process_schemas(@config.schemas, SchemaAttachment) + + manifest_entry = @manifest.lookup(:schemas_only, true) + + manifest_entry.each do |entry| + next unless entry.schema_config + + # Process each schema in entry.schema_config.schemas + process_schemas(entry.schema_config.schemas, SchemaDocument) + end + end + def compile finalize - schemas.map(&:save_exp) - docs.each(&:compile) + schemas.each_pair do |schema_id, entry| + entry.save_exp + end + + docs.each_pair do |schema_id, entry| + entry.compile + end # TODO: make this parallel # Utils.log"Starting Ractor processing" diff --git a/lib/suma/schema_config/config.rb b/lib/suma/schema_config/config.rb index b48537d..76e97e0 100644 --- a/lib/suma/schema_config/config.rb +++ b/lib/suma/schema_config/config.rb @@ -11,7 +11,7 @@ class Config < Shale::Mapper attr_accessor :path def initialize(path: nil, **args) - @path = path + @path = path_relative_to_absolute(path) if path super(**args) end @@ -25,7 +25,7 @@ def base_path def self.from_file(path) from_yaml(File.read(path)).tap do |x| - x.path = path + x.set_initial_path(path) end end @@ -35,27 +35,58 @@ def to_file(to_path = path) end end - def set_schemas_only(schema_name) - schema = schemas.detect do |e| - e.id == schema_name + def set_initial_path(new_path) + @path = path_relative_to_absolute(new_path) + schemas.each do |schema| + schema.path = path_relative_to_absolute(schema.path) end - - schema.schemas_only = true end def schemas_from_yaml(model, value) + puts "*"*30 model.schemas = value.map do |k, v| - Schema.new(id: k, path: v["path"], schemas_only: v["schemas-only"]) + Schema.new(id: k, path: path_relative_to_absolute(v["path"])) end end def schemas_to_yaml(model, doc) + puts "^"*30 + pp self doc["schemas"] = model.schemas.sort_by(&:id).to_h do |schema| - [schema.id, { "path" => schema.path, "schemas-only" => schema.schemas_only }] + [schema.id, { "path" => path_absolute_to_relative(schema.path) }] end end + def path_relative_to_absolute(relative_path) + eval_path = Pathname.new(relative_path) + return relative_path if eval_path.absolute? + + # Or based on current working directory? + return relative_path unless @path + + Pathname.new(File.dirname(@path)).join(eval_path).expand_path.to_s + end + + def path_absolute_to_relative(absolute_path) + puts "path_absolute_to_relative 1 #{absolute_path}" + return absolute_path unless @path + + eval_path = Pathname.new(absolute_path) + + puts "path_absolute_to_relative 2 #{eval_path}" + # Or based on current working directory? + + x = Pathname.new(absolute_path).relative_path_from(File.dirname(@path)).to_s + puts "path_absolute_to_relative x #{x}" + x + end + def update_path(new_path) + if @path.nil? + @path = new_path + return @path + end + old_base_path = File.dirname(@path) new_base_path = File.dirname(new_path) @@ -76,8 +107,8 @@ def concat(another_config) raise StandardError, "Can only concatenate a non SchemaConfig::Config object." end - # We need to update the relative paths - if path != another_config.path + # We need to update the relative paths when paths exist + if path && another_config.path && path != another_config.path new_config = another_config.dup new_config.update_path(path) end diff --git a/lib/suma/schema_config/schema.rb b/lib/suma/schema_config/schema.rb index 327e697..7f5c290 100644 --- a/lib/suma/schema_config/schema.rb +++ b/lib/suma/schema_config/schema.rb @@ -7,7 +7,7 @@ module SchemaConfig class Schema < Shale::Mapper attribute :id, Shale::Type::String attribute :path, Shale::Type::String - attribute :schemas_only, Shale::Type::Boolean + # attribute :schemas_only, Shale::Type::Boolean end end end