Module: ImmosquareYaml

Extended by:
SharedMethods
Defined in:
lib/immosquare-yaml.rb,
lib/immosquare-yaml/railtie.rb,
lib/immosquare-yaml/version.rb,
lib/immosquare-yaml/configuration.rb,
lib/immosquare-yaml/shared_methods.rb

Overview

##

ImmosquareYaml — post-processeur Psych dédié aux fichiers de traduction (locales Rails).

Trois responsabilités :

- parse(file)  : YAML → Hash, en s'appuyant sur l'AST Psych
- dump(hash)   : Hash → YAML formaté (quotes minimales,
                 blocs littéraux, emojis décodés)
- clean(file)  : parse + tri par clé + dump → écrit

La gem résout cinq problèmes que Psych seul ne traite pas :

1. Norway problem (yes/no/on/off lus comme String)
2. Tri déterministe par clé
3. Préservation des blocs littéraux (|, |-)
4. Quotes minimales pour la lisibilité
5. Décodage des escapes \U0001F600 → emoji
##

Defined Under Namespace

Modules: SharedMethods Classes: Configuration, Railtie

Constant Summary collapse

VERSION =
"1.0.0".freeze

Constants included from SharedMethods

SharedMethods::CUSTOM_SEPARATOR, SharedMethods::DOUBLE_QUOTE, SharedMethods::DOUBLE_SIMPLE_QUOTE, SharedMethods::INDENT_SIZE, SharedMethods::NEWLINE, SharedMethods::NOTHING, SharedMethods::RESERVED_KEYS, SharedMethods::SIMPLE_QUOTE, SharedMethods::SPACE, SharedMethods::WEIRD_QUOTES_REGEX, SharedMethods::YML_SPECIAL_CHARS

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from SharedMethods

deep_transform_values

Class Attribute Details

.configurationObject



32
33
34
# File 'lib/immosquare-yaml.rb', line 32

def configuration
  @configuration ||= Configuration.new
end

Class Method Details

.clean(file_path, **options) ⇒ Object

##

clean(file_path, sort: true, output: file_path) Charge le fichier, le re-écrit propre et trié. Retourne true / false selon le succès.

##


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/immosquare-yaml.rb', line 45

def clean(file_path, **options)
  options = {
    :sort   => true,
    :output => file_path
  }.merge(options)

  begin
    raise("File not found") if !File.exist?(file_path)

    parsed_yml = parse(file_path, :sort => options[:sort])
    return false if parsed_yml == false

    output = dump(parsed_yml)
    FileUtils.mkdir_p(File.dirname(options[:output]))
    File.write(options[:output], output)
    true
  rescue StandardError => e
    puts(e.message)
    puts(e.backtrace)
    false
  end
end

.config {|configuration| ... } ⇒ Object

Yields:



36
37
38
# File 'lib/immosquare-yaml.rb', line 36

def config
  yield(configuration)
end

.dump(hash) ⇒ Object

##

dump(hash) → String YAML Sérialise un Hash en YAML avec nos règles de formatage :

- clés "yes/no/on/..." re-quotées
- valeurs plain quand c'est sûr, sinon doublequotées
- chaînes multi-lignes en bloc littéral | ou |-
- arrays imbriqués délégués à Psych.dump puis indentés
##


116
117
118
# File 'lib/immosquare-yaml.rb', line 116

def dump(hash)
  render_hash(hash, [], 0)
end

.parse(file_path, **options) ⇒ Object

##

parse(file_path, sort: true) Lit un fichier YAML et retourne un Hash Ruby. Hash trié par clé par défaut.

Implémentation : on parcourt l’AST Psych plutôt que d’appeler Psych.load. Cela permet de :

- distinguer un scalaire plain "yes" d'un bool true
- garder les valeurs problématiques (Norway) en String
- décoder nous-mêmes les escapes \U... pour les blocs
  littéraux qui ne sont pas désescapés par Psych
##


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/immosquare-yaml.rb', line 80

def parse(file_path, **options)
  options = {:sort => true}.merge(options)

  begin
    raise("File not found") if !File.exist?(file_path)

    ##============================================================##
    ## Psych.parse_file retourne un Document. Si le fichier est
    ## vide ou ne contient que des commentaires, root est nil.
    ##============================================================##
    doc = Psych.parse_file(file_path)
    return {} if !doc || doc.root.nil?

    result = node_to_value(doc.root, {})

    ##============================================================##
    ## On accepte tous les types racine (Hash, Array, scalaire),
    ## mais on ne trie que si la racine est un Hash.
    ##============================================================##
    result = result.sort_by_key if options[:sort] && result.is_a?(Hash)
    result
  rescue StandardError => e
    puts(e.message)
    puts(e.backtrace)
    false
  end
end