# How to Propose a New Category or Subsection for Resources in Free-Programming-Books

> Learn how to propose a new category or subsection for free programming books. Follow our guide to suggest changes to the EbookFoundation/free-programming-books repository easily.

- Repository: [Free Ebook Foundation/free-programming-books](https://github.com/EbookFoundation/free-programming-books)
- Tags: how-to-guide
- Published: 2026-02-23

---

**To propose a new category or subsection in the EbookFoundation/free-programming-books repository, open an issue to discuss the scope, then submit a pull request that adds a level-3 heading (`###`) for categories or level-4 heading (`####`) for subsections in the appropriate language-specific Markdown file, updates the index, and passes the automated linter.**

The **free-programming-books** repository organizes learning resources by language in dedicated Markdown files. When you propose a new category or subsection for resources, you are essentially creating a new document hierarchy that helps users discover content. This guide walks you through the exact process used by maintainers, referencing the actual file structure and validation workflows.

## Understanding Repository Structure and Heading Conventions

Resources live in language-specific files such as [`books/free-programming-books-en.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-en.md) or [`courses/free-courses-en.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/courses/free-courses-en.md). The repository uses **ATX-style Markdown headings** to define hierarchy:

- **Categories** use level-3 headings: `### Category Name`

- **Subsections** use level-4 headings: `#### Subsection Name` nested under an existing category

Each file contains an **index** at the top that links to these headings using Markdown anchors (e.g., `[Category Name](#category-name)`).

## Step-by-Step Process to Propose a New Category or Subsection

Follow this workflow to ensure your proposal aligns with repository standards and passes automated checks.

1. **Open a GitHub issue** describing the proposed category or subsection, its rationale, and 2-3 sample resources. This allows maintainers to discuss scope before you write code.

2. **Fork the repository** and create a feature branch (e.g., `git checkout -b add-data-science-category`).

3. **Edit the appropriate language file** (e.g., [`books/free-programming-books-en.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-en.md)). Add a `###` heading for a top-level category or a `####` heading for a subsection under an existing category.

4. **Insert resources** under your new heading in strict alphabetical order, following the formatting rules defined in [`docs/CONTRIBUTING.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/docs/CONTRIBUTING.md).

5. **Update the file index** at the top of the document. Add a bullet point linking to your new heading using the auto-generated anchor (lowercase, spaces replaced with hyphens).

6. **Run the linter locally** using the `fpb-lint` tool or rely on the GitHub Actions workflow defined in [`.github/workflows/fpb-lint.yml`](https://github.com/EbookFoundation/free-programming-books/blob/main/.github/workflows/fpb-lint.yml) to verify alphabetical ordering and formatting compliance.

7. **Push your branch** and open a Pull Request. Link it to your issue, explain the category's scope, and respond to reviewer feedback until CI passes and the PR is merged.

## Formatting Requirements and Code Examples

### Adding a Top-Level Category

When you propose a new category for resources, use a level-3 heading and maintain alphabetical order within the file:

```markdown

### Data-Science Resources

* [An Introduction to Statistical Learning (PDF)](https://example.com/isl.pdf) - Gareth James, Daniela Witten, Trevor Hastie, Robert Tibshirani (PDF) (CC BY-SA)
* [Python Data Science Handbook (HTML)](https://jakevdp.github.io/PythonDataScienceHandbook/) - Jake VanderPlas (HTML)

```

### Adding a Subsection

For nested organization under an existing category, use a level-4 heading:

```markdown

### Books

#### Deep-Learning

* [Deep Learning (PDF)](https://example.com/deeplearning.pdf) - Ian Goodfellow, Yoshua Bengio, Aaron Courville (PDF) (CC BY-NC-ND)

```

### Updating the File Index

The index at the top of each language file uses Markdown anchors. When you propose a new category or subsection, insert the link in alphabetical order:

```markdown

## Index

* [Artificial-Intelligence](#artificial-intelligence)
* [Data-Science Resources](#data-science-resources)   <!-- new category -->
* [Deep-Learning](#deep-learning)                     <!-- new subsection -->
* [Web-Development](#web-development)

```

## Validation and Linting

The repository enforces strict formatting through **fpb-lint**, a custom linter configured in [`.github/workflows/fpb-lint.yml`](https://github.com/EbookFoundation/free-programming-books/blob/main/.github/workflows/fpb-lint.yml). This tool verifies:

- Alphabetical ordering of entries within each category
- Consistent formatting of resource links (title, URL, author, format tags)
- Valid Markdown structure

Run the linter locally before submitting your pull request, or rely on the GitHub Actions check that triggers automatically on your PR.

## Summary

- **Categories** use `###` headings and **subsections** use `####` headings in language-specific Markdown files like [`books/free-programming-books-en.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-en.md).
- Always **open an issue first** to discuss the scope of your proposed category or subsection for resources.
- Maintain **alphabetical order** for both the index entries and the resource lists within each section.
- Update the **file index** at the top of the document with Markdown anchors linking to your new headings.
- Pass the **fpb-lint** validation defined in [`.github/workflows/fpb-lint.yml`](https://github.com/EbookFoundation/free-programming-books/blob/main/.github/workflows/fpb-lint.yml) before submitting your pull request.

## Frequently Asked Questions

### Do I need to create a new Markdown file to propose a new category?

No. You should add the new category or subsection to an existing language-specific file (e.g., [`books/free-programming-books-en.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-en.md) for English books). Only create a new file if you are adding resources for an entirely new language that does not yet exist in the repository.

### What is the difference between a category and a subsection in the repository?

A **category** is a top-level grouping represented by a level-3 heading (`### Category Name`), such as "Python" or "JavaScript." A **subsection** is a nested grouping under an existing category, represented by a level-4 heading (`#### Subsection Name`), such as "Django" under "Python" or "React" under "JavaScript."

### How do I ensure my proposed category passes the automated checks?

The repository uses **fpb-lint**, configured in [`.github/workflows/fpb-lint.yml`](https://github.com/EbookFoundation/free-programming-books/blob/main/.github/workflows/fpb-lint.yml), to enforce alphabetical ordering and formatting standards. Before submitting your pull request, ensure your resource entries are in strict alphabetical order, follow the link format specified in [`docs/CONTRIBUTING.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/docs/CONTRIBUTING.md), and that you have updated the file index with the correct Markdown anchors.

### Can I propose a category that spans multiple languages?

While the conceptual category might apply to multiple languages (e.g., "Machine Learning"), you must implement it separately in each language-specific file (e.g., [`books/free-programming-books-en.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-en.md), [`books/free-programming-books-es.md`](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-es.md)). Open an issue to coordinate with maintainers if you plan to add the category across many languages simultaneously.