Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/build-docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Build API docs

on:
workflow_dispatch:
push:
branches: ["main"]
pull_request:

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
fail-fast: false

steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Upgrade pip
run: python -m pip install --upgrade pip

- name: Install Quarto
uses: quarto-dev/quarto-actions/setup@v2
with:
version: 1.3.340

- name: Install dependencies
run: |
cd docs
make deps

- name: Run quartodoc
run: |
cd docs
make quartodoc

- name: Build site
run: |
cd docs
make site
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,5 @@ docs/source/reference/

.DS_Store
.Rproj.user

/.luarc.json
6 changes: 6 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
_site/
api/
_inv/
_sidebar.yml
/.quarto/
objects.json
60 changes: 60 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
.PHONY: help Makefile
.DEFAULT_GOAL := help

define BROWSER_PYSCRIPT
import os, webbrowser, sys

from urllib.request import pathname2url

webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
endef
export BROWSER_PYSCRIPT

define PRINT_HELP_PYSCRIPT
import re, sys

for line in sys.stdin:
match = re.match(r'^([a-zA-Z1-9_-]+):.*?## (.*)$$', line)
if match:
target, help = match.groups()
print("%-20s %s" % (target, help))
endef
export PRINT_HELP_PYSCRIPT

BROWSER := python -c "$$BROWSER_PYSCRIPT"

# Use venv from parent
VENV = ../venv
PYBIN = $(VENV)/bin

# Any targets that depend on $(VENV) or $(PYBIN) will cause the venv to be
# created. To use the venv, python scripts should run with the prefix $(PYBIN),
# as in `$(PYBIN)/pip`.
$(VENV):
python3 -m venv $(VENV)

$(PYBIN): $(VENV)


help:
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)

deps: $(PYBIN) ## Install build dependencies
$(PYBIN)/pip install pip --upgrade
$(PYBIN)/pip install -e ..[doc]

quartodoc: ## Build qmd files for API docs
. $(PYBIN)/activate \
&& quartodoc interlinks \
&& quartodoc build --config _quartodoc.yml --verbose

site: ## Build website
. $(PYBIN)/activate \
&& quarto render

serve: ## Build website and serve
. $(PYBIN)/activate \
&& quarto preview --port 8080

clean: ## Clean build artifacts
rm -rf _inv api _site .quarto
31 changes: 31 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Shiny for Python API docs
=========================

This directory contains files to generate Shiny for Python API documentation, using [Quartodoc](https://machow.github.io/quartodoc/get-started/overview.html) and [Quarto](https://quarto.org/).

## Building the docs

To build the docs, first install the Python dependencies and Quarto extensions:

```bash
# Install build dependencies
make py-deps
```

After those dependencies are installed, build the .qmd files for Shiny, using quartodoc. This will go in the `api/` directory:

```bash
make quartodoc
```

Then build the web site using Quarto:

```bash
make site
```

Alternatively, running `make serve` will build the docs, and serve them locally, and watch for changes to the .qmd files:

```bash
make serve
```
3 changes: 3 additions & 0 deletions docs/_extensions/machow/interlinks/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.html
*.pdf
*_files/
7 changes: 7 additions & 0 deletions docs/_extensions/machow/interlinks/_extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title: Interlinks
author: Michael Chow
version: 1.0.0
quarto-required: ">=1.2.0"
contributes:
filters:
- interlinks.lua
183 changes: 183 additions & 0 deletions docs/_extensions/machow/interlinks/interlinks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
local function read_json(filename)
local file = io.open(filename, "r")
if file == nil then
return nil
end
local str = file:read("a")
file:close()
return quarto.json.decode(str)
end

local inventory = {}

function lookup(search_object)

local results = {}
for ii, inventory in ipairs(inventory) do
for jj, item in ipairs(inventory.items) do
-- e.g. :external+<inv_name>:<domain>:<role>:`<name>`
if item.inv_name and item.inv_name ~= search_object.inv_name then
goto continue
end

if item.name ~= search_object.name then
goto continue
end

if search_object.role and item.role ~= search_object.role then
goto continue
end

if search_object.domain and item.domain ~= search_object.domain then
goto continue
else
table.insert(results, item)

goto continue
end

::continue::
end
end

if #results == 1 then
return results[1]
end
if #results > 1 then
print("Found multiple matches for " .. search_object.name)
quarto.utils.dump(results)
return nil
end
if #results == 0 then
print("Found no matches for object:")
quarto.utils.dump(search_object)
end

return nil
end

function mysplit (inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end

local function normalize_role(role)
if role == "func" then
return "function"
end
return role
end

local function build_search_object(str)
local starts_with_colon = str:sub(1, 1) == ":"
local search = {}
if starts_with_colon then
local t = mysplit(str, ":")
if #t == 2 then
-- e.g. :py:func:`my_func`
search.role = normalize_role(t[1])
search.name = t[2]:match("%%60(.*)%%60")
elseif #t == 3 then
-- e.g. :py:func:`my_func`
search.domain = t[1]
search.role = normalize_role(t[2])
search.name = t[3]:match("%%60(.*)%%60")
elseif #t == 4 then
-- e.g. :ext+inv:py:func:`my_func`
search.external = true

search.inv_name = t[1]:match("external%+(.*)")
search.domain = t[2]
search.role = normalize_role(t[3])
search.name = t[4]:match("%%60(.*)%%60")
else
print("couldn't parse this link: " .. str)
return {}
end
else
search.name = str:match("%%60(.*)%%60")
end

if search.name == nil then
print("couldn't parse this link: " .. str)
return {}
end

if search.name:sub(1, 1) == "~" then
search.shortened = true
search.name = search.name:sub(2, -1)
end
return search
end

function report_broken_link(link, search_object, replacement)
-- TODO: how to unescape html elements like [?
return pandoc.Code(pandoc.utils.stringify(link.content))
end

function Link(link)
-- do not process regular links ----
if not link.target:match("%%60") then
return link
end

-- lookup item ----
local search = build_search_object(link.target)
local item = lookup(search)

-- determine replacement, used if no link text specified ----
local original_text = pandoc.utils.stringify(link.content)
local replacement = search.name
if search.shortened then
local t = mysplit(search.name, ".")
replacement = t[#t]
end

-- set link text ----
if original_text == "" and replacement ~= nil then
link.content = pandoc.Code(replacement)
end

-- report broken links ----
if item == nil then
return report_broken_link(link, search)
end
link.target = item.uri:gsub("%$$", search.name)


return link
end

function fixup_json(json, prefix)
for _, item in ipairs(json.items) do
item.uri = prefix .. item.uri
end
table.insert(inventory, json)
end

return {
{
Meta = function(meta)
local json
local prefix
for k, v in pairs(meta.interlinks.sources) do
json = read_json(quarto.project.offset .. "/_inv/" .. k .. "_objects.json")
prefix = pandoc.utils.stringify(v.url)
fixup_json(json, prefix)
end
json = read_json(quarto.project.offset .. "/objects.json")
if json ~= nil then
fixup_json(json, "/")
end
end
},
{
Link = Link
}
}
8 changes: 8 additions & 0 deletions docs/_extensions/quarto-ext/shinylive/_extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: shinylive
title: Embedded Shinylive applications
author: Winston Chang
version: 0.0.3
quarto-required: ">=1.2.198"
contributes:
filters:
- shinylive.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
div.output-content,
div.shinylive-wrapper {
background-color: rgba(250, 250, 250, 0.65);
border: 1px solid rgba(233, 236, 239, 0.65);
border-radius: 0.5rem;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.04), 0px 3px 7px rgba(0, 0, 0, 0.04),
0px 12px 30px rgba(0, 0, 0, 0.07);
margin-top: 32px;
margin-bottom: 32px;
}

div.shinylive-wrapper {
margin: 1em 0;
border-radius: 8px;
}

.shinylive-container {
background-color: #eeeff2;
min-height: auto;
}

.shinylive-container > div {
box-shadow: none;
}

.editor-container .cm-editor .cm-scroller {
font-size: 13px;
line-height: 1.5;
}

iframe.app-frame {
/* Override the default margin from Bootstrap */
margin-bottom: 0;
}
Loading