Skip to content

documentation as software and data¤

computational literature like documentation is presented with antithetical distribution practices like static sites and pdf. the idea of static computational literature pushes against its real potential to give visitors agency over their content. we see developments towards more interactive computational literature with projects like jupyterlite, pyodide, and pyscript. these approaches providing slightly more agency to interact with code, but this is only part of the interaction we could imagine.

documentation is valuable when people spend time with it. different folks might find different parts of documentation valuable as different places in their career. documentation has less to do with aesthetics than with spending quality time learning and practicing. a significant part of the documentation experience is how much time your audience is willing to put into participating.

the most interactive way to enjoy information is in computational notebooks. if we can capture documentation as data we can expose multitudes of interaction capabilities than statically generated sites anca acheive.

the following presents that concept of nobook which treats documentation as data. it lets the learners discover the documentation they desire. i imagine it could make better chat assistants if you are into that kind of thing.

beyond individual documentation¤

a key success criterion for this is approach is that we ought to be able to operate on multiple documentations at once and reuse existing configurations when possible.

    (shell := get_ipython()).execution_count > 2 and shell.reset(1,1)
    import nbconvert_a11y.builder
    def md(frame): display({"text/markdown": "\n".join(frame)}, raw=True)   
    import midgy

build my personal blog¤

a goal is to build multiple sites at once. the first we build is my personal blog. i do a lot of weird shit in documents so my works are a good stress tests.

    docs = nbconvert_a11y.builder.Contents.Config.new(
        root="../../", 
        include=["**/[0-9][0-9][0-9][0-9]-*.ipynb"],
        exclude=""".ipynb_checkpoints\n../../site/run""")
    docs = (await docs.discover()).head(20)
    tfast = docs = await (await docs.expand()).compact()
    docs.head(2)
sha contents target prev next env title header footer html
file
../../tonyfast/2023-01-19-.ipynb 41912b030a8834f41adb70586dbec6316351d4cc554f97... {'cells': [{'cell_type': 'code', 'execution_co... site/draft/tonyfast/2023-01-19-.html ../../tonyfast/2023-02-05-.ipynb None {} None <details><summary id="docs-nav">site navigatio... <a href="2023-02-05-.html" rel="prev><span ari... <!DOCTYPE html>\n<html lang="en">\n <head>\n ...
../../tonyfast/2023-02-05-.ipynb aabc765a7000f4c6ce30b7ae24bbec4c39763001e74e17... {'cells': [{'cell_type': 'markdown', 'id': '95... site/draft/tonyfast/2023-02-05-.html ../../tonyfast/2023-02-05-pipings.ipynb ../../tonyfast/2023-01-19-.ipynb {} pipes are common sugar <details><summary id="docs-nav">site navigatio... <a href="2023-02-05-pipings.html" rel="prev><s... <!DOCTYPE html>\n<html lang="en">\n <head>\n ...

build the mast space telescope notebooks¤

https://spacetelescope.github.io/mast_notebooks/

    docs = nbconvert_a11y.builder.Contents.Config.new(
        root="mast_notebooks/", toc="_toc.yml",
        kind=nbconvert_a11y.builder.ConfigKind.jb)
    docs = (await docs.discover()).head()
    docs = await (await docs.expand()).compact()
    docs.head(2)
sha contents target prev next env title header footer html
file
mast_notebooks/notebooks/astrocut/making_tess_cubes_and_cutouts/making_tess_cubes_and_cutouts.ipynb 8d65898c978df06639c293d370c7269f32db06134515c6... {'cells': [{'cell_type': 'markdown', 'metadata... site/draft/notebooks/astrocut/making_tess_cube... mast_notebooks/notebooks/astroquery/intro.md None {} Generating Cubes and Cutouts from TESS FFIs <details><summary id="docs-nav">site navigatio... <a href="../astroquery/intro.html" rel="prev><... <!DOCTYPE html>\n<html lang="en">\n <head>\n ...
mast_notebooks/notebooks/astroquery/intro.md cf38ab12e848f5bd27b698f3c6983d78d7630f3b73df79... {'nbformat': 4, 'nbformat_minor': 5, 'metadata... site/draft/notebooks/astroquery/intro.html mast_notebooks/notebooks/astroquery/beginner_s... mast_notebooks/notebooks/astrocut/making_tess_... {} Intro <details><summary id="docs-nav">site navigatio... <a href="../beginner_search/beginner_search.ht... <!DOCTYPE html>\n<html lang="en">\n <head>\n ...

manipulating the documentation¤

we'll use the dataframes from our previous cells to demonstrate what we can do with documentation frames.

%%
### preview a webpage

    tfast.html.tail(2).display.iframe().display()

preview a webpage¤

tfast.html.tail(2).display.iframe().display()
%%
### how many cells?

    tfast.cells.cell_type.value_counts().to_frame().T

how many cells?¤

tfast.cells.cell_type.value_counts().to_frame().T
cell_type code markdown
count 138 115
%%
### search cell contents

find all the cells containing a reference to pandas.

    tfast.cells[tfast.cells.source.str.contains("pandas")][["source"]].sample(6)

we can invoke more complicated regular expressions to extract information.

search cell contents¤

find all the cells containing a reference to pandas.

tfast.cells[tfast.cells.source.str.contains("pandas")][["source"]].sample(6)

we can invoke more complicated regular expressions to extract information.

%%
### what markdown intermediates can we access?

#### access markdown referneces across documents

markdown provides syntax for link references. these values return from markdown parsing 
as structured data, and we'll show some really good information in there.

    refs = tfast["env"].series().dropna()["references"].apply(dict.values).explode().series()        
    refs.apply(
        lambda x: F"* [{x.title or x.href}]({x.href})", axis=1
    ).pipe(md)

what markdown intermediates can we access?¤

access markdown referneces across documents¤

markdown provides syntax for link references. these values return from markdown parsing as structured data, and we'll show some really good information in there.

refs = tfast["env"].series().dropna()["references"].apply(dict.values).explode().series()        
refs.apply(
    lambda x: F"* [{x.title or x.href}]({x.href})", axis=1
).pipe(md)
%%
#### access images in the mimebundle

    docs.bundles[["image/png", "image/jpeg"]].stack().to_frame("b64").apply(
        lambda x: F"![](data:{x.name[-1]};base64,{x.b64})", axis=1
    ).pipe(md)

access images in the mimebundle¤

docs.bundles[["image/png", "image/jpeg"]].stack().to_frame("b64").apply(
    lambda x: F"![](data:{x.name[-1]};base64,{x.b64})", axis=1
).pipe(md)