= Pydowndoc

:project-root: .

:!example-caption:
:!table-caption:
:icons: font
:experimental:

:_url-wikipedia: https://wikipedia.org/wiki
:_url-github: https://github.com
:_url-github-wiki: https://docs.github.com
:_url-pypi: https://pypi.org

:url-project-repository: {_url-github}/CarrotManMatt/Pydowndoc
:url-project-pypi: {_url-pypi}/project/Pydowndoc
:url-project-bug-tracker: {url-project-repository}/issues
:url-python-home: https://python.org
:url-python: {url-python-home}
:url-python-download: {url-python-home}/downloads
:url-python-wiki: https://docs.python.org/3
:url-python-wiki-type-annotations: https://typing.python.org/en/latest/spec/annotations.html
:url-python-wiki-virtual-environments: {url-python-wiki}/tutorial/venv
:url-python-wiki-extras: https://packaging.python.org/en/latest/specifications/dependency-specifiers#extras
:url-python-wiki-packaging-supported-readme-formats: https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata-description-content-type
:url-pre-commit-home: https://pre-commit.com
:url-pre-commit: {url-pre-commit-home}
:url-ruff-home: https://ruff.rs
:url-ruff: {url-ruff-home}
:url-mypy-home: https://mypy-lang.org
:url-mypy: {url-mypy-home}
:url-github-wiki-readme: {_url-github-wiki}/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes
:url-downdoc-repository: {_url-github}/opendevise/downdoc
:url-pandoc-home: https://pandoc.org/
:url-pandoc: {url-pandoc-home}
:url-pandoc-markdown: {url-pandoc-home}/MANUAL.html#pandocs-markdown
:url-docbook-home: https://docbook.org
:url-docbook: {url-docbook-home}
:url-multimarkdown-home: https://fletcherpenney.net/multimarkdown
:url-multimarkdown: {url-multimarkdown-home}
:url-php-markdown-extra: https://michelf.ca/projects/php-markdown/extra
:url-wiki-markdown: {_url-wikipedia}/Markdown
:url-wiki-plaintext: {_url-wikipedia}/Plaintext
:url-wiki-restructuredtext: {_url-wikipedia}/ReStructuredText
:url-wiki-docstrings: {_url-wikipedia}/Docstring#Python
:url-wiki-ide: {_url-wikipedia}/Integrated_development_environment
:url-wiki-lsp: {_url-wikipedia}/Language_Server_Protocol
:url-downdoc: {url-downdoc-repository}
:url-asciidoc-home: https://asciidoc.org
:url-asciidoc: {url-asciidoc-home}
:url-asciidoc-asciidoctor: https://asciidoctor.org
:url-pypi-home: {_url-pypi}
:url-pypi: https://pypi.org
:url-hatch-home: https://hatch.pypa.io
:url-hatch: {url-hatch-home}
:url-uv-home: https://astral.sh/uv
:url-uv: {url-uv-home}
:url-uv-wiki: https://docs.astral.sh/uv
:url-uv-wiki-tools: {url-uv-wiki}/guides/tools
:url-uv-wiki-tools-installing: {url-uv-wiki-tools}#installing-tools
:url-uv-wiki-tools-upgrading: {url-uv-wiki-tools}#upgrading-tools
:url-uv-wiki-dependencies-adding: {url-uv-wiki}/concepts/projects#managing-dependencies
:url-pip-home: https://pip.pypa.io
:url-pip: {url-pip-home}

:labelled-url-python: {url-python}[Python]
:labelled-url-downdoc: {url-downdoc}[downdoc]
:labelled-url-pandoc: {url-pandoc}[Pandoc]
:labelled-url-docbook: {url-docbook}[DocBook]
:labelled-url-multimarkdown: {url-multimarkdown}[MultiMarkdown]
:labelled-url-php-markdown-extra: {url-php-markdown-extra}[PHP Markdown Extra]
:labelled-url-asciidoc: {url-asciidoc}[AsciiDoc]
:labelled-url-asciidoc-asciidoctor: {url-asciidoc-asciidoctor}[Asciidoctor]
:labelled-url-wiki-plaintext: {url-wiki-plaintext}[Plaintext]
:labelled-url-wiki-restructuredtext: {url-wiki-restructuredtext}[reStructuredText]
:labelled-url-wiki-markdown: {url-wiki-markdown}[Markdown]
:labelled-url-wiki-readme: {url-github-wiki-readme}[README]
:labelled-url-pypi: {url-pypi}[PyPI]
:labelled-url-hatch: {url-hatch}[Hatch]
:labelled-url-pip: {url-pip}[pip]
:labelled-url-uv: {url-uv}[uv]

image:https://img.shields.io/badge/%F0%9F%A5%95-Pydowndoc-blue[Pydowndoc,link={url-project-repository}]
image:https://img.shields.io/pypi/v/Pydowndoc[PyPI Version,link={url-project-pypi}]
image:https://img.shields.io/pypi/pyversions/Pydowndoc?logo=Python&logoColor=white&label=Python[Python Version,link={url-python-download}]
image:https://img.shields.io/badge/dynamic/yaml?url=https%3A%2F%2Fraw.githubusercontent.com%2FCarrotManMatt%2FPydowndoc%2Fmain%2F.github%2Fworkflows%2Fupload-downdoc-binaries.yaml&query=%24.jobs.upload-downdoc-binaries.steps%5B0%5D.with.ref&label=downdoc&logo=asciidoctor[downdoc Version,link={url-downdoc}]
image:{url-project-repository}/actions/workflows/check-build-publish.yaml/badge.svg[Tests Status,link={url-project-repository}/actions/workflows/check-build-publish.yaml]
image:https://img.shields.io/badge/mypy-checked-%232EBB4E&label=mypy[mypy Status,link={url-mypy}]
image:https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit[pre-commit Status,link={url-pre-commit}]
image:https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json[Ruff,link={url-ruff}]
image:https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json[uv,link={url-uv}]

****
Rapidly convert your {labelled-url-asciidoc} files to {labelled-url-wiki-markdown}, using {labelled-url-python}
****

A {labelled-url-python} wrapper around the latest-built binary of {labelled-url-downdoc}; a rapid {labelled-url-asciidoc} to {labelled-url-wiki-markdown} converter.

== Why Use Pydowndoc?

* Run {labelled-url-downdoc} from the CLI within your {url-python-wiki-virtual-environments}[virtual environment]
* Use {labelled-url-pypi} as the single installation location of your {labelled-url-python} project tooling
* Use link:pass:macros[pydowndoc/__init__.py][the API] to convert files using your own {labelled-url-python} code/scripts
* Use the {labelled-url-hatch} plugin to convert your project's README.adoc file to {labelled-url-wiki-markdown} (or any other {url-python-wiki-packaging-supported-readme-formats}[PyPI supported README format]), when building your package

== Installation

.Run as a {url-uv-wiki-tools}[uv tool] (no installation necessary)
[source,bash]
uvx --from Pydowndoc-bin -- downdoc --version

TIP: uv will warn you that the `+downdoc+` binary is not directly provided by the `+Pydowndoc[bin]+` package, so we suggest to use `+--from Pydowndoc-bin+` when running downdoc using `+uvx+` or `+uv tool+`.

.Add to your {url-uv-wiki-dependencies-adding}[uv project/script's dependencies]
[source,bash]
uv add Pydowndoc[bin]

.{url-uv-wiki-tools-installing}[Install permanently as a uv tool]
[source,bash]
uv tool install Pydowndoc-bin

.Install using {labelled-url-pip} after {url-python-wiki-virtual-environments}[creating a virtual environment]
[source,bash]
path/to/venv/python -m pip install Pydowndoc[bin]

[#installing-the-downdoc-binary]
=== Installing the `downdoc` Binary

Pydowndoc assumes by default that you wish to use the `+downdoc+` binary already installed on your system (E.g. using your system's package manager).
Installing the PyPI package `+Pydowndoc+` will only install the Python compatibility layer for downdoc.

If you wish to _also_ install the `+downdoc+` https://pypi.org/project/Pydowndoc-bin[binary] itself, please install using the `+[bin]+` {url-python-wiki-extras}[extra].

.Installing *without* the `+[bin]+` extra on a system where `+downdoc+` is not already installed will not work
[source,console]
----
$ uvx --with Pydowndoc python -c "import pydowndoc; pydowndoc.get_help()"
OSError: The downdoc executable could not be found. Ensure it is installed (E.g `uv add Pydowndoc[bin]`).
----

NOTE: Once https://peps.python.org/pep-0771[PEP 771] is finalised, the default install will include the `+[bin]+` {url-python-wiki-extras}[extra], and using the `+downdoc+` binary already installed on your system will require opting-out from including the `+[bin]+` {url-python-wiki-extras}[extra].

== CLI Usage

[WARNING]
--
These commands will only work correctly after the `+downdoc+` binary has been installed, either as a system binary or using the `+[bin]+` {url-python-wiki-extras}[extra].
See <<installing-the-downdoc-binary>> for more information.
--

.Display the current version number (useful to validate that installation was successful)
[source,bash]
downdoc --version

.Display the help message
[source,bash]
downdoc --help

.Convert a given file (the same filename will be retained, with file-extension changed to `+.md+`)
[source,bash]
downdoc MyNotes.adoc

.Output the converted file to the given filename & path
[source,bash]
downdoc MyNotes.adoc -o path/to/output.md

.Output the converted file to stdout
[source,bash]
downdoc MyNotes.adoc -o -

.Read the input AsciiDoc file from stdin
[source,bash]
cat MyNotes.adoc | downdoc - -o MyNotes.md

== API Usage

.Convert a given file. (The same filename will be retained, with file-extension changed to `+.md+`)
[source,python]
----
from pathlib import Path

import pydowndoc

pydowndoc.convert_file(Path("MyNotes.adoc"))
----

.Output the converted file to the given location
[source,python]
----
from pathlib import Path

import pydowndoc

pydowndoc.convert_file(Path("MyNotes.adoc"), output_location=Path("path/to/output.md"))
----

.Retrieve the converted file as a string
[source,python]
----
from pathlib import Path

import pydowndoc

converted_file_content: str = pydowndoc.convert_file(
    Path("MyNotes.adoc"), output_location=pydowndoc.OUTPUT_CONVERSION_TO_STRING,
)
----

.Convert an in-memory string
[source,python]
----
from pathlib import Path

import pydowndoc

original_content: str = ...

converted_content: str = pydowndoc.convert_string(original_content)
----

.Use an alternative conversion backend
[source,python]
----
from pathlib import Path

import pydowndoc
from pydowndoc.conversion_backends import PandocMultiMarkdownConversionBackend

pydowndoc.convert_file(Path("MyNotes.adoc"), backend=PandocMultiMarkdownConversionBackend)
----

.Retrieve the version number of the currently installed downdoc executable
[source,python]
----
import pydowndoc

version_string: str = pydowndoc.get_version()
----

TIP: This project includes function {url-wiki-docstrings}[docstrings] and modern {url-python-wiki-type-annotations}[type annotations], allowing you to search for API functionality using your {url-wiki-ide}[IDE] or any program with Python {url-wiki-lsp}[LSP support].

== Use as a Hatch build hook

. Ensure the `+readme+` field is added to your `+project.dynamic+` list within your `+pyproject.toml+` file
+
[source,toml]
----
[project]
name = "my-cool-project"
version = "0.1.0"
dynamic = ["readme"]
----

. Set up your build backend, within your `+pyproject.toml+` file, adding `+Pydowndoc[bin]+` as a build dependency
+
[source,toml]
----
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling", "Pydowndoc[bin]"]
----
+
TIP: To prevent issues with users building your package that may not have the `downdoc` binary already installed on their system, we suggest including the `+[bin]+` {url-python-wiki-extras}[extra] in your package's build dependencies.

. Include the hook name within `[tool.hatch.metadata.hooks]` to enable {labelled-url-wiki-readme}-file conversion
+
--
[source,toml]
----
[tool.hatch.metadata.hooks.downdoc-readme]
----

or

[source,toml]
----
[tool.hatch.metadata.hooks]
downdoc-readme = {}
----
--

.. Using a path to a custom {labelled-url-wiki-readme} file
+
[source,toml]
----
[tool.hatch.metadata.hooks.downdoc-readme]
path = "README2.adoc"
----

.. Using an alternative conversion backend
+
[source,toml]
----
[tool.hatch.metadata.hooks.downdoc-readme]
backend = "pandoc-md-mmd"
----

.A full example of a `+pyproject.toml+` file
[%collapsible]
====
[source,toml]
----
[project]
name = "my-cool-project"
version = "0.1.0"
dynamic = ["readme"]

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling", "Pydowndoc[bin]"]

[tool.hatch.metadata.hooks.downdoc-readme]
path = "README2.adoc"
path = "pandoc-md-mmd"
----
====

=== Configuration Options

[cols="1,1,1,4"]
|===
|Option |Type |Default |Description

|`+path+`
|`+str+`
|`+README.adoc+`
|The location of the AsciiDoc file to be converted to {labelled-url-wiki-markdown} and used as the project's {labelled-url-wiki-readme} file

|`+backend+`
|`+str+`
|`+downdoc-md+`
a|The conversion backend used to convert from AsciiDoc to any other {url-python-wiki-packaging-supported-readme-formats}[PyPI supported README format].

[horizontal]
.Supported Conversion Backends
`+downdoc-md+`:: {labelled-url-wiki-markdown} converted by {labelled-url-downdoc}
`+pandoc-md+`:: {url-pandoc-markdown}[Pandoc's Markdown] converted by {labelled-url-pandoc} & {labelled-url-asciidoc-asciidoctor} (via {labelled-url-docbook})
`+pandoc-multi-md+`:: {labelled-url-multimarkdown} converted by {labelled-url-pandoc} & {labelled-url-asciidoc-asciidoctor} (via {labelled-url-docbook})
`+pandoc-php-md-extra+`:: {labelled-url-php-markdown-extra} converted by {labelled-url-pandoc} & {labelled-url-asciidoc-asciidoctor} (via {labelled-url-docbook})
`+pandoc-txt+`:: {labelled-url-wiki-plaintext} converted by {labelled-url-pandoc} & {labelled-url-asciidoc-asciidoctor} (via {labelled-url-docbook})
`+pandoc-rst+`:: {labelled-url-wiki-restructuredtext} converted by {labelled-url-pandoc} & {labelled-url-asciidoc-asciidoctor} (via {labelled-url-docbook})
|===

== Upgrading

.If {url-uv-wiki-tools-upgrading}[installed as a uv tool]
[source,bash]
uv tool upgrade Pydowndoc-bin

.If added as a {url-uv-wiki-dependencies-adding}[uv project dependency]
[source,bash]
uv sync --upgrade-package Pydowndoc

.If installed using {labelled-url-pip}
[source,bash]
path/to/venv/python -m pip install --upgrade Pydowndoc

== Uninstallation

.If added as a {url-uv-wiki-dependencies-adding}[uv project dependency]
[source,bash]
uv remove Pydowndoc

.If installed as a {url-uv-wiki-tools}[uv tool]
[source,bash]
uv tool uninstall Pydowndoc-bin

.If installed with {labelled-url-pip}
[source,bash]
path/to/venv/python -m pip uninstall Pydowndoc

== Reporting Issues

If there are issues with the Python API for this package, or you are encountering installation problems, please report these on {url-project-bug-tracker}[the GitHub issues tracker for this project].

If you have problems with the conversion process of your AsciiDoc files to Markdown, please report these {url-downdoc-repository}/issues[upstream], directly to the {url-downdoc}[downdoc project].

=== Windows & macOS Wheels

Windows and macOS wheels are provided to enable use of this project on non-linux hosts.
However, these versions have not had the same level of testing as the linux version.
Therefore, if you encounter any bugs with these other versions, report them on {url-project-bug-tracker}[the GitHub issues tracker for this project].

== Licencing

The compiled binary of the distributed downdoc software is shared under the MIT licence as described in {url-downdoc-repository}?tab=MIT-1-ov-file#readme[the upstream project's licence file].

All other code in this project is distrubuted under link:./LICENSE[the Apache-2.0 licence].
