How book-to-skill Handles Multilingual Chapter Detection: Arabic, Roman, Chinese & Kangxi Support
multilingual chapter detection is built into book-to-skill with native support for Arabic numerals, Roman numerals, traditional Chinese numerals, and Kangxi radicals—no configuration required.
The book-to-skill repository provides a robust chapter-extraction pipeline that recognizes chapter headings across multiple writing systems and numeral styles. Whether your source material uses standard Western numbering, classical Roman numerals, or traditional Chinese characters, the library automatically detects and parses chapter boundaries without manual intervention.
Core Detection Mechanism in utils.py
The backbone of multilingual chapter detection resides in book_to_skill/utils.py, specifically in the _match_chapter_number function starting at line 447. This function orchestrates multiple numeral parsers to identify valid chapter headings.
Each parser follows the same contract: attempt to extract an integer chapter number (1–999) from a heading string. If successful, the heading is treated as a chapter boundary.
Supported Numeral Systems
ASCII and Arabic Chapter Numbers
Standard numeric headings like 12 Introduction are detected using regex pattern matching. The parser requires two or more spaces after the number to distinguish chapter headings from list items.
# From book_to_skill/utils.py, lines 447-456
_match_chapter_number("12 Advanced Topics") # → 12
The regex ^([1-9]\d{0,2})\s{2,}\S enforces this spacing requirement, preventing false positives on numbered lists.
Roman Numerals
Classical chapter numerals (I, II, IV, IX, XIV) are supported through bidirectional conversion functions. The _roman_to_int helper (lines 514–527) validates and converts Roman strings, while _int_to_roman (lines 502–511) handles reverse conversion when needed.
_match_chapter_number("IX Conclusion") # → 9
_match_chapter_number("XIV Appendices") # → 14
Chinese (Han) Numerals
Traditional Chinese characters for numbers are fully supported through the _cn_numeral_to_int function at lines 484–499. This parser recognizes both simple numerals (一, 二, 三) and compound forms with units (二十, 一百零八).
The implementation maps individual characters using lookup tables _CN_NUM_VALUES and _CN_NUM_UNITS, enabling conversion of any valid Chinese numeral from 1 to 999.
_match_chapter_number("二十一 章节标题") # → 21
_match_chapter_number("一百零八 细节说明") # → 108
Kangxi Radicals Normalization
Before Chinese numeral parsing, the system normalizes Kangxi radicals (Unicode block U+2F00) into their corresponding ideographs. This preprocessing occurs in _match_chapter_number (lines 332–339) via translate(_KANGXI_NUMERAL_TRANS).
This step ensures compatibility with legacy texts and specialized fonts that may use radical variants instead of standard Han characters.
Full-Width Arabic Digits
East-Asian typography often employs full-width Arabic digits (1, 2, 3). These are handled transparently through the same numeric pipeline, converting to standard integers before chapter validation.
_match_chapter_number("12 序章") # → 12
Structural Chapter Detection
For documents with varied heading styles, _structural_chapter_count (lines 404–481) performs line-by-line analysis. This function:
- Skips fenced code blocks to avoid false chapter detection in source examples
- Applies the same multilingual numeral heuristics to Setext and ATX markdown headings
- Handles AsciiDoc and RST conventions through pattern-agnostic parsing
The structural walker feeds detected chapter boundaries into the skill generation pipeline, which outputs isolated chapter files to the chapters/ directory.
Working Code Example
from book_to_skill.utils import _match_chapter_number
# Test all supported numeral systems
test_cases = [
"12 Advanced Topics", # ASCII Arabic
"IX Conclusion", # Roman
"二十一 章节标题", # Chinese Han
"12 序章", # Full-width Arabic
]
for heading in test_cases:
chapter_num = _match_chapter_number(heading)
print(f"{heading!r:30} → {chapter_num}")
All four cases return valid integer chapter numbers, demonstrating the multilingual chapter detection capability without configuration switches or language flags.
Integration with Document Parsers
Language-specific parsers in book_to_skill/parsers/*.py (PDF, HTML, EPUB) feed raw text into the chapter detector. This architecture separates format handling from numeral parsing, allowing any input format to leverage the same multilingual chapter detection engine.
The discovery tool at tools/discovery_tax.py demonstrates downstream reuse of chapter detection for analysis pipelines.
Test Coverage
Unit tests in tests/test_book_to_skill.py validate:
- Chinese numeral conversion edge cases (
_cn_numeral_to_int) - Roman numeral round-trip correctness (
_int_to_roman↔_roman_to_int) - Kangxi radical normalization accuracy
- Full-width digit handling
Summary
- multilingual chapter detection in book-to-suport supports Arabic, Roman, Chinese, and Kangxi numeral systems out of the box
- Core logic resides in
_match_chapter_numberand helpers withinbook_to_skill/utils.py - No configuration required—detection is automatic based on character patterns
- Valid chapter numbers span 1–999 across all supported writing systems
- Line-based structural parsing handles markdown, AsciiDoc, and RST formats uniformly
Frequently Asked Questions
Does book-to-skill require language configuration for chapter detection?
No. The _match_chapter_number function automatically attempts multiple parsers in sequence: ASCII Arabic, Roman, Chinese, and full-width variants. The first successful conversion determines the chapter number without explicit language selection.
What is the maximum chapter number supported?
All numeral parsers enforce a 1–999 range. Chinese numerals compound using units (十, 百), Roman numerals follow classical construction rules, and Arabic formats accept 1–3 digit numbers. This bound prevents false positives on year dates and similar numeric strings.
Can I extend support for additional numeral systems?
Yes. The parser architecture in book_to_skill/utils.py accommodates new converters by adding conversion logic to _match_chapter_number. Each converter must return an integer or None, following the existing pattern of _roman_to_int and _cn_numeral_to_int.
How does the system avoid detecting numbered lists as chapters?
The ASCII Arabic parser requires two or more spaces after the number via regex \s{2,}. Single-space separators typical of markdown lists (1. Item) fail this pattern, preserving list structure while capturing genuine chapter headings.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →