Parse, compare, and sort the chapter identifiers scanlation sources actually use — into correct reading order.
Chapter "numbers" in the wild aren't numbers. Real identifiers from real
sources: 10.5 (sub-chapter), 129e / 62b (letter-suffixed extras and
parts), 062 (zero-padded), 430f, v30-c378 (volume-chapter
compounds). Naive string sorting breaks instantly ("10" < "9"), naive
number parsing chokes on the rest — and wrong ordering silently corrupts
real behavior: prev/next navigation, resume pointers, new-chapter
notifications, caught-up detection.
Chapter.sort(["10.5", "9", "129e", "10", "129"])
#=> ["9", "10", "10.5", "129", "129e"]
Chapter.gt?("v30-c378", "v30-c377.5") #=> true — is this chapter newer?
Chapter.compare("062", "62") #=> :eq — zero padding insignificant
Chapter.number("v30-c378") #=> 378 — display number
Chapter.last_number(~w(1 2 2.5 3)) #=> 3 — count that survives sub-chaptersPure functions, zero dependencies. Identifiers stay opaque strings — only their order is interpreted.
def deps do
[
{:chapter, "~> 0.1"}
]
end| Function | Answers |
|---|---|
Chapter.sort_key/1 |
a term that orders correctly under Enum.sort_by / term comparison |
Chapter.sort/1,2 |
reading order (:asc / :desc) |
Chapter.compare/2 |
:lt / :eq / :gt |
Chapter.gt?/2, Chapter.before?/2 |
"is this chapter newer / already read?" |
Chapter.number/1 |
display integer ("v30-c378" → 378) |
Chapter.last_number/1 |
highest display number in a list ("133 chapters" that isn't inflated by 10.5s) |
Chapter.Status.normalize/1 |
series publication status → ongoing / completed / hiatus / unknown (EN + RU variants) |
sort_key/1 maps each identifier to a comparison-safe term:
vVOL-cNUM→{volume, number}— volume-aware- numeric-prefixed →
{number, suffix}— so129 < 129e,062 == 62 - unparsable (
"extra","oneshot") →{0, identifier}— clusters at the front, lexical among itself
Cross-format comparisons (a v-c compound vs a bare number) are
inherently ambiguous; real series stick to one format, and keys stay
deterministic either way.
Built for comic/manga readers — it's the ordering half of implementing
a manhwa /
manga Store (list_chapters must be
reading-ordered), next to dims for the
page-dimensions half.
MIT