Metadata-Version: 2.4
Name: asciidocstring
Version: 0.1.0a6
Summary: A semantic parser and converter for Python docstrings written in AsciiDoc
Project-URL: Homepage, https://pypi.org/project/asciidocstring/
Project-URL: Documentation, https://github.com/webmaven/asciidocstring#readme
Project-URL: Repository, https://github.com/webmaven/asciidocstring
Project-URL: Issues, https://github.com/webmaven/asciidocstring/issues
Project-URL: Changelog, https://github.com/webmaven/asciidocstring/blob/main/CHANGELOG.adoc
Author: webmaven
License-Expression: Apache-2.0
License-File: LICENSE
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.14
Requires-Dist: asciidoctrine>=0.1.0a11
Requires-Dist: lark==1.3.1
Provides-Extra: lint
Requires-Dist: mypy; extra == 'lint'
Requires-Dist: ruff; extra == 'lint'
Provides-Extra: test
Requires-Dist: docutils; extra == 'test'
Requires-Dist: pytest; extra == 'test'
Requires-Dist: pytest-cov; extra == 'test'
Description-Content-Type: text/plain

= AsciiDocstring
:toc: left
:sectnums:
:idprefix:
:idseparator: -

image:https://github.com/webmaven/asciidocstring/actions/workflows/ci.yml/badge.svg[Build Status, link=https://github.com/webmaven/asciidocstring/actions/workflows/ci.yml]
image:https://img.shields.io/pypi/v/asciidocstring.svg[PyPI Version, link=https://pypi.org/project/asciidocstring/]
image:https://img.shields.io/pypi/dm/asciidocstring.svg[PyPI Downloads, link=https://pypi.org/project/asciidocstring/]
image:https://img.shields.io/pypi/pyversions/asciidocstring.svg[Python Versions, link=https://pypi.org/project/asciidocstring/]
image:https://img.shields.io/pypi/l/asciidocstring.svg[License, link=https://github.com/webmaven/asciidocstring/blob/main/LICENSE]
image:https://img.shields.io/badge/coverage-99%25-success[Coverage]
image:https://img.shields.io/badge/code%20style-ruff-000000.svg[Ruff, link=https://github.com/astral-sh/ruff]
image:https://img.shields.io/badge/types-mypy-blue.svg[MyPy, link=https://mypy-lang.org/]
image:https://img.shields.io/badge/Pyodide-WASM%20Ready-6842B2.svg[Pyodide Compatible]

A pure-Python semantic parser, extractor, and translator for Python docstrings written in AsciiDoc. Fully compatible with Python 3.14+ and WASM/Pyodide environments with zero native compiled extensions.

== Key Features

* *Pure Python & WASM/Pyodide Ready*: Zero C-extensions or native binary dependencies.
* *Sphinx Integration*: Converts AsciiDoc docstrings into Sphinx-compatible reStructuredText (reST).
* *Doctest Extraction*: Queries and extracts executable code blocks and interactive prompts (`>>>`).
* *Safe Mode & Graceful Fallbacks*: Emits non-blocking warnings (`AsciiDocStringWarning`) with visual error carets during Sphinx builds instead of crashing.
* *Detailed Diagnostics*: Rich exception reporting with precise line, column, and caret context previews on syntax errors.

== Introduction & Architecture

`asciidocstring` is built on top of the pure-Python https://pypi.org/project/asciidoctrine/[AsciiDoctrine] parser. It is designed to cleanly process Python docstrings written in AsciiDoc, resolve indentation, and parse them into a lossless Abstract Semantic Graph (ASG).

[source,text]
----
                      ┌─────────────────────────┐
                      │ Raw AsciiDoc Docstring  │
                      └────────────┬────────────┘
                                   │
                                   ▼
                      ┌─────────────────────────┐
                      │  asciidocstring.parse() │
                      └────────────┬────────────┘
                                   │
                                   ▼
                      ┌─────────────────────────┐
                      │ Abstract Semantic Graph │
                      └────────────┬────────────┘
                                   │
                 ┌─────────────────┴─────────────────┐
                 ▼                                   ▼
   ┌───────────────────────────┐       ┌───────────────────────────┐
   │       doc.to_rest()       │       │    doc.extract_tests()    │
   └─────────────┬─────────────┘       └─────────────┬─────────────┘
                 │                                   │
                 ▼                                   ▼
   ┌───────────────────────────┐       ┌───────────────────────────┐
   │ Sphinx-Compatible reST    │       │ Executable Doctest Blocks │
   └───────────────────────────┘       └───────────────────────────┘
----

This parsed semantic representation can be used by downstream libraries to:

1. Render high-fidelity, Sphinx-compatible reStructuredText (reST) using https://pypi.org/project/sphinx-asciidoctrine/[Sphinx-AsciiDoctrine].
2. Query and extract executable interactive doctest code blocks using https://pypi.org/project/asciidoctest/[AsciiDoctest].

== Installation

Initialize your project and install the library from https://pypi.org/project/asciidocstring/[PyPI]:

[source,bash]
----
pip install asciidocstring
----

To install optional developer dependencies (testing and linting tools):

[source,bash]
----
pip install "asciidocstring[test,lint]"
----

== Usage

=== Quick Start

[source,python]
----
import asciidocstring

docstring = """
    = Parse Coordinates
    
    This function processes dynamic coordinate objects.
    
    [source,python,test]
    ----
    assert parse_coords(10, 20) == (10, 20)
    ----
    
    x (int):: The horizontal component
    y (int):: The vertical component
    """

# Parse the raw docstring (automatically cleans leading docstring indentation)
doc = asciidocstring.parse(docstring)

# Translate the docstring into reStructuredText (reST) for Sphinx
rest_text = doc.to_rest()
print(rest_text)

# Extract code blocks tagged for doctesting
test_blocks = doc.extract_tests(language="python")
for block in test_blocks:
    print(f"Test Code ({block.language}):")
    print(block.content)
----

=== Translation Comparison (AsciiDoc to reST)

Here is a side-by-side view of how AsciiDoc syntax in a docstring is translated into Sphinx-compatible reStructuredText:

.Input AsciiDoc Docstring
[source,asciidoc]
----
= Parse Coordinates

This function processes dynamic coordinate objects.

NOTE: Coordinates must be non-negative integers.

x (int):: The horizontal component
y (int):: The vertical component
----

.Output reStructuredText (reST)
[source,rst]
----
Parse Coordinates
=================

This function processes dynamic coordinate objects.

.. note::

   Coordinates must be non-negative integers.

x (int)
   The horizontal component

y (int)
   The vertical component
----

=== Catching Syntax and Parsing Errors

The library includes robust, structured syntax error handling. When parsing syntactically invalid AsciiDoc, an `AsciiDocStringParseError` is raised, detailing the exact location and a visual caret context.

[source,python]
----
import asciidocstring

invalid_docstring = """
    = Sample Header
    
    :: invalid-syntax
    """

try:
    asciidocstring.parse(invalid_docstring)
except asciidocstring.AsciiDocStringParseError as e:
    print(f"Error Message: {e}")
    print(f"Error Location: Line {e.line}, Column {e.column}")
    print("Caret Preview:")
    print(e.context)
----

Expected output:

[source,text]
----
Error Message: AsciiDoc Parse Error: Syntax error at line 3, column 1.
:: invalid-syntax
^
Error Location: Line 3, Column 1
Caret Preview:
:: invalid-syntax
^
----

=== Safe Mode Parsing & Warnings

By default, syntax violations raise an exception and halt Sphinx builds. To allow documentation to compile successfully even if a docstring contains syntax errors, you can enable `safe_mode`:

[source,python]
----
import asciidocstring

invalid_docstring = """
    = Sample Header
    
    :: invalid-syntax
    """

# Parse in safe mode (emits a non-blocking AsciiDocStringWarning)
doc = asciidocstring.parse(invalid_docstring, safe_mode=True)

# Generates a standard warning admonition containing the error and careted source
print(doc.to_rest())
----

Output:

[source,text]
----
.. warning::
   Failed to parse AsciiDoc docstring: AsciiDoc Parse Error: Syntax error at line 3, column 1.

   .. code-block:: asciidoc

      = Sample Header
      
      :: invalid-syntax
      ^
----

== API Reference

=== Functions

* `parse(docstring: str, safe_mode: bool = False) -> AsciiDocStringDocument` +
  Convenience function to parse a raw Python docstring.

=== Classes

* `AsciiDocStringDocument` +
  The main interface representing a parsed docstring document.
  ** `__init__(raw_source: str, safe_mode: bool = False)`: Cleans and parses the given docstring.
  ** `to_rest() -> str`: Renders the parsed document as standard Sphinx-compatible reStructuredText.
  ** `extract_tests(language: str = "python", requires_test_marker: bool = False) -> list[TestBlock]`: Extracts executable code blocks.

* `TestBlock` +
  Represents an extracted code block designed for execution or testing.
  ** `content` (str): The raw code contents of the block.
  ** `language` (str): The code block language (e.g. `python`).
  ** `line_number` (int): The 1-based starting line number of the block in the docstring.
  ** `is_interactive` (bool): True if the block contains python-interactive prompts (`>>> `).
  ** `attributes` (dict): A dictionary of raw block attributes parsed from the AsciiDoc metadata.

* `AsciiDocStringParseError` +
  Raised when parsing an AsciiDoc docstring fails. Inherits from `ValueError`.
  ** `line` (int | None): The line number of the parsing error.
  ** `column` (int | None): The column number of the parsing error.
  ** `context` (str | None): A visual text block indicating the line of code and a caret highlighting the syntax error position.

* `AsciiDocStringWarning` +
  Warning raised when parsing fails under `safe_mode=True`. Inherits from `UserWarning`.

== Developer Guide

Ensure you have your environment set up and dependencies installed:

[source,bash]
----
# Set up a virtual environment
python3 -m venv venv
source venv/bin/activate

# Install the package in editable mode with development dependencies
pip install -e ".[test,lint]"
----

=== Running Tests
We maintain 100% test coverage standards. To run tests and generate a coverage report:

[source,bash]
----
PYTHONPATH=src pytest --cov=src --cov-report=term-missing
----

=== Static Analysis
Run our linting and type-safety check pipeline:

[source,bash]
----
# Run Ruff code format and quality checks
ruff check src/ tests/

# Run MyPy type-safety validation
mypy src/
----

== License

This project is licensed under the Apache License, Version 2.0.
