agentsclimarketplace

Fb skill

Skill nikolaygekht/fb2-skill/skills/fb-skill

Manipulate FB2 (FictionBook 2) ebook files: validate against XSD schema, fix structure, reformat XML, repair broken text (split paragraphs, misplaced chapters/notes), compare text content to ensure nothing is lost, convert plain text to FB2, convert FB2 to EPUB, and apply Russian typographic cleanup (a port of the FictionBook Editor script 'Генеральная уборка' / 'general cleanup'). Use this skill whenever the user works with .fb2 files, mentions FictionBook, wants to fix or clean up an ebook, run typographic cleanup ('генеральная уборка'), convert text to FB2 format, or convert FB2 to EPUB -- even if they don't say 'FB2' explicitly but the file extension or context makes it clear.From its SKILL.md

Install
npx -y skills add nikolaygekht/fb2-skill --skill fb-skill

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

15.1 KB, ~3.7k tokens by cl100k_base, as published. Nobody here has run it

FB2 Manipulation Skill

This skill handles all common operations on FB2 (FictionBook 2) ebook files. FB2 is an XML-based format widely used for ebooks, especially in Russian-language publishing.

ZIP Support

All scripts transparently handle ZIP-compressed FB2 files. Pass a .zip or .fb2.zip file anywhere you'd pass a .fb2 file -- the scripts automatically detect the archive, extract the FB2 inside, and process it. If a ZIP contains multiple FB2 files, the first one is used (with a warning).

Setup

The skill bundles Python helper scripts in the scripts/ directory (relative to this SKILL.md). Before running any script, verify that lxml is installed:

python -c "import lxml" 2>/dev/null || pip install lxml

For EPUB conversion, also check:

python -c "import ebooklib" 2>/dev/null || pip install ebooklib

The scripts directory path (referred to as $SCRIPTS below) is the scripts/ subdirectory next to this SKILL.md file.

Operations

1. Validate

Validates an FB2 file against the FB2 2.1 XSD schema and checks internal reference integrity. Supports .fb2, .zip, and .fb2.zip files.

When to use: The user wants to check if an FB2 file is valid, find errors, or assess quality before other operations.

How to do it:

python "$SCRIPTS/validate_fb2.py" path/to/book.fb2

The script checks:

  • XML well-formedness
  • Schema compliance against references/fb21.xsd
  • Internal references: all xlink:href attributes point to existing IDs
  • Image references point to <binary> elements
  • Footnote links (type="note") point to sections in a body named "notes"
  • Non-typed anchor references stay within the same body

Report each issue with its location (line/column where possible) and a clear explanation of what's wrong and how to fix it.

2. Fix Structure

Repairs structural problems found during validation.

When to use: After validation reveals structural issues, or the user asks to "fix" or "clean up" an FB2 file.

How to do it:

  1. First validate the file to get the list of issues.

  2. Read the FB2 file and parse it with lxml.

  3. Apply fixes based on the issues found. Common structural fixes include:

    • Missing required elements: Add missing <lang>, <book-title>, <genre>, <document-info> fields with sensible defaults or values inferred from the content.
    • Empty sections: A <section> must contain either child sections or content elements (<p>, <poem>, etc.). Add an <empty-line/> or merge with a sibling if truly empty.
    • Broken references: Remove <image> or <a> elements that point to non-existent IDs, or fix the href if the target can be identified.
    • Footnotes in wrong body: Move footnote sections to a <body name="notes">, creating that body if it doesn't exist.
    • Duplicate IDs: Rename duplicates by appending a suffix.
  4. After fixing, always run the text comparison (operation 5) to confirm no text was lost:

    python "$SCRIPTS/compare_text.py" original.fb2 fixed.fb2
    
  5. Re-validate the fixed file to confirm all issues are resolved.

Read references/fb2-format.md for the complete element hierarchy and rules when you need to understand what's allowed where.

3. Reformat

Normalizes FB2 XML formatting for readability and consistency.

When to use: The file is valid but messy (no indentation, inconsistent whitespace, wrong encoding declaration).

How to do it:

python "$SCRIPTS/reformat_fb2.py" path/to/book.fb2 -o path/to/reformatted.fb2

The reformatter:

  • Pretty-prints with 2-space indentation
  • Normalizes to UTF-8 encoding
  • Preserves all text content exactly (including significant whitespace in <p>, <v>, inline elements)
  • Keeps <binary> content on a single line (base64 data shouldn't be broken across lines)

After reformatting, run the text comparison to verify nothing changed:

python "$SCRIPTS/compare_text.py" original.fb2 reformatted.fb2

4. Fix Broken Text

Analyzes and repairs text-level problems. Unlike structural fixes, these are judgment calls -- each file has its own issues.

When to use: The user reports problems like broken paragraphs, text appearing in wrong sections, notes mixed into the main body, or garbled content.

How to do it:

Each case is different. Here is the general approach:

  1. Diagnose first. Read the file and understand what's wrong. Common patterns:

    • Split paragraphs: <p>Beginning of sentence</p><p>continuation of the same sentence.</p> -- A paragraph was broken across two <p> elements, usually because the source had hard line breaks. Signs: the second <p> starts with a lowercase letter, or ends a sentence started in the previous <p>.

    • Broken chapters: Sections that should be one chapter are split into multiple <section> elements, or chapter boundaries are in the wrong place. Look at <title> elements to understand the intended structure.

    • Inline footnotes: Note text appears in the main body instead of a separate <body name="notes">. The text may be wrapped in <a type="note"> but the actual note content is nearby instead of in the notes body.

    • OCR artifacts: Garbled characters, systematic substitutions (e.g., "rn" for "m"), broken hyphenation across lines.

  2. Write a targeted fix script. Because each case is unique, write a Python script specific to this file's problems. Use lxml to parse, apply the fixes, and serialize. The script should be saved in the working directory (not in the skill's scripts folder).

  3. Compare before and after. This step is critical -- text manipulation can easily lose content:

    python "$SCRIPTS/compare_text.py" original.fb2 fixed.fb2
    

    Review the diff carefully. The only changes should be the intended fixes (merged paragraphs, moved notes, etc.). Any unexpected text loss means the fix script has a bug.

  4. Validate the result to make sure the fix didn't break the XML structure.

5. Compare Text Content

Extracts pure text from two FB2 files and shows the differences, ensuring no content was lost.

When to use: After any modification to an FB2 file (fixing, reformatting, converting). This is a safety net -- run it after every operation that modifies content.

How to do it:

python "$SCRIPTS/compare_text.py" original.fb2 modified.fb2

The script:

  • Extracts all text content from both files (stripping XML tags but preserving text order)
  • Shows a unified diff of the text
  • Reports whether the text content is identical, or what specifically changed
  • Exits with code 0 if identical, 1 if different

For manual inspection, you can also extract text from a single file:

python "$SCRIPTS/extract_text.py" book.fb2

This prints the pure text content to stdout (one paragraph/element per line).

6. Convert Text to FB2

Creates a well-formed FB2 file from plain text.

When to use: The user has a plain text file (or pasted text) and wants to turn it into a proper FB2 ebook.

How to do it:

  1. Analyze the source text to identify:

    • Title (usually the first line, or the user specifies it)
    • Author (ask the user if not obvious)
    • Chapter boundaries (look for blank lines, "Chapter N" headers, centered/uppercase lines, etc.)
    • Language (detect from content or ask)
  2. Build the FB2 structure using lxml. The minimum valid FB2 needs:

    <?xml version="1.0" encoding="utf-8"?>
    <FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0"
                 xmlns:l="http://www.w3.org/1999/xlink">
      <description>
        <title-info>
          <genre>prose</genre>
          <author><first-name>...</first-name><last-name>...</last-name></author>
          <book-title>...</book-title>
          <lang>...</lang>
        </title-info>
        <document-info>
          <author><nickname>Claude</nickname></author>
          <date>...</date>
          <id>...</id>
          <version>1.0</version>
        </document-info>
      </description>
      <body>
        <title><p>Book Title</p></title>
        <section>
          <title><p>Chapter 1</p></title>
          <p>Text content...</p>
        </section>
      </body>
    </FictionBook>
    
  3. Map text to FB2 elements:

    • Each paragraph becomes a <p> element
    • Blank lines between text blocks indicate paragraph boundaries
    • Chapter headers become <section><title><p>...</p></title> wrappers
    • Poetry (if detected) uses <poem><stanza><v> structure
    • Epigraphs at chapter starts use <epigraph><p> structure
  4. Validate the result using the validate script.

  5. Ask the user to review the metadata (title, author, genre, language) and chapter structure.

Read references/fb2-format.md for the full list of available elements and where they can appear.

7. Convert FB2 to EPUB

Transforms an FB2 file into EPUB format.

When to use: The user wants to read the book on a device/app that supports EPUB but not FB2, or wants an EPUB version.

How to do it:

Write a conversion script using lxml for parsing and ebooklib for EPUB generation. The conversion should:

  1. Parse the FB2 with lxml, extracting:

    • Metadata from <description>: title, authors, language, genre, annotation, cover image
    • Body content: sections, paragraphs, poems, epigraphs, footnotes
    • Binary data: embedded images (base64-decode them)
  2. Create EPUB structure:

    • Set metadata (title, authors, language, identifier, description from annotation)
    • Add cover image if <coverpage> exists
    • Create one XHTML chapter per top-level <section> in the first <body>
    • Map FB2 elements to HTML:
      • <p> -> <p>
      • <strong> -> <strong>
      • <emphasis> -> <em>
      • <strikethrough> -> <del>
      • <sub> -> <sub>, <sup> -> <sup>
      • <code> -> <code>
      • <subtitle> -> <h2> or <h3> depending on nesting depth
      • <title> -> <h1> (section title) or <h2> (subsection)
      • <poem> -> <div class="poem"> with <p class="stanza"> and verse lines as <br/>-separated text
      • <cite> -> <blockquote>
      • <epigraph> -> <div class="epigraph">
      • <empty-line/> -> <br/>
      • <image> -> <img> with the decoded binary as the source
      • <table> -> <table> (direct mapping, attributes carry over)
      • <a> links -> <a href> links (rewrite internal #refs to point to correct chapter files)
    • Create footnotes chapter from <body name="notes"> if present
    • Generate table of contents from section titles
    • Add basic CSS for readability
  3. Verify the conversion by extracting text from both and comparing:

    python "$SCRIPTS/extract_text.py" original.fb2 > /tmp/fb2_text.txt
    # Then compare with text extracted from the EPUB
    

8. Typographic Cleanup ("Generalnaya uborka")

Applies Russian typographic cleanup rules to every paragraph of an FB2 file. This is a Python port of the well-known FictionBook Editor (FBE) script "Генеральная уборка" (literally "general cleanup" / "spring cleaning") by Sclex, faithful to version 2.2.

When to use: The user wants to tidy up the typography of an FB2 book -- fix dashes, ellipses, non-breaking spaces, spacing around punctuation, etc. Especially for Russian-language books converted from other formats or scanned. Recognize requests like "генеральная уборка", "почистить типографику", "typographic cleanup".

What it does (per paragraph <p>, verse <v>, <subtitle>, <text-author>, table cells; also annotation and history):

  • hyphen / short dash -> em dash (including leading dialogue dash with a non-breaking space)
  • ... -> , !… -> !.., collapses doubled dashes/punctuation
  • inserts non-breaking spaces after list numbers, /§, units of measure, Рис., т. д./н. э., page numbers
  • shortens date/roman-numeral ranges, normalizes degrees (°, °C, °′″)
  • fixes missing/extra spaces around dashes, quotes, colons; trims leading/trailing spaces; removes soft hyphens and junk ()
  • removes trailing dots in titles (with exceptions like 1980 г., XXI в., -мл.)
  • removes junk ids (AutBody_…)

As in the original v2.2, footnote and quotation-mark rules are not applied (they were commented out in the source; dedicated scripts handle those). Inline elements other than emphasis/strong (links <a>, <sub>, <sup>, <code>, <image>, …) are preserved untouched.

Note — one deliberate deviation from the original: the Celsius rule no longer treats a bare 0 as a degree sign, because the original would corrupt model names / numbers (e.g. МК5000С -> МК500 °C). Everything else matches the FBE script.

How to do it:

python "$SCRIPTS/cleanup_fb2.py" path/to/book.fb2 [more.fb2 | dir | *.zip ...] [-o OUTDIR] [--inplace] [-q]
  • Without -o/--inplace, writes <name>.clean.fb2 next to the input.
  • --inplace overwrites .fb2 files in place; -o OUTDIR writes results to a directory.
  • Accepts .fb2, .zip/.fb2.zip, and directories (all FB2 inside are processed).
  • Prints per-file and total statistics (same categories as the original's message box).

This operation intentionally changes text (that is its purpose), so a plain compare_text.py will show the typographic diffs. To confirm no content was lost, compare the alphanumeric characters only -- they must be identical before and after:

python - <<'PY'
import re
from lxml import etree
def letters(p):
    r = etree.parse(p).getroot()
    return re.sub(r'[^0-9A-Za-zА-Яа-яЁё]', '', "".join(r.itertext()))
print("identical" if letters("before.fb2") == letters("after.fb2") else "CONTENT CHANGED")
PY

Also re-validate (operation 1) afterwards and confirm footnote links still resolve.

Important: Text Integrity

The golden rule for all FB2 operations: no text may be lost. After every operation that produces a modified file, run the text comparison:

python "$SCRIPTS/compare_text.py" before.fb2 after.fb2

If the diff shows unexpected changes, investigate before delivering the result. The user trusts that their book content is preserved.

Reference Materials

  • references/fb2-format.md -- Complete FB2 format specification: element hierarchy, what goes where, attribute details. Read this when you need to understand the schema rules for a specific element.
  • references/fb21.xsd -- The official FB2 2.1 XSD schema file. Used by the validation script.

What ships with it: 9 files

104.1 KB alongside SKILL.md, 6 of them executable

references/

scripts/

Keep looking

Skills are one crate of 326,512. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.