# Book-to-Skill Chapter Detection Methods: Numeric and Structural Analysis

> Discover Book-to-Skill chapter detection methods. Explore numeric and structural analysis, including multilingual markers and Markdown/AsciiDoc heading support for precise chapter identification.

- Repository: [Virgilio Junior/book-to-skill](https://github.com/virgiliojr94/book-to-skill)
- Tags: deep-dive
- Published: 2026-08-31

---

**Book-to-Skill determines document chapters through a two-stage strategy that first scans for explicit multilingual chapter markers, then falls back to structural Markdown and AsciiDoc heading analysis when numeric indicators are insufficient.**

Book-to-Skill is an open-source tool designed to extract skill taxonomies from technical books and documentation. Accurate **chapter detection** is fundamental to segmenting source documents for downstream processing, and the library implements a robust dual-method approach in [`book_to_skill/utils.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/utils.py) to handle diverse document formats and languages.

## Two-Stage Detection Strategy

The detection pipeline is orchestrated by `detect_structure()`, which sequentially evaluates content through two specialized methods. According to the Book-to-Skill source code, the system prioritizes explicit chapter numbering before resorting to structural document analysis. This approach ensures high accuracy across both formally structured textbooks and loosely organized technical documentation.

### Primary Method: Numeric Detection

The first stage relies on `_chapter_number()` (lines 78-90 of [`book_to_skill/utils.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/utils.py)) to identify explicit chapter markers. This function implements a comprehensive regex-based scanner that recognizes chapter declarations in multiple languages and numbering systems.

**Multilingual Pattern Matching**

The numeric detection system supports explicit chapter markers in English, Spanish, French, German, Italian, Dutch, Vietnamese, Chinese, Thai, Hindi, Bengali, Korean, and Persian. It distinguishes between Arabic numerals (1, 2, 3) and Roman numerals (I, II, III) while ensuring matched lines represent actual headings rather than prose references.

**Regex Pattern Definitions**

The detection rules leverage specialized regex patterns defined between lines 103-173:

- `_EXPLICIT_CHAPTER`: Captures standard "Chapter N" constructs
- `_ROMAN_HEAD`: Identifies Roman numeral prefixes
- `_CN_CHAPTER`, `_TH_CHAPTER`, `_HI_CHAPTER`, `_BN_CHAPTER`, `_KO_CHAPTER`: Language-specific patterns for CJK and Indic scripts

When `detect_structure()` collects **two or more** distinct chapter numbers, it immediately returns the **numeric** method classification along with the detected count.

### Fallback Method: Structural Detection

If numeric detection yields fewer than two chapters, the system invokes `_structural_chapter_count()` as a fallback mechanism.

**Markdown and AsciiDoc Analysis**

This method parses multiple heading syntaxes including ATX style (`# Title`, `## Section`), Setext underlines (`===`, `---`), and RST conventions. The logic specifically filters out headings appearing inside fenced code blocks to prevent false positives from commented code examples.

**Validating Numbered Titles**

The helper `_numbered_titles_are_structural()` (lines 61-71) validates whether digit-led headings represent genuine structural divisions. It requires that numbered titles form a systematic, sufficiently long series before accepting them as chapter indicators. The algorithm selects the shallowest heading depth containing at least two distinct titles to determine the chapter level.

## Decision Logic in detect_structure()

The `detect_structure()` function (lines 108-150) implements the final arbitration logic:

1. Scan every line using `_chapter_number()` to gather distinct numbers
2. If **numeric_count ≥ 2**: Set `chapters_method = "numeric"` and return that count
3. Otherwise: Compute `structural_count = _structural_chapter_count(text)`
4. Return the larger count, reporting `"structural"` when structural dominates, `"numeric"` for single matches, or `"none"` when no chapters are found

## Implementation Examples

```python
from book_to_skill.utils import detect_structure

# Example with explicit English chapter headings

text_with_chapters = """

# My Book Title

## Chapter 1: Introduction

Content here...

## Chapter 2: Getting Started

More content...
"""

result = detect_structure(text_with_chapters)
print(result["chapters_detected"])  # → 2

print(result["chapters_method"])   # → "numeric"

```

For documents without explicit chapter markers:

```python

# Structural detection via Markdown headings

text_with_headings = """

# Guide Title

## Part One

Content...

## Part Two

More content...
"""

result = detect_structure(text_with_headings)
print(result["chapters_detected"])  # → 2

print(result["chapters_method"])   # → "structural"

```

## Summary

- Book-to-Skill uses a **two-stage priority system** where numeric detection takes precedence over structural analysis
- The **numeric method** supports 12+ languages via specialized regex patterns in `_chapter_number()`
- The **structural method** analyzes Markdown/AsciiDoc heading depth while excluding fenced code blocks
- The `detect_structure()` function in [`book_to_skill/utils.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/utils.py) coordinates both methods and reports methodology via `chapters_method`

## Frequently Asked Questions

### What languages does the numeric chapter detection support?

The `_chapter_number()` implementation recognizes explicit chapter markers in English, Spanish, French, German, Italian, Dutch, Vietnamese, Chinese, Thai, Hindi, Bengali, Korean, and Persian. It handles both Arabic and Roman numerals through dedicated regex patterns defined in [`book_to_skill/utils.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/utils.py).

### How does Book-to-Skill handle code blocks when detecting structural chapters?

The `_structural_chapter_count()` function specifically ignores headings inside closed fenced code blocks (delimited by triple backticks or tildes) to prevent code comments from being mistaken for document structure. This filtering ensures that only genuine document headings contribute to the chapter count.

### When does the system fallback from numeric to structural detection?

Fallback occurs when `detect_structure()` finds fewer than two distinct numeric chapter indicators. If `_chapter_number()` identifies zero or one chapter number, the system automatically invokes `_structural_chapter_count()` to analyze heading hierarchy and determine if structural chapters exist.

### Where is the chapter detection logic implemented in the codebase?

All chapter detection functionality resides in [`book_to_skill/utils.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/utils.py), specifically within the `detect_structure()` orchestrator function and its helper functions `_chapter_number()` and `_structural_chapter_count()`. Unit tests verifying these methods are located in [`tests/test_chapter_method_reported.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/tests/test_chapter_method_reported.py) and [`tests/test_structural_chapter_count.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/tests/test_structural_chapter_count.py).