Skip to content

Option for short-form import for interlinks #404

@cliffckerr

Description

@cliffckerr

I'm building docs for a Python package where the classes and methods are implemented as my_module.submodule.MyClass, but the user is expected to interact with them via mm.MyClass (as in, __init__.py has from .submodule import MyClass). quartodoc's aliases feature is great for letting you write mm instead of my_module. But I couldn't find an option that lets you write mm.MyClass and have it be linked correctly.

However, I discovered that it's very easy to manually edit objects.json to provide this functionality: simply duplicate an entry with the shortened name.

Sorry this is in Python rather than Lua, but including it here in case you want to include something like this in future. Usage is to call this function after python -m quartodoc build and before python -m quartodoc interlinks.

import sys
import json
import importlib

def short_aliases(mod_name, json_path='objects.json', verbose=True):
    """ Add short aliases to objects for interlinks

    For example, instead of `my_module.submodule.MyClass`, you can link via
    `my_module.MyClass`, assuming `my_module.MyClass` is valid.

    **Example:**

        python -m quartodoc build
        python -m short_aliases my_module # Use this function
        python -m quartodoc interlinks
        quarto preview
    """
    if verbose:
        print('Shortening aliases ...')
    mod = importlib.import_module(mod_name)
    mod_items = dir(mod)

    # Load the current objects inventory
    with open(json_path, 'r') as f:
        data = json.load(f)
    items = data['items']
    names = [item['name'] for item in items]
    if verbose:
        print(f'  Loaded {len(data["items"])} objects from inventory')

    # Collect duplicates
    dups = []
    for item in items:
        parts = item['name'].split('.')
        if len(parts) < 3 or parts[0] != mod_name:
            continue
        obj_name = parts[2] # e.g. 'MyClass' from my_module.submodule.MyClass
        if obj_name in mod_items:
            remainder = '.'.join(parts[2:])
            alias = f'{mod_name}.{remainder}'
            if alias not in names:
                dup = item.copy()
                dup['name'] = alias
                dups.append(dup)

    # Add them back into the JSON
    items.extend(dups)

    # Save the modified version
    with open(json_path, 'w') as f:
        json.dump(data, f)
    if verbose:
        print(f'  Saved {len(data["items"])} objects to inventory')
    return


if __name__ == '__main__':
    short_aliases(mod_name=sys.argv[1])

(Note: related to https://stackoverflow.com/questions/70598207/sphinx-autodoc-without-submodules)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions