Python to Ruby
This commit is contained in:
1 parent
cf82698bef
commit
4c9e1f5f66
13 files changed
+360
-711
No files matched your search
Executable
+98
@@ -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
|
||||
Reference in new issue
Block a user