# How Book-to-Skill Determines BOOK_TYPE for Documents: Extension-Based Parser Selection

> Discover how Book-to-Skill identifies BOOK_TYPE using extension mapping. Learn about parser selection and handling unknown document formats.

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

---

**Book-to-Skill determines the BOOK_TYPE by mapping file extensions to specific parser classes via the `EXTENSION_MAP` dictionary in [`book_to_skill/parsers/__init__.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/__init__.py), falling back to a generic text parser for unrecognized formats.**

Book-to-Skill is an open-source Python library that extracts raw text from documents to support skill analysis workflows. To handle diverse formats—from PDFs to EPUBs—it implements a deterministic extension-based detection system that selects the appropriate parser class for each input file based on the `BOOK_TYPE` determination logic.

## The Extension-Based Detection Logic

The core detection mechanism resides in [`book_to_skill/parsers/__init__.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/__init__.py) within the `detect_booktype()` function. This helper normalizes the input filename by converting it to lowercase and stripping any trailing query strings, then performs a dictionary lookup against `EXTENSION_MAP`.

Each key in `EXTENSION_MAP` represents a file extension (e.g., `.pdf`, `.epub`) mapped to a concrete parser class implementing the `DocumentParser` interface. When the extension matches, the corresponding parser class is returned; otherwise, the system defaults to a generic plain-text parser to ensure robust operation.

## Supported Document Types and Their Parsers

Book-to-Skill supports seven major document categories through dedicated parser modules located in the `book_to_skill/parsers/` directory:

- **`.txt`** → `TextParser` ([`book_to_skill/parsers/text.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/text.py))
- **`.pdf`** → `PdfParser` ([`book_to_skill/parsers/pdf.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/pdf.py))
- **`.html` / `.htm`** → `HtmlParser` ([`book_to_skill/parsers/html.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/html.py))
- **`.rtf`** → `RtfParser` ([`book_to_skill/parsers/rtf.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/rtf.py))
- **`.epub`** → `EpubParser` ([`book_to_skill/parsers/epub.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/epub.py))
- **`.docx`** → `DocxParser` ([`book_to_skill/parsers/docx.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/docx.py))
- **`.cbz`, `.cbr` (Calibre)** → `CalibreParser` ([`book_to_skill/parsers/calibre.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/calibre.py))

This modular architecture isolates format-specific extraction logic, making the `BOOK_TYPE` determination both predictable and maintainable across the codebase.

## The Detection Pipeline in Action

When the CLI driver in [`book_to_skill/cli.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/cli.py) receives an input path, it executes a three-step detection workflow:

1. **Normalization**: The filename is lowercased and trailing query strings are removed to ensure consistent matching.
2. **Lookup**: The extension is checked against `EXTENSION_MAP` in [`book_to_skill/parsers/__init__.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/__init__.py).
3. **Instantiation**: The selected parser class is instantiated and its `extract_text()` method is invoked to retrieve raw content from the source document.

### Direct API Usage

You can programmatically access the `BOOK_TYPE` detection logic in your own scripts:

```python
from book_to_skill.parsers import detect_booktype

path = "/path/to/my_book.pdf"
ParserClass = detect_booktype(path)   # Returns PdfParser class

parser = ParserClass(path)
text = parser.extract_text()
print(text[:200])   # Preview first 200 characters

```

### CLI Invocation

The same detection logic runs automatically via command line:

```bash
python -m book_to_skill extract /path/to/my_book.epub

```

Internally, this calls `detect_booktype()` to return `EpubParser`, then processes the document without requiring manual `BOOK_TYPE` specification.

## Extending BOOK_TYPE Detection

The mapping system is intentionally extensible for custom formats. To add support for a new document type, subclass `DocumentParser` and register the extension in `EXTENSION_MAP`:

```python
from book_to_skill.parsers.base import DocumentParser
from book_to_skill.parsers import EXTENSION_MAP

class MySpecialParser(DocumentParser):
    def extract_text(self):
        # Implementation-specific extraction logic

        return "extracted content"

# Register the new BOOK_TYPE mapping

EXTENSION_MAP[".myspecial"] = MySpecialParser

```

After registration, `detect_booktype("file.myspecial")` returns `MySpecialParser`, seamlessly integrating your custom format into the existing pipeline.

## Summary

- Book-to-Skill determines `BOOK_TYPE` via file extension analysis centralized in [`book_to_skill/parsers/__init__.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/__init__.py).
- The `detect_booktype()` function normalizes filenames and queries the `EXTENSION_MAP` dictionary to select the appropriate parser.
- Seven built-in parsers handle formats from `.txt` to `.epub` via the shared `DocumentParser` interface.
- Unknown extensions fall back to a generic plain-text parser rather than raising fatal errors.
- Developers can extend detection by adding custom entries to `EXTENSION_MAP` at runtime or in the source code.

## Frequently Asked Questions

### What happens if Book-to-Skill encounters an unknown file extension?

If the extension is not found in `EXTENSION_MAP`, the system gracefully falls back to a generic plain-text parser rather than raising an error. This ensures robust processing while still attempting text extraction from the file.

### Where is the BOOK_TYPE detection logic implemented in the source code?

The primary logic resides in [`book_to_skill/parsers/__init__.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/__init__.py), specifically within the `detect_booktype()` function and the `EXTENSION_MAP` dictionary. The CLI driver in [`book_to_skill/cli.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/cli.py) invokes this logic when processing input arguments.

### Can I add support for custom document formats?

Yes. Subclass `DocumentParser` from `book_to_skill/parsers.base`, implement the required `extract_text()` method, and register your extension in `EXTENSION_MAP` within [`book_to_skill/parsers/__init__.py`](https://github.com/virgiliojr94/book-to-skill/blob/main/book_to_skill/parsers/__init__.py) or at runtime in your application code before calling `detect_booktype()`.

### How does the CLI use BOOK_TYPE detection?

The CLI calls `detect_booktype()` immediately after receiving the input path. It instantiates the returned parser class and executes `extract_text()` to convert the document content, making the `BOOK_TYPE` determination transparent to end users while maintaining strict consistency with programmatic API usage.