What Types of Chapter Headings Can book-to-skill Detect?

book-to-skill detects nine distinct categories of chapter headings across English, Chinese, Thai, Hindi, Korean, Persian, and other languages using layered regex patterns implemented in book_to_skill/utils.py.

The book-to-skill open-source project extracts structured knowledge from technical books and documentation by identifying chapter boundaries. Understanding what types of chapter headings the tool can detect is essential for processing multilingual publications, as the library implements language-specific regex patterns that recognize everything from explicit English labels to CJK ideographic counters and Perso-Arabic ordinals.

Detection Architecture and Core Logic

At the heart of the detection system lies the detect_structure() function in book_to_skill/utils.py. This high-level orchestrator returns a dictionary containing the chapter count, detection method (numeric, structural, or none), sample headings, and a Table-of-Contents presence flag. The actual pattern matching is handled by _match_chapter_number(), which iterates through language-specific regexes, and _chapter_number(), which extracts the numeric value from matched headings.

Supported Chapter Heading Formats

Explicit English-Style and Western Headings

The tool recognizes explicit chapter labels using the _EXPLICIT_CHAPTER regex. This pattern matches words like Chapter, Capítulo, Chapitre, Kapitel, Capitolo, and Hoofdstuk, as well as the abbreviated form ch.. These markers must be followed by a number—either Arabic or Roman—and may include optional trailing punctuation or title text.

Plain Numbered Headings

Common in technical O'Reilly-style books, plain numbered headings use a simple Arabic numeral followed by at least two spaces and then title text (e.g., 1 Introduction). The plain regex inside _match_chapter_number specifically requires this spacing to avoid misclassifying list items like 1. Item as chapters.

Roman Numeral Headings

The _ROMAN_HEAD pattern identifies upper-case Roman numerals at the start of a line followed by punctuation (I:, II.). For Markdown documents, the _LC_MD_ROMAN regex detects lower-case Roman numerals within ATX headings (e.g., ## i. introduction).

Chinese Chapter Headings

The _CN_CHAPTER regex handles traditional Chinese patterns such as 第 N 章, 第 N 回, and 第 十二 节, as well as variants like 第一讲. For Markdown-formatted Chinese texts, _MD_CN_HEADING recognizes CJK headings prefixed with hash symbols (e.g., # 第 1 章 … or # 一 · 缘起).

Thai Chapter Headings

Thai chapter markers are detected via _TH_CHAPTER, which matches words like บทที่, ตอนที่, and ภาคที่ (including short forms). These may be followed by Thai digits (⁰‑⁹) or Arabic digits, and the pattern optionally accounts for Markdown heading prefixes (##).

Hindi (Devanagari) Chapter Headings

The _HI_CHAPTER pattern identifies the word अध्याय followed by either Devanagari digits or Arabic numerals. This detection works on raw text lines or when prefixed by Markdown heading markers.

Korean Chapter Headings

Korean documents use the classifier 제 plus a numeral and specific suffixes. The _KO_CHAPTER regex matches patterns like 제12장 (chapter), 제3편 (volume), 제2절 (section), or 제5관 (part). It also handles inserted-chapter suffixes (의 N) and Markdown prefixes.

Persian (Farsi) Chapter Headings

Persian detection uses multiple patterns including _FA_DIGITS and _FA_ONES to match labels like فصل (chapter) or بخش (section) with Arabic/Persian digits, Unicode-Indic digits, or word ordinals (e.g., فصل اول, فصل بیست و یکم). The _fa_chapter_number helper function processes these variations, with a secondary pass handling Markdown heading markers.

Markdown and AsciiDoc Structural Headings

When no numeric chapters are detected, the system falls back to structural analysis using _ATX_HEADING (for # Title and ## Section) and _SETEXT_UNDERLINE (for === and --- underlines). These patterns are defined in book_to_skill/utils.py and are invoked by _structural_chapter_count only when the numeric scan returns no results.

The Detection Pipeline

The chapter detection flow follows a strict four-step sequence to maximize accuracy across languages:

  1. Normalization: Kangxi-radical numerals are translated to standard CJK ideographs using _KANGXI_NUMERAL_TRANS before pattern matching begins.

  2. Fast Numeric Scan: _match_chapter_number tests plain, explicit, Roman, CJK, Thai, Hindi, Korean, and Persian patterns in order against each line.

  3. Secondary Markdown Pass: If a line is preceded by a Markdown or AsciiDoc prefix, _MD_HEADING_PREFIX strips the prefix and re-tests the line against all numeric patterns.

  4. Structural Fallback: When no numeric headings are discovered, _structural_chapter_count analyzes generic document structure using ATX and Setext patterns.

Practical Implementation Examples

The _chapter_number helper function demonstrates how the regexes extract values from diverse heading formats. Below is a runnable example showing detection across all supported languages:

from book_to_skill.utils import _chapter_number

samples = [
    "Chapter 5: Introduction",               # English explicit

    "I. The Loomings",                        # Roman numeral

    "第 3 章 数据结构",                       # Chinese

    "## บทที่ ๒ การทำงานของระบบ",           # Thai (Markdown prefix)

    "अध्याय 7 प्रोग्रामिंग",                  # Hindi

    "제12장 계약",                             # Korean

    "فصل ۲۲ تحلیل داده‌ها",                    # Persian (Arabic digits)

    "1  Overview of Algorithms",              # Plain numbered (>=2 spaces)

]

for s in samples:
    print(f"{s!r:40} → {_chapter_number(s)}")

Output:

'Chapter 5: Introduction'                → 5
'I. The Loomings'                        → 1
'第 3 章 数据结构'                       → 3
'## บทที่ ๒ การทำงานของระบบ'           → 2

'अध्याय 7 प्रोग्रामिंग'                  → 7
'제12장 계약'                             → 12
'فصل ۲۲ تحلیل داده‌ها'                    → 22
'1  Overview of Algorithms'              → 1

Summary

  • book-to-skill detects chapter headings across nine major categories including English explicit labels, plain numbered sections, Roman numerals, Chinese, Thai, Hindi, Korean, and Persian formats.
  • The core detection engine resides in book_to_skill/utils.py, specifically within detect_structure(), _match_chapter_number(), and language-specific regex constants like _EXPLICIT_CHAPTER, _CN_CHAPTER, and _KO_CHAPTER.
  • Detection requires specific formatting rules, such as at least two spaces after plain numbers, to distinguish chapters from list items.
  • The pipeline uses a four-step process: Kangxi radical normalization, fast numeric scanning, Markdown prefix stripping, and structural fallback.
  • Extensive test coverage in tests/test_book_to_skill.py and tests/test_numbered_headings.py validates each heading style.

Frequently Asked Questions

Can book-to-skill detect chapters in languages not listed in the documentation?

According to the source code in book_to_skill/utils.py, the tool is limited to the specific regex patterns implemented for English, Chinese, Thai, Hindi, Korean, Persian, and Roman numerals. If a language uses a different chapter marker not covered by these patterns, the tool will fall back to structural heading detection or return no chapters. You would need to extend the _match_chapter_number() function with additional regex patterns for unsupported languages.

How does book-to-skill avoid confusing list items with chapter headings?

The plain regex inside _match_chapter_number() specifically requires at least two spaces between a leading Arabic numeral and the following text. This pattern distinguishes true chapter headings like 1 Introduction from numbered list items like 1. Item or 1) Item, which typically use single punctuation without extensive whitespace.

What happens if a document uses both numeric chapters and Markdown headings?

The detection pipeline prioritizes numeric patterns. detect_structure() first calls _match_chapter_number() to identify explicit, Roman, CJK, Thai, Hindi, Korean, or Persian chapter markers. Only when no numeric chapters are found does the system invoke _structural_chapter_count() to count generic Markdown ATX or Setext headings. This ensures that a chapter titled ## Chapter 3 is recognized as chapter 3 via the explicit English pattern rather than being treated as a generic structural heading.

Where are the regex patterns for chapter detection defined?

All chapter-heading regexes are defined as module-level constants in book_to_skill/utils.py. Key patterns include _EXPLICIT_CHAPTER for Western labels, _CN_CHAPTER and _MD_CN_HEADING for Chinese, _TH_CHAPTER for Thai, _HI_CHAPTER for Hindi, _KO_CHAPTER for Korean, and _FA_DIGITS with _fa_chapter_number() for Persian. The structural fallback patterns _ATX_HEADING and _SETEXT_UNDERLINE are also located in this file.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →