Python to Ruby

This commit is contained in:
julien committed 2026-09-30 14:27:05 +02:00
1 parent cf82698bef
commit 4c9e1f5f66
13 files changed
+360 -711

No files matched your search

+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require "json"
require "optparse"
require "time"
require_relative "schema"
ENV["TZ"] = "Europe/Paris"
ROOT = File.expand_path("..", __dir__)
CONTENT = File.join(ROOT, "src", "content")
options = {}
parser = OptionParser.new do |opts|
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} SECTION IDENTIFIANT [options]"
opts.on("--nature NATURE", "nature d’une fiche de vocabulaire") { |value| options[:nature] = value }
opts.on("--title TITRE", "titre initial") { |value| options[:title] = value }
end
begin
parser.parse!
raise "SECTION et IDENTIFIANT sont requis, sans argument supplémentaire" unless ARGV.length == 2
section_name, identifier = ARGV
section = SECTION_ALIASES[section_name]
raise "section inconnue : #{section_name}" unless section
normalize = ->(value) { value.strip.unicode_normalize(:nfc) }
identifier = normalize.call(identifier)
if section == "signes"
match = identifier.match(/\A(?:mzl-)?([0-9]{1,3})\z/)
raise "le numéro MZL doit être compris entre 1 et 999" unless match && match[1].to_i.between?(1, 999)
mzl = format("%03d", match[1].to_i)
filename = "mzl-#{mzl}"
else
leading_hyphen = identifier.start_with?("-")
body = leading_hyphen ? identifier[1..] : identifier
raise "seul le vocabulaire accepte un identifiant commençant par un tiret" if leading_hyphen && section != "vocabulaire"
valid = body && !body.empty? && identifier != "_index" && identifier == identifier.downcase &&
!identifier.end_with?("-") && !identifier.include?("--") && body.match?(/\A[\p{Alnum}-]+\z/u)
raise "identifiant de fichier invalide" unless valid
filename = identifier
end
nature = options[:nature]&.unicode_normalize(:nfc)
if section == "vocabulaire"
raise "--nature est requis pour le vocabulaire" unless nature
raise "nature grammaticale inconnue : #{nature}" unless VOCABULARY_FIELDS.key?(nature)
elsif nature
raise "--nature est réservé au vocabulaire"
end
title = if options[:title]
normalize.call(options[:title])
elsif section == "signes"
""
elsif section == "vocabulaire"
filename
else
filename.tr("-", " ").sub(/\A./) { |char| char.upcase }
end
tables = if section == "vocabulaire"
{
"extra" => VOCABULARY_FIELDS.fetch(nature).to_h { |field| [field, LIST_FIELDS.include?(field) ? [] : ""] },
"taxonomies" => { "natures" => [nature] }
}
else
SECTION_FIELDS.fetch(section).transform_values do |fields|
fields.to_h { |field| [field, LIST_FIELDS.include?(field) ? [] : ""] }
end
end
tables["extra"]["mzl"] = mzl if section == "signes"
lines = [
"+++",
"title = #{JSON.generate(title)}",
"date = #{Time.now.iso8601}",
"# updated = YYYY-MM-DDTHH:MM:SS+HH:MM",
'description = ""',
"draft = true"
]
tables.each do |table, fields|
lines << ""
lines << "[#{table}]"
fields.each { |field, value| lines << "#{field} = #{JSON.generate(value)}" }
end
lines += ["+++", ""]
destination = File.join(CONTENT, section, "#{filename}.md")
File.open(destination, File::WRONLY | File::CREAT | File::EXCL, 0o644) { |file| file.write(lines.join("\n")) }
puts "Brouillon créé : #{destination.delete_prefix(ROOT + '/')}"
rescue OptionParser::ParseError, RuntimeError, Errno::EEXIST, SystemCallError => e
warn "Erreur : #{e.message}"
exit 1
end