rust-lang / mdBook

Create book from markdown files. Like Gitbook but implemented in Rust
https://rust-lang.github.io/mdBook/
Mozilla Public License 2.0
17.84k stars 1.62k forks source link

Is there a way to divide SUMMARY.md into sections, each with their own preliminary, main, and concluding chapters? #2428

Closed ksd3 closed 1 month ago

ksd3 commented 1 month ago

Question

Basically what the title says. Is there a way to format SUMMARY.md in the following way:

# Summary (ignored by mdbook)

[Compendium Introduction](./intro.md)

# Book 1 of Compendium

[Introduction of Book One](./introbook1.md)

- [Chapter 1 of Book One](./chapter1book1.md)

[Concluding Chapter of Book One]

# Book 2 of Compendium

and so on?

If not, are there any workarounds?

Version

mdbook v0.4.40
ksd3 commented 1 month ago

Found somewhat of a solution: This is a common problem with all markdown-based book generators (even Quatro has it) that the chapter numbering is drawn from Markdown's #toc - so it's hardcoded and can't easily be changed. A workaround would be to have numbering as follows:

Preliminary Chapter

Preliminary Chapter

Section 1

Section 1 Chapter 1 (1. Chapter 1)

Section 1 Chapter 2 (2. Chapter 2)

Section 1 Subchapter 1 (2.1. Chapter 2.1)

Section 2

Section 2 Chapter 1 (1. Chapter 1)

. .

Final Chapter

This is specifically because it is ambiguous to specify what the suffix chapter would be for a section (if its a nested chapter then it should have an index, rather than no index at all), so this format looks better.

The solution is to add a function at the bottom of the book.js file

(function customizeChapterNumbers() {
    function resetChapterNumbers() {
        const sidebar = document.querySelector('#sidebar .sidebar-scrollbox');
        if (!sidebar) {
            console.log('Sidebar not found.');
            return;
        }

        let chapterCounter = 0;  // Counter for main chapters
        let subChapterCounter = 0;  // Counter for subchapters

        sidebar.querySelectorAll('ol.chapter > li').forEach((item) => {
            const partTitle = item.classList.contains('part-title');
            const chapterLink = item.querySelector('a');

            if (partTitle) {
                // Reset chapter counter for each new section
                chapterCounter = 0;
                console.log(`New section found: ${item.textContent.trim()}, resetting chapter counter.`);
            } else if (chapterLink) {
                // Determine if it's a main chapter or a subchapter
                const isSubChapter = item.querySelector('ol.section');

                if (!isSubChapter) {
                    // It's a main chapter
                    chapterCounter++;    // Increment main chapter counter
                    subChapterCounter = 0;  // Reset subchapter counter for each new chapter
                    const chapterNumber = `${chapterCounter}`;
                    const strongElem = chapterLink.querySelector('strong');
                    if (strongElem) {
                        console.log(`Setting chapter number: ${chapterNumber} for chapter ${chapterLink.textContent.trim()}`);
                        strongElem.textContent = `${chapterNumber}. `;
                    }
                } else {
                    // It's a subchapter
                    subChapterCounter++;
                    const chapterNumber = `${chapterCounter}`;
                    const subChapterNumber = `${chapterNumber}.${subChapterCounter}`;
                    const strongElem = chapterLink.querySelector('strong');
                    if (strongElem) {
                        console.log(`Setting subchapter number: ${subChapterNumber} for chapter ${chapterLink.textContent.trim()}`);
                        strongElem.textContent = `${subChapterNumber}. `;
                    }
                }
            }
        });
    }

    document.addEventListener('DOMContentLoaded', resetChapterNumbers);
})();

This generates chapter numbers according to the above scheme. This issue's name should now be changed to something like 'Reset Chapter Numbering', but I'm leaving these keywords in in the hope that someone encountering this problem finds this solution in the future.

zerone0x commented 3 weeks ago

I sometimes think maybe number is redundant...