summaryrefslogtreecommitdiffstats
path: root/docs/contributing.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/contributing.md')
-rw-r--r--docs/contributing.md108
1 files changed, 108 insertions, 0 deletions
diff --git a/docs/contributing.md b/docs/contributing.md
new file mode 100644
index 0000000..6c43e0e
--- /dev/null
+++ b/docs/contributing.md
@@ -0,0 +1,108 @@
+# Contribute to markdown-it-py
+
+We welcome all contributions! ✨
+
+See the [EBP Contributing Guide](https://executablebooks.org/en/latest/contributing.html) for general details, and below for guidance specific to markdown-it-py.
+
+Before continuing, make sure you've read:
+
+1. [Architecture description](md/architecture)
+2. [Security considerations](md/security)
+3. [API documentation](api/markdown_it)
+
+## Development guidance
+
+Details of the port can be found in the `markdown_it/port.yaml` and in `port.yaml` files, within the extension folders.
+
+## Code Style
+
+Code style is tested using [flake8](http://flake8.pycqa.org), with the configuration set in `.flake8`, and code formatted with [black](https://github.com/ambv/black).
+
+Installing with `markdown-it-py[code_style]` makes the [pre-commit](https://pre-commit.com/) package available, which will ensure this style is met before commits are submitted, by reformatting the code and testing for lint errors.
+It can be setup by:
+
+```shell
+>> cd markdown-it-py
+>> pre-commit install
+```
+
+Editors like VS Code also have automatic code reformat utilities, which can adhere to this standard.
+
+All functions and class methods should be annotated with types and include a docstring.
+
+## Testing
+
+For code tests, markdown-it-py uses [pytest](https://docs.pytest.org)):
+
+```shell
+>> cd markdown-it-py
+>> pytest
+```
+
+You can also use [tox](https://tox.readthedocs.io), to run the tests in multiple isolated environments (see the `tox.ini` file for available test environments):
+
+```shell
+>> cd markdown-it-py
+>> tox -p
+```
+
+This can also be used to run benchmarking tests using [pytest-benchmark](https://pytest-benchmark.readthedocs.io):
+
+```shell
+>> cd markdown-it-py
+tox -e py38-bench-packages -- --benchmark-min-rounds 50
+```
+
+For documentation build tests:
+
+```shell
+>> cd markdown-it-py/docs
+>> make clean
+>> make html-strict
+```
+
+## Contributing a plugin
+
+1. Does it already exist as JavaScript implementation ([see npm](https://www.npmjs.com/search?q=keywords:markdown-it-plugin))?
+ Where possible try to port directly from that.
+ It is usually better to modify existing code, instead of writing all from scratch.
+2. Try to find the right place for your plugin rule:
+ - Will it conflict with existing markup (by priority)?
+ - If yes - you need to write an inline or block rule.
+ - If no - you can morph tokens within core chains.
+ - Remember that token morphing in core chains is always more simple than writing
+ block or inline rules, if you don't copy existing ones. However,
+ block and inline rules are usually faster.
+ - Sometimes, it's enough to only modify the renderer, for example, to add
+ header IDs or `target="_blank"` for the links.
+
+## FAQ
+
+### I need async rule, how to do it?
+
+Sorry. You can't do it directly. All complex parsers are sync by nature. But you
+can use workarounds:
+
+1. On parse phase, replace content by random number and store it in `env`.
+2. Do async processing over collected data.
+3. Render content and replace those random numbers with text; or replace first, then render.
+
+Alternatively, you can render HTML, then parse it to DOM, or
+[cheerio](https://github.com/cheeriojs/cheerio) AST, and apply transformations
+in a more convenient way.
+
+### How to replace part of text token with link?
+
+The right sequence is to split text to several tokens and add link tokens in between.
+The result will be: `text` + `link_open` + `text` + `link_close` + `text`.
+
+See implementations of [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js) and [emoji](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/replace.js) - those do text token splits.
+
+__Note:__ Don't try to replace text with HTML markup! That's not secure.
+
+### Why is my inline rule not executed?
+
+The inline parser skips pieces of texts to optimize speed. It stops only on [a small set of chars](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_inline/text.js), which can be tokens. We did not made this list extensible for performance reasons too.
+
+If you are absolutely sure that something important is missing there - create a
+ticket and we will consider adding it as a new charcode.