-
-
Notifications
You must be signed in to change notification settings - Fork 657
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use YAML examples in documentation by default, not JSON #1153
Comments
Could there be a little widget that offers conversion from one to the other? |
That's a good idea. I could do that with JavaScript - loading YAML and converting it to JSON in JavaScript shouldn't be hard, and it's better than JSON-to-YAML because there's only one correct JSON representation of a YAML file whereas you can represent a JSON document in YAML in a bunch of different ways. |
... actually I think I would do that conversion in Python. The client-side YAML parsers all look a little bit heavy to me in terms of additional page weight. |
https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.0.0/js-yaml.min.js is only 12.5KB zipped, 38KB total - so that's not a bad option. |
https://docs.datasette.io/en/stable/metadata.html has this example: title: Demonstrating Metadata from YAML
description_html: |-
<p>This description includes a long HTML string</p>
<ul>
<li>YAML is better for embedding HTML strings than JSON!</li>
</ul>
license: ODbL
license_url: https://opendatacommons.org/licenses/odbl/
databases:
fixtures:
tables:
no_primary_key:
hidden: true
queries:
neighborhood_search:
sql: |-
select neighborhood, facet_cities.name, state
from facetable join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%' order by neighborhood;
title: Search neighborhoods
description_html: |-
<p>This demonstrates <em>basic</em> LIKE search I ran this in the browser dev tools: var s = document.createElement('script')
s.src = 'https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.0.0/js-yaml.min.js'
document.head.appendChild(s)
var yamlExample = document.querySelector('.highlight-yaml').textContent);
console.log(JSON.stringify(window.jsyaml.load(yamlExample), null, 4)) And got: {
"title": "Demonstrating Metadata from YAML",
"description_html": "<p>This description includes a long HTML string</p>\n<ul>\n <li>YAML is better for embedding HTML strings than JSON!</li>\n</ul>",
"license": "ODbL",
"license_url": "https://opendatacommons.org/licenses/odbl/",
"databases": {
"fixtures": {
"tables": {
"no_primary_key": {
"hidden": true
}
},
"queries": {
"neighborhood_search": {
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%' order by neighborhood;",
"title": "Search neighborhoods",
"description_html": "<p>This demonstrates <em>basic</em> LIKE search"
}
}
}
}
} |
I used this code to get that: var jsonVersion = JSON.stringify(window.jsyaml.load(document.querySelector('.highlight-yaml').textContent), null, 4);
div.querySelector('.highlight pre').innerText = jsonVersion;
div.querySelector('.highlight pre').style.whiteSpace = 'pre-wrap' |
Beginnings of a UI element for switching between them: <div style="border: 1px solid rgb(225, 228, 229);
background-color: rgb(238, 255, 204);
padding: 0.3em;
position: relative;
top: 3px;
font-family: courier;">
<a href="#" style="display: inline-block; padding-left: 0px; padding-right: 2em;">JSON</a>
<a href="#" style="display: inline-block;">YAML</a>
</div> That |
I could use https://github.com/pradyunsg/sphinx-inline-tabs for this - recommended by https://pradyunsg.me/furo/recommendations/ |
Undocumented Sphinx feature: you can add extra classes to a code example like this:
https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block doesn't mention this. Filed an issue about the lack of documentation here: |
I was inspired to finally address this after seeing |
Added sphinx-inline-tabs to provide JSON and YAML tabs to show examples. Refs #1153
I'm using datasette/docs/metadata_doc.py Lines 1 to 13 in 3b336d8
Example usage: Lines 17 to 53 in 3b336d8
|
Hit a problem:
That's happening here: datasette/.github/workflows/deploy-latest.yml Lines 42 to 48 in 0183e1a
My https://github.com/simonw/sphinx-to-sqlite tool can't handle the new |
Actually no it's in
|
Relevant code: https://github.com/docutils/docutils/blob/3b53ded52bc439d8068b6ecb20ea0a761247e479/docutils/docutils/nodes.py#L2021-L2031 def unknown_visit(self, node):
"""
Called when entering unknown `Node` types.
Raise an exception unless overridden.
"""
if (self.document.settings.strict_visitor
or node.__class__.__name__ not in self.optional):
raise NotImplementedError(
'%s visiting unknown node type: %s'
% (self.__class__, node.__class__.__name__)) |
Running with sphinx-build -P -b xml . _build
So if I can get |
This one was tricky: ![]() I wanted complete control over the YAML example here, so I could ensure it used multi-line strings correctly. I ended up changing my cog helper function to this: import json
import textwrap
from yaml import safe_dump
from ruamel.yaml import round_trip_load
def metadata_example(cog, data=None, yaml=None):
assert data or yaml, "Must provide data= or yaml="
assert not (data and yaml), "Cannot use data= and yaml="
output_yaml = None
if yaml:
# dedent it first
yaml = textwrap.dedent(yaml).strip()
# round_trip_load to preserve key order:
data = round_trip_load(yaml)
output_yaml = yaml
else:
output_yaml = safe_dump(data, sort_keys=False)
cog.out("\n.. tab:: YAML\n\n")
cog.out(" .. code-block:: yaml\n\n")
cog.out(textwrap.indent(output_yaml, " "))
cog.out("\n\n.. tab:: JSON\n\n")
cog.out(" .. code-block:: json\n\n")
cog.out(textwrap.indent(json.dumps(data, indent=2), " "))
cog.out("\n") This allows me to call it ith YAML in some places:
I had to introduce https://pypi.org/project/ruamel.yaml/ as a dependency here in order to load YAML from disk while maintaining key order. I'm still using |
I'm going to drop Python 3.7. |
YAML configuration is much better for multi-line strings, and I'm increasingly adding configuration options to Datasette that benefit from that - fragments of HTML in
description_html
or SQL queries used to configure things like https://github.com/simonw/datasette-atom for example.Rather than confusing things by showing both in the documentation, I should switch all of the default examples to use YAML instead.
The text was updated successfully, but these errors were encountered: