Module: Abqari::Importers::Support::SlugNormalizer

Defined in:
lib/abqari/importers/support/slug_normalizer.rb

Overview

Slug normalisation + collision resolution shared by every importer. The slug rules match bin/new's slugify (lowercase, [^a-z0-9]+ collapsed to a single dash, leading/trailing dashes stripped) so imported posts are indistinguishable from posts authored fresh via the generator.

Collision policy is "append a numeric suffix" — foo, foo-2, foo-3. The user picked this over date-prefixing because date-prefixing makes URLs uglier and the source platforms (Substack especially) sometimes reuse slugs deliberately. The appended suffix preserves the original slug as the canonical form when there's no conflict.

Class Method Summary collapse

Class Method Details

.normalize(text) ⇒ Object

Strip a slug down to the engine's canonical shape. ASCII-fold is intentionally omitted — non-ASCII characters are dropped rather than transliterated, matching bin/new's behaviour. Callers that need transliteration (e.g. an importer pulling from a CJK source) should pre-process before calling this.



26
27
28
29
30
31
# File 'lib/abqari/importers/support/slug_normalizer.rb', line 26

def normalize(text)
  text.to_s
      .downcase
      .gsub(/[^a-z0-9]+/, '-')
      .gsub(/\A-|-\z/, '')
end

.resolve(slug, taken) ⇒ Object

Resolve a slug against an in-memory set of already-taken slugs. Mutates the set as a side-effect — the resolved slug is added so subsequent calls in the same run see it. This is a pure-in-memory check, distinct from the on-disk collision check that the writer applies separately (filesystem state can change between importer invocations).



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/abqari/importers/support/slug_normalizer.rb', line 39

def resolve(slug, taken)
  slug = 'untitled' if slug.to_s.empty?
  candidate = slug
  n = 2
  while taken.include?(candidate)
    candidate = "#{slug}-#{n}"
    n += 1
  end
  taken << candidate
  candidate
end