Contributing to Python-Markdown§
The following is a set of guidelines for contributing to Python-Markdown and its extensions, which are hosted in the Python-Markdown Organization on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
Code of Conduct§
This project and everyone participating in it is governed by the Python-Markdown Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to python.markdown@gmail.com.
Project Organization§
The core Python-Markdown code base and any built-in extensions are hosted in the Python-Markdown/markdown project on GitHub. Other extensions maintained by the Python-Markdown project may be hosted as separate repositories in the Python-Markdown Organization on GitHub and must follow best practices for third-party extensions.
The Python-Markdown/markdown project is organized as follows:
- Branch
mastershould generally be stable and release-ready at all times. - Version branches should be used for bug-fixes back-ported to the most recent MICRO release.
- No other branches should be created. Any other branches which exist are preserved for historical reasons only.
Issues§
Feature requests, bug reports, usage questions, and other issues can all be raised on the GitHub issue tracker.
When describing issues try to phrase your ticket in terms of the behavior you think needs to change rather than the code you think needs to change.
Make sure you’re running the latest version of Python-Markdown before reporting an issue.
Search the issue list first for related items. Be sure to check closed issues and pull requests. GitHub’s search only checks open issues by default.
You may want to check the syntax rules and/or Babelmark to confirm that your expectations align with the rules and/or other implementations of Markdown.
If reporting a syntax bug, you must provide the minimal input which exhibits the behavior, the actual output and the output you expected. All three items must be provided as textual code blocks (screen-shots are not helpful). It may also be helpful to point to the syntax rules which specifically address the area of concern.
Feature requests will often be closed with a recommendation that they be implemented as third party extensions outside of the core Python-Markdown library. Keeping new feature requests implemented as third party extensions allows us to keep the maintenance overhead of Python-Markdown to a minimum, so that the focus can be on continued stability, bug fixes, and documentation.
If you intend to submit a fix for your bug or provide an implementation of your feature request, it is not necessary to first open an issue. You can report a bug or make a feature request as part of a pull request. Of course, if you want to receive feedback on how to implement a bug-fix or feature before submitting a solution, then it would be appropriate to open an issue first and ask your questions there.
Having your issue closed does not necessarily mean the end of a discussion. If you believe your issue has been closed incorrectly, explain why and we’ll consider if it needs to be reopened.
Pull Requests§
A pull request often represents the start of a discussion, and does not necessarily need to be the final, finished submission. In fact, if you discover an issue and intend to provide a fix for it, there is no need to open an issue first. You can report the issue and provide the fix together in a pull request.
All pull requests should be made from your personal fork of the library hosted in your personal GitHub account. Do not create branches on the Python-Markdown/markdown project for pull requests. All pull requests should be implemented in a new branch with a unique name. Remember that if you have an outstanding pull request, pushing new commits to the related branch of your GitHub repository will also automatically update the pull request. It may help to review GitHub’s documentation on Creating a pull request from a fork.
If you are providing a fix for a previously reported issue, you must reference
the issue in your commit message. Be sure to prefix the reference with one of
GitHub’s action words which will automatically close the issue when the pull
request is merged. For example, fixes #42 and closes #42 would be
acceptable, whereas ref #42 would not. Of course, if merging a pull request
should not cause an issue to be closed, then the action word should not be
included when referencing that issue.
Before being accepted, each pull request must include the applicable code, new tests of all new features, updated tests for any changed features, documentation updates, and an appropriate update to the changelog. All changes must follow the applicable style guides. Failure to meet any one of the requirements is likely to delay any serious consideration of your pull request and may even cause it to be closed. Of course, if you are in the early stages of development, you may include a note in the pull request acknowledging that it is incomplete along with a request for feedback.
Pull requests will generally not be accepted if any tests are failing. Therefore, it is recommended that you run the tests before submitting your pull request. After making a pull request, check the build status in the GitHub interface to ensure that all tests are running as expected. If any checks fail, you may push additional commits to your branch. GitHub will add those commits to the pull request and rerun the checks.
It is generally best not to squash multiple commits and force-push your changes to a pull request. Instead, the maintainers would like to be able to follow the series of commits along with the discussion about those changes as they progress over time. If your pull request is accepted, it will be squashed at that time if deemed appropriate.
AI Contributions§
Contributions to the Python-Markdown project are welcome, including those developed with the assistance of generative AI tools. However, the use of such tools does not change expectations for contributor responsibility, engagement, or code quality. The following apply to all contributions.
Contributors are responsible for all submitted content, regardless of whether generative AI tools were used.
Contributors must be able to explain all changes upon request during review.
Contributors are responsible for ensuring all submitted code complies with Python-Markdown’s licensing, regardless of whether generative AI tools were used.
The pull request process should be collaborative and iterative. Contributors are expected to actively engage with reviewer feedback themselves. Contributors are expected to understand the changes they are proposing, not act as a message courier for a third party. Copying and pasting replies to / from a generative AI tool does not count as engaging with the reviewer. The use of an AI agent to submit a pull request, issue, or comment autonomously is not permitted.
All contributions must disclose whether AI tools were used or not. Disclosures of AI use must include the specific tools used and what content was generated by the tool, including, but not limited to code, documentation, comments, commit messages, and explanations. Issue and pull request templates must be followed when provided. If a template is ignored or deleted, it will be assumed that an AI agent was used to submit the pull request or issue autonomously and the pull request or issue may be closed immediately.
All code and prose (documentation, commit messages, comments, etc.) must reflect the style and conventions used by the Python-Markdown project (see Code Style Guide, Documentation Style Guide, and Commit Message Style Guide below).
Maintainers may close issues and pull requests that are not useful or productive, regardless of whether AI tools were used or not. If a contributor repeatedly opens unproductive issues or requests, they may be blocked from contributing to the project as it is disruptive and disrespectful of the maintainers’ time.
Info
This policy was largely inspired by the Astropy Project’s Usage of Generative AI policy.
Style Guides§
In an effort to maintain consistency, Python-Markdown adheres to the following style guides in its code and documentation. A pull request may be rejected if it fails to match the relevant style guides.
Code Style Guide§
Except as noted below, all pull requests should follow Python’s standard PEP8 Style Guide and are run through Flake8 to ensure that the style guide is followed.
Legacy code which does not follow the guidelines should only be updated if and when other changes (bug fix, feature addition, etc.) are being made to that section of code. While new features should be given names that follow modern Python naming conventions, existing names should be preserved to avoid backward incompatible changes.
Line length is limited to a maximum of 119 characters.
When a line of code does not fit within the line length limit, continuation lines should align elements wrapped inside parentheses, brackets and braces using a hanging indent. When using a hanging indent there should be no arguments on the first line and further indentation should be used to clearly distinguish itself as a continuation line. The closing parenthesis, bracket or brace should be on a line by itself and should line up under the first character of the line that starts the multi-line construct.
my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
When the conditional part of an if-statement is long enough to require that it
be written across multiple lines, extra indentation should be included on the
conditional continuation line.
Documentation Style Guide§
Documentation should be in American English. The tone of the documentation should be simple, plain, objective and well-balanced where possible.
Keep paragraphs reasonably short.
With the exception of code blocks, limit line length to 79 characters. You may want to use your editor’s tools to automatically hard wrap lines of text.
Don’t use abbreviations such as ‘e.g.’ but instead use the long form, such as ‘For example’.
The documentation is built from the Markdown source files in the
docs directory by the Zensical static site generator.
In addition to the basic Markdown syntax, the following extensions are
supported: abbr, admonition, attr_list, def_list, footnotes,
md_in_html, smarty, toc, mdx_gh_links, pymdownx.blocks.html,
pymdownx.highlight, and pymdownx.superfences.
There are a few conventions you should follow when working on the documentation.
Headers§
Headers should use the hash style. For example:
The underline style should not be used. Don’t do this:
Links§
Links should always use the reference style, with the referenced hyperlinks kept at the end of the document.
Here is a link to [some other thing].
More text...
[some other thing]: http://example.com/other/thing
This style helps keep the documentation source consistent and readable.
If you are linking to another document within Python-Markdown’s documentation,
you should use a relative link, and link to the .md suffix. If applicable, it
is preferred that the link includes a hash fragment pointing to the specific
section of the page. For example:
Linking in this style ensures that the links work when browsing the documentation on GitHub. If your Markdown editor makes links clickable, they will work there as well. When the documentation is built, these links will be converted into regular links which point to the built HTML pages.
When linking to the objects in the API documentation, simply use a reference to the dot path of the Python object. There is no need to define the reference as it is already predefined in a collection of global link references.
Note that as the link label contains code, it should be wrapped in a code span and the reference needs to be defined immediately after. This also allows a long dot path to be truncated for simplicity in the text.
Notes and Warnings§
If you want to draw attention to a note or warning, use the syntax defined in Python-Markdown’s Admonition Extension:
Note
This is the content of the note.
In addition to the supported types listed in Zensical’s documentation, the
seealso type is supported. Unlike the other defined types, seealso needs
the title to be manually defined ("See Also") as the default behavior will
not split a generated title into two words.
See Also
See Zensical’s documentation on supported types for more information.
Code Blocks§
All code blocks should use the fenced code block style and indicate the language of the code contained in the block to ensure proper syntax highlighting.
There are two special types of code blocks which will render output based on the content of the code block. See Rendered Markdown and Rendered Python below. Alternatively, result blocks can be manually constructed.
Rendered Markdown§
If a code block is demonstrating Markdown syntax, it can be assigned the
md-render attribute in place of the language, and both the Markdown source
and HTML output will be rendered in a nested set of code blocks.
The rendered output is generated by an isolated Markdown instance, which is
separate from the body text of the document. Extensions and configuration
options are not carried over. If extension(s) need to be enabled for the code
block, then they can be defined as YAML front-matter within the code block.
The extensions and extension_configs keywords are the only options which
are passed on to the isolated Markdown instance.The YAML front-matter is
stripped from the body of the code block before the code block is passing to
the isolated Markdown instance.
The example below will be rendered with the toc extension and that
extension’s permalinks option enabled.
``` md-render
---
extensions: [toc]
extension_configs:
toc:
permalinks: true
---
# A Markdown header
```
Note that the YAML front-matter must be deliminated by a line of at least three hyphens (both before and after) and be valid YAML. Any invalid formatting or unknown keywords will cause the entire block to not be recognized as a code block. Therefore, be sure to confirm the formatting before submitting proposed changes which utilize rendered code blocks.
If a Markdown code block should not receive the special rendering described
above, then simply assign it the markdown attribute. It will then be
rendered as a normal Markdown code block.
Rendered Python§
If a code block is demonstrating Python code, it can be assigned the
py-render attribute in place of the language, and both the Python code and
output will be rendered in a nested set of code blocks. The language of the
output should be specified using the output-lang attribute.
``` py-render { output-lang='html' }
import markdown
src = 'Some **Markdown** text.'
fragment = markdown.markdown(src)
```
Note that the Python code is executed in an isolated environment. Therefore,
any imports need to be made to avoid errors. However, as all py-render
blocks on the same page are run within the same environment, an import only
needs to be made once (before the first use) for all code blocks on the same
page. Variables assigned in one block will be available in later blocks on the
same page.
In the example below, the variable fragment from the previous code
block is available within this code block. However, JustHTML needs to be
imported as it had not been previously.