diff --git a/Makefile b/Makefile index 8319566..a9c5715 100644 --- a/Makefile +++ b/Makefile @@ -40,31 +40,30 @@ doc: # Dump the documentation example mkdir -p build/doc/html/example + cp src/chisel/static/index.html build/doc/html/example/ + cp src/chisel/static/chiselDoc.bare build/doc/html/example/ $(DEFAULT_VENV_PYTHON) -c "$$DUMP_EXAMPLE_PY" .PHONY: test-doc commit: test-doc test-doc: $(DEFAULT_VENV_BUILD) - $(DEFAULT_VENV_BIN)/bare -s static/doc/*.mds static/doc/test/*.mds - $(DEFAULT_VENV_BIN)/bare -c 'include ' static/doc/test/runTests.mds$(if $(DEBUG), -d)$(if $(TEST), -v vTest "'$(TEST)'") + $(DEFAULT_VENV_BIN)/bare -s src/chisel/static/*.bare src/chisel/static/test/*.bare + $(DEFAULT_VENV_BIN)/bare -c 'include ' src/chisel/static/test/runTests.bare$(if $(DEBUG), -d)$(if $(TEST), -v vTest "'$(TEST)'") # Python to dump documentation API responses define DUMP_EXAMPLE_PY import chisel -from chisel.doc import CHISEL_DOC_HTML import json app = chisel.Application() app.pretty_output = True app.add_requests(chisel.create_doc_requests()) -_, _, response = app.request('GET', '/doc/doc_request', query_string=f'name=chisel_doc_request') -with open(f'build/doc/html/example/index.html', 'wb') as request_file: - request_file.write(CHISEL_DOC_HTML) -with open(f'build/doc/html/example/doc_request', 'wb') as request_file: +_, _, response = app.request('GET', '/doc/doc_request', query_string='name=chisel_doc_request') +with open('build/doc/html/example/doc_request', 'wb') as request_file: request_file.write(response) -with open(f'build/doc/html/example/doc_index', 'w') as index_file: +with open('build/doc/html/example/doc_index', 'w') as index_file: json.dump({'title': 'Chisel Documentation Example', 'groups': {'Documentation': ['chisel_doc_request']}}, index_file, indent=2) endef export DUMP_EXAMPLE_PY diff --git a/setup.cfg b/setup.cfg index 0d78df1..527b6f4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,3 +29,8 @@ package_dir = = src install_requires= schema-markdown >= 1.2.0 + +[options.package_data] +chisel = + static/*.bare + static/*.html diff --git a/src/chisel/doc.py b/src/chisel/doc.py index 464b839..854ddd4 100644 --- a/src/chisel/doc.py +++ b/src/chisel/doc.py @@ -5,6 +5,8 @@ Chisel documentation application """ +import importlib.resources + from schema_markdown import get_referenced_types from schema_markdown.type_model import TYPE_MODEL @@ -12,62 +14,6 @@ from .request import RedirectRequest, StaticRequest -# The chisel-doc application's HTML stub -CHISEL_DOC_HTML = b'''\ - - - - Chisel Documentation Application - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -''' - - def create_doc_requests(requests=None, root_path='/doc', api=True, app=True): """ Yield a series of requests for use with :meth:`~chisel.Application.add_requests` comprising the Chisel @@ -86,13 +32,25 @@ def create_doc_requests(requests=None, root_path='/doc', api=True, app=True): yield DocIndex(requests=requests, urls=(('GET', root_path + '/doc_index'),)) yield DocRequest(requests=requests, urls=(('GET', root_path + '/doc_request'),)) if app: - yield RedirectRequest((('GET', root_path),), root_path + '/', doc_group='Documentation') - yield StaticRequest( - 'chisel_doc', - CHISEL_DOC_HTML, - urls=(('GET', root_path + '/'), ('GET', root_path + '/index.html')), - doc_group='Documentation' - ) + yield RedirectRequest((('GET', root_path),), root_path + '/', name='chisel_doc_redirect', doc_group='Documentation') + with importlib.resources.files('chisel.static').joinpath('index.html').open('rb') as fh: + yield StaticRequest( + 'chisel_doc', + fh.read(), + 'text/html; charset=utf-8', + (('GET', root_path + '/'), ('GET', root_path + '/index.html')), + 'The Chisel documentation HTML', + 'Documentation' + ) + with importlib.resources.files('chisel.static').joinpath('chiselDoc.bare').open('rb') as fh: + yield StaticRequest( + 'chisel_doc_app', + fh.read(), + 'text/plain; charset=utf-8', + (('GET', root_path + '/chiselDoc.bare'),), + 'The Chisel documentation application', + 'Documentation' + ) class DocIndex(Action): diff --git a/src/chisel/static/chiselDoc.bare b/src/chisel/static/chiselDoc.bare new file mode 100644 index 0000000..44413a7 --- /dev/null +++ b/src/chisel/static/chiselDoc.bare @@ -0,0 +1,87 @@ +# Licensed under the MIT License +# https://github.com/craigahobbs/chisel/blob/main/LICENSE + +include + + +# The Chisel documentation application main entry point +async function chiselDoc(): + args = argsParse(chiselDocArguments) + name = objectGet(args, 'name') + if name != null: + chiselDocRequestPage(name) + else: + chiselDocIndexPage() + endif +endfunction + + +# The Chisel documentation application arguments +chiselDocArguments = argsValidate(arrayNew( \ + objectNew('name', 'name') \ +)) + + +# Render the Chisel documentation application index page +async function chiselDocIndexPage(): + # Fetch the documentation index API + indexURL = 'doc_index' + docIndexJSON = systemFetch(indexURL) + docIndex = if(docIndexJSON != null, jsonParse(docIndexJSON)) + if docIndex == null: + markdownPrint('**Error:** Failed to fetch chisel index API "' + indexURL + '"') + return + endif + title = objectGet(docIndex, 'title') + groups = objectGet(docIndex, 'groups') + + # Render the index page + documentSetTitle(title) + markdownPrint('# ' + markdownEscape(title)) + for groupName in arraySort(objectKeys(groups)): + markdownPrint('', '## ' + markdownEscape(groupName)) + for requestName in arraySort(objectGet(groups, groupName)): + markdownPrint('', argsLink(chiselDocArguments, requestName, objectNew('name', requestName))) + endfor + endfor +endfunction + + +# Render the Chisel documentation application request page +async function chiselDocRequestPage(typeName): + # Fetch the request API + requestURL = 'doc_request?name=' + urlEncodeComponent(typeName) + docRequestJSON = systemFetch(requestURL) + docRequest = if(docRequestJSON != null, jsonParse(docRequestJSON)) + if docRequest == null: + markdownPrint('**Error:** Failed to fetch chisel request API "' + requestURL + '"') + return + endif + doc = objectGet(docRequest, 'doc') + urls = objectGet(docRequest, 'urls') + types = objectGet(docRequest, 'types') + + # Render the request page + documentSetTitle(typeName) + markdownPrint(argsLink(chiselDocArguments, 'Index', objectNew('name', null))) + + # Action request? + if types != null: + elementModelRender(schemaElements(types, typeName, urls)) + return + endif + + # Non-action request + markdownPrint('', '# ' + markdownEscape(typeName)) + if doc != null: + markdownPrint('', doc) + endif + if urls != null && arrayLength(urls) > 0: + markdownPrint('', '**Note:** The request is exposed at the following ' + if(arrayLength(urls) == 1, 'URL:', 'URLs:')) + for requestURL in urls: + method = objectGet(requestURL, 'method', '') + path = objectGet(requestURL, 'path') + markdownPrint('', '  [' + markdownEscape(method) + ' ' + markdownEscape(path) + '](' + path + ')') + endfor + endif +endfunction diff --git a/src/chisel/static/index.html b/src/chisel/static/index.html new file mode 100644 index 0000000..73023e1 --- /dev/null +++ b/src/chisel/static/index.html @@ -0,0 +1,51 @@ + + + + Chisel Documentation Application + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/doc/test/index.html b/src/chisel/static/test/index.html similarity index 99% rename from static/doc/test/index.html rename to src/chisel/static/test/index.html index a365f42..8c8a178 100644 --- a/static/doc/test/index.html +++ b/src/chisel/static/test/index.html @@ -42,7 +42,7 @@ # Chisel Documentation Tests ~~~ markdown-script -include 'runTests.mds' +include 'runTests.bare' ~~~ `}); app.run(); diff --git a/static/doc/test/runTests.mds b/src/chisel/static/test/runTests.bare similarity index 87% rename from static/doc/test/runTests.mds rename to src/chisel/static/test/runTests.bare index 0b9d2e9..3c12eb5 100644 --- a/static/doc/test/runTests.mds +++ b/src/chisel/static/test/runTests.bare @@ -5,7 +5,7 @@ include include # Test includes -include 'testApp.mds' +include 'testChiselDoc.bare' # Test report return unittestReport() diff --git a/static/doc/test/testApp.mds b/src/chisel/static/test/testChiselDoc.bare similarity index 99% rename from static/doc/test/testApp.mds rename to src/chisel/static/test/testChiselDoc.bare index 8b33054..fcb5916 100644 --- a/static/doc/test/testApp.mds +++ b/src/chisel/static/test/testChiselDoc.bare @@ -1,7 +1,7 @@ # Licensed under the MIT License # https://github.com/craigahobbs/chisel/blob/main/LICENSE -include '../app.mds' +include '../chiselDoc.bare' async function testChiselDoc_index(): diff --git a/src/tests/test_doc.py b/src/tests/test_doc.py index 6ac8448..5995d2b 100644 --- a/src/tests/test_doc.py +++ b/src/tests/test_doc.py @@ -30,12 +30,16 @@ def test_default(self): 'urls': (('GET', '/doc/doc_request'),) }, { - 'name': 'redirect_doc', + 'name': 'chisel_doc_redirect', 'urls': (('GET', '/doc'),) }, { 'name': 'chisel_doc', 'urls': (('GET', '/doc/'), ('GET', '/doc/index.html')) + }, + { + 'name': 'chisel_doc_app', + 'urls': (('GET', '/doc/chiselDoc.bare'),) } ] ) @@ -51,12 +55,16 @@ def test_no_request_api(self): ], [ { - 'name': 'redirect_doc', + 'name': 'chisel_doc_redirect', 'urls': (('GET', '/doc'),) }, { 'name': 'chisel_doc', 'urls': (('GET', '/doc/'), ('GET', '/doc/index.html')) + }, + { + 'name': 'chisel_doc_app', + 'urls': (('GET', '/doc/chiselDoc.bare'),) } ] ) @@ -108,9 +116,10 @@ def test_doc_index(self): 'groups': { 'Documentation': [ 'chisel_doc', + 'chisel_doc_app', 'chisel_doc_index', - 'chisel_doc_request', - 'redirect_doc' + 'chisel_doc_redirect', + 'chisel_doc_request' ] } }) diff --git a/static/doc/app.mds b/static/doc/app.mds deleted file mode 100644 index 44413a7..0000000 --- a/static/doc/app.mds +++ /dev/null @@ -1,87 +0,0 @@ -# Licensed under the MIT License -# https://github.com/craigahobbs/chisel/blob/main/LICENSE - -include - - -# The Chisel documentation application main entry point -async function chiselDoc(): - args = argsParse(chiselDocArguments) - name = objectGet(args, 'name') - if name != null: - chiselDocRequestPage(name) - else: - chiselDocIndexPage() - endif -endfunction - - -# The Chisel documentation application arguments -chiselDocArguments = argsValidate(arrayNew( \ - objectNew('name', 'name') \ -)) - - -# Render the Chisel documentation application index page -async function chiselDocIndexPage(): - # Fetch the documentation index API - indexURL = 'doc_index' - docIndexJSON = systemFetch(indexURL) - docIndex = if(docIndexJSON != null, jsonParse(docIndexJSON)) - if docIndex == null: - markdownPrint('**Error:** Failed to fetch chisel index API "' + indexURL + '"') - return - endif - title = objectGet(docIndex, 'title') - groups = objectGet(docIndex, 'groups') - - # Render the index page - documentSetTitle(title) - markdownPrint('# ' + markdownEscape(title)) - for groupName in arraySort(objectKeys(groups)): - markdownPrint('', '## ' + markdownEscape(groupName)) - for requestName in arraySort(objectGet(groups, groupName)): - markdownPrint('', argsLink(chiselDocArguments, requestName, objectNew('name', requestName))) - endfor - endfor -endfunction - - -# Render the Chisel documentation application request page -async function chiselDocRequestPage(typeName): - # Fetch the request API - requestURL = 'doc_request?name=' + urlEncodeComponent(typeName) - docRequestJSON = systemFetch(requestURL) - docRequest = if(docRequestJSON != null, jsonParse(docRequestJSON)) - if docRequest == null: - markdownPrint('**Error:** Failed to fetch chisel request API "' + requestURL + '"') - return - endif - doc = objectGet(docRequest, 'doc') - urls = objectGet(docRequest, 'urls') - types = objectGet(docRequest, 'types') - - # Render the request page - documentSetTitle(typeName) - markdownPrint(argsLink(chiselDocArguments, 'Index', objectNew('name', null))) - - # Action request? - if types != null: - elementModelRender(schemaElements(types, typeName, urls)) - return - endif - - # Non-action request - markdownPrint('', '# ' + markdownEscape(typeName)) - if doc != null: - markdownPrint('', doc) - endif - if urls != null && arrayLength(urls) > 0: - markdownPrint('', '**Note:** The request is exposed at the following ' + if(arrayLength(urls) == 1, 'URL:', 'URLs:')) - for requestURL in urls: - method = objectGet(requestURL, 'method', '') - path = objectGet(requestURL, 'path') - markdownPrint('', '  [' + markdownEscape(method) + ' ' + markdownEscape(path) + '](' + path + ')') - endfor - endif -endfunction diff --git a/static/doc/app.mds b/static/doc/app.mds new file mode 120000 index 0000000..183d116 --- /dev/null +++ b/static/doc/app.mds @@ -0,0 +1 @@ +../../src/chisel/static/chiselDoc.bare \ No newline at end of file