sextile 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sextile-0.1.0/.gitignore +24 -0
- sextile-0.1.0/LICENSE +26 -0
- sextile-0.1.0/NOTICE.md +51 -0
- sextile-0.1.0/PKG-INFO +119 -0
- sextile-0.1.0/README.md +90 -0
- sextile-0.1.0/docs/design.md +962 -0
- sextile-0.1.0/docs/glossary.md +4 -0
- sextile-0.1.0/docs/graphics.md +6 -0
- sextile-0.1.0/docs/layout.md +244 -0
- sextile-0.1.0/docs/navigation.md +202 -0
- sextile-0.1.0/docs/public-surface.md +298 -0
- sextile-0.1.0/docs/rendering.md +154 -0
- sextile-0.1.0/docs/viewdata-encoding.md +5 -0
- sextile-0.1.0/docs/writing-an-application.md +7 -0
- sextile-0.1.0/pyproject.toml +47 -0
- sextile-0.1.0/src/sextile/__init__.py +96 -0
- sextile-0.1.0/src/sextile/__main__.py +100 -0
- sextile-0.1.0/src/sextile/application.py +538 -0
- sextile-0.1.0/src/sextile/builtin/__init__.py +29 -0
- sextile-0.1.0/src/sextile/builtin/contents.py +66 -0
- sextile-0.1.0/src/sextile/builtin/guidance.py +166 -0
- sextile-0.1.0/src/sextile/builtin/history.py +80 -0
- sextile-0.1.0/src/sextile/builtin/names.py +61 -0
- sextile-0.1.0/src/sextile/builtin/readership.py +212 -0
- sextile-0.1.0/src/sextile/cli.py +357 -0
- sextile-0.1.0/src/sextile/content/__init__.py +5 -0
- sextile-0.1.0/src/sextile/content/blocks.py +87 -0
- sextile-0.1.0/src/sextile/content/transliterate.py +104 -0
- sextile-0.1.0/src/sextile/formatting.py +525 -0
- sextile-0.1.0/src/sextile/forms/__init__.py +36 -0
- sextile-0.1.0/src/sextile/forms/base.py +194 -0
- sextile-0.1.0/src/sextile/forms/fields.py +301 -0
- sextile-0.1.0/src/sextile/forms/type_ahead.py +227 -0
- sextile-0.1.0/src/sextile/handlers.py +362 -0
- sextile-0.1.0/src/sextile/keys.py +173 -0
- sextile-0.1.0/src/sextile/layout/__init__.py +85 -0
- sextile-0.1.0/src/sextile/layout/footer.py +200 -0
- sextile-0.1.0/src/sextile/layout/furniture.py +160 -0
- sextile-0.1.0/src/sextile/layout/page.py +283 -0
- sextile-0.1.0/src/sextile/layout/parts.py +446 -0
- sextile-0.1.0/src/sextile/middleware.py +180 -0
- sextile-0.1.0/src/sextile/page.py +176 -0
- sextile-0.1.0/src/sextile/pages.py +232 -0
- sextile-0.1.0/src/sextile/py.typed +0 -0
- sextile-0.1.0/src/sextile/requests.py +77 -0
- sextile-0.1.0/src/sextile/routing.py +614 -0
- sextile-0.1.0/src/sextile/server.py +200 -0
- sextile-0.1.0/src/sextile/session/__init__.py +1 -0
- sextile-0.1.0/src/sextile/session/commands.py +238 -0
- sextile-0.1.0/src/sextile/session/navigation.py +89 -0
- sextile-0.1.0/src/sextile/session/screen.py +216 -0
- sextile-0.1.0/src/sextile/session/session.py +455 -0
- sextile-0.1.0/src/sextile/state.py +96 -0
- sextile-0.1.0/src/sextile/testing.py +200 -0
- sextile-0.1.0/src/sextile/viewdata/__init__.py +18 -0
- sextile-0.1.0/src/sextile/viewdata/ansi.py +88 -0
- sextile-0.1.0/src/sextile/viewdata/attributes.py +222 -0
- sextile-0.1.0/src/sextile/viewdata/blocks.py +242 -0
- sextile-0.1.0/src/sextile/viewdata/canvas.py +363 -0
- sextile-0.1.0/src/sextile/viewdata/charset.py +98 -0
- sextile-0.1.0/src/sextile/viewdata/charting.py +105 -0
- sextile-0.1.0/src/sextile/viewdata/command_line.py +123 -0
- sextile-0.1.0/src/sextile/viewdata/compass.py +141 -0
- sextile-0.1.0/src/sextile/viewdata/composition.py +517 -0
- sextile-0.1.0/src/sextile/viewdata/controls.py +130 -0
- sextile-0.1.0/src/sextile/viewdata/display.py +181 -0
- sextile-0.1.0/src/sextile/viewdata/drawing.py +195 -0
- sextile-0.1.0/src/sextile/viewdata/encoding.py +81 -0
- sextile-0.1.0/src/sextile/viewdata/font.py +342 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/3x3-mono.font +477 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/OFL-1.1.txt +116 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/__init__.py +7 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/acorn.font +1899 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/arcade.font +665 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/boldbash.font +1041 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/console-bold.font +947 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/console.font +947 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/garland.font +1793 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/grotesque-bold.font +1229 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/grotesque.font +1229 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/lilliputsteps.font +947 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator-bold.font +1417 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator-hb.font +1417 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator-sc-bold.font +1417 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator-sc-hb.font +1417 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator-sc.font +1417 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator.font +1417 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator8-bold.font +947 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator8-hb.font +947 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixeloperator8.font +947 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/pixelplace.font +759 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/publicpixel.font +853 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/roman.font +1041 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/scientifica-bold.font +1135 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/scientifica-italic.font +1135 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/scientifica.font +1135 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/silkscreen-bold.font +1041 -0
- sextile-0.1.0/src/sextile/viewdata/fonts/silkscreen.font +1041 -0
- sextile-0.1.0/src/sextile/viewdata/frame.py +209 -0
- sextile-0.1.0/src/sextile/viewdata/hangup.py +38 -0
- sextile-0.1.0/src/sextile/viewdata/html.py +98 -0
- sextile-0.1.0/src/sextile/viewdata/idle_warning.py +85 -0
- sextile-0.1.0/src/sextile/viewdata/lettering.py +404 -0
- sextile-0.1.0/src/sextile/viewdata/measure.py +42 -0
- sextile-0.1.0/src/sextile/viewdata/repaint.py +187 -0
- sextile-0.1.0/src/sextile/viewdata/static/bedstead.woff2 +0 -0
- sextile-0.1.0/src/sextile/viewdata/static/viewdata.css +64 -0
- sextile-0.1.0/src/sextile/viewdata/typesetting.py +143 -0
- sextile-0.1.0/src/sextile/viewdata/wrapping.py +141 -0
- sextile-0.1.0/src/sextile/visits.py +230 -0
- sextile-0.1.0/tests/data/viewdata_fixture.html +24 -0
- sextile-0.1.0/tests/exemplar.py +121 -0
- sextile-0.1.0/tests/test_addressing.py +92 -0
- sextile-0.1.0/tests/test_ansi.py +108 -0
- sextile-0.1.0/tests/test_application.py +1076 -0
- sextile-0.1.0/tests/test_blocks.py +99 -0
- sextile-0.1.0/tests/test_canvas.py +387 -0
- sextile-0.1.0/tests/test_charset.py +148 -0
- sextile-0.1.0/tests/test_charting.py +90 -0
- sextile-0.1.0/tests/test_cli.py +248 -0
- sextile-0.1.0/tests/test_command_line.py +108 -0
- sextile-0.1.0/tests/test_commands.py +364 -0
- sextile-0.1.0/tests/test_compass.py +195 -0
- sextile-0.1.0/tests/test_composition.py +537 -0
- sextile-0.1.0/tests/test_contents.py +151 -0
- sextile-0.1.0/tests/test_control_codes.py +129 -0
- sextile-0.1.0/tests/test_display.py +120 -0
- sextile-0.1.0/tests/test_drawing.py +233 -0
- sextile-0.1.0/tests/test_encoding.py +134 -0
- sextile-0.1.0/tests/test_fields.py +414 -0
- sextile-0.1.0/tests/test_font.py +278 -0
- sextile-0.1.0/tests/test_footer.py +217 -0
- sextile-0.1.0/tests/test_formatting.py +337 -0
- sextile-0.1.0/tests/test_forms.py +553 -0
- sextile-0.1.0/tests/test_frame.py +271 -0
- sextile-0.1.0/tests/test_frame_engine.py +91 -0
- sextile-0.1.0/tests/test_guidance.py +89 -0
- sextile-0.1.0/tests/test_handlers.py +80 -0
- sextile-0.1.0/tests/test_hangup.py +65 -0
- sextile-0.1.0/tests/test_history.py +137 -0
- sextile-0.1.0/tests/test_icons.py +74 -0
- sextile-0.1.0/tests/test_idle_warning.py +72 -0
- sextile-0.1.0/tests/test_layout.py +625 -0
- sextile-0.1.0/tests/test_lettering.py +460 -0
- sextile-0.1.0/tests/test_middleware.py +212 -0
- sextile-0.1.0/tests/test_names.py +69 -0
- sextile-0.1.0/tests/test_page.py +128 -0
- sextile-0.1.0/tests/test_pages.py +206 -0
- sextile-0.1.0/tests/test_public_surface.py +244 -0
- sextile-0.1.0/tests/test_readership.py +189 -0
- sextile-0.1.0/tests/test_repaint.py +200 -0
- sextile-0.1.0/tests/test_router.py +163 -0
- sextile-0.1.0/tests/test_routing.py +458 -0
- sextile-0.1.0/tests/test_server.py +458 -0
- sextile-0.1.0/tests/test_session.py +998 -0
- sextile-0.1.0/tests/test_skeleton.py +13 -0
- sextile-0.1.0/tests/test_state.py +60 -0
- sextile-0.1.0/tests/test_testing.py +145 -0
- sextile-0.1.0/tests/test_transliteration.py +191 -0
- sextile-0.1.0/tests/test_typesetting.py +264 -0
- sextile-0.1.0/tests/test_typing_repaint.py +190 -0
- sextile-0.1.0/tests/test_viewdata_html.py +99 -0
- sextile-0.1.0/tests/test_visits.py +120 -0
- sextile-0.1.0/tests/test_wrapping.py +204 -0
sextile-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# The archive Sextile accumulates at runtime
|
|
13
|
+
*.sqlite
|
|
14
|
+
|
|
15
|
+
# macOS
|
|
16
|
+
.DS_Store
|
|
17
|
+
|
|
18
|
+
# Editors
|
|
19
|
+
.idea/
|
|
20
|
+
.vscode/
|
|
21
|
+
|
|
22
|
+
# Sphinx build output and autosummary-generated stubs
|
|
23
|
+
docs/_build/
|
|
24
|
+
uv.lock
|
sextile-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Robert Smallshire
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
The MIT licence above covers the software and its documentation. It does not,
|
|
26
|
+
and cannot, cover third-party material included for testing. See NOTICE.md.
|
sextile-0.1.0/NOTICE.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Third-party material
|
|
2
|
+
|
|
3
|
+
Sextile is MIT licensed (see [LICENSE](LICENSE)). The mosaic font faces and the
|
|
4
|
+
Bedstead font it ships are not ours to license, and are noted here. Each face
|
|
5
|
+
also carries its source and terms in its own header, and the conversion to this
|
|
6
|
+
project's format changes the format and nothing else about the design.
|
|
7
|
+
|
|
8
|
+
## Fonts
|
|
9
|
+
|
|
10
|
+
`sextile/viewdata/fonts/` holds bitmap faces converted into this project's own
|
|
11
|
+
format. None is covered by the MIT grant above.
|
|
12
|
+
|
|
13
|
+
### Free for public use
|
|
14
|
+
|
|
15
|
+
| face | from |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `acorn` | MDFS ArcNormal (mdfs.net/Apps/Font/Fonts1.zip), by J.G.Harston |
|
|
18
|
+
|
|
19
|
+
### Public domain (Creative Commons Zero v1.0)
|
|
20
|
+
|
|
21
|
+
`3x3-mono` (GGBotNet), `boldbash` (Michiel), `lilliputsteps` (Raymond Larabie),
|
|
22
|
+
`pixeloperator` and its variants (Jayvee Enaguas / HarvettFox96), `pixelplace`
|
|
23
|
+
(Michiel), `publicpixel` (GGBotNet).
|
|
24
|
+
|
|
25
|
+
### SIL Open Font License, Version 1.1
|
|
26
|
+
|
|
27
|
+
The licence text and copyright notices are in `sextile/viewdata/fonts/OFL-1.1.txt`,
|
|
28
|
+
which ships with the faces because the licence requires it. Converting a font to
|
|
29
|
+
another format makes a Modified Version, which may not use a reserved font name,
|
|
30
|
+
so several carry a name of ours instead; the original is named in each file's
|
|
31
|
+
`source:` line, and the mapping is in the licence file.
|
|
32
|
+
|
|
33
|
+
`arcade` (QuinqueFive, GGBotNet), `console` and `console-bold` (Dogica, Roberto
|
|
34
|
+
Mocci), `garland` (Birch Leaf, solirides), `grotesque` and `grotesque-bold`
|
|
35
|
+
(Pixeloid Sans, GGBotNet), `roman` (Times9k, Sammy L. Koch), `scientifica` and
|
|
36
|
+
its variants (Akshay Oppiliappan), `silkscreen` and `silkscreen-bold` (Jason
|
|
37
|
+
Kottke).
|
|
38
|
+
|
|
39
|
+
The CC0 and Open Font faces come from `github.com/michielp1807/more-fonts`, whose
|
|
40
|
+
own MIT licence covers its source and not the faces it collects.
|
|
41
|
+
|
|
42
|
+
## Bedstead
|
|
43
|
+
|
|
44
|
+
`sextile/viewdata/static/bedstead.woff2` is Bedstead, the Mullard SAA5050
|
|
45
|
+
teletext character generator recreated as an OpenType font by bjh21 (Ben
|
|
46
|
+
Harris), which draws Viewdata frames as HTML — `sextile render --form html`
|
|
47
|
+
ships it. The program that generates Bedstead and its newly-designed glyphs are
|
|
48
|
+
released into the public domain (CC0-1.0); the original SAA5050 bitmap is stated
|
|
49
|
+
to be public domain in the United Kingdom under Section 55 of the Copyright,
|
|
50
|
+
Designs and Patents Act 1988. Vendored from `https://bjh21.me.uk/bedstead/bedstead.otf`
|
|
51
|
+
and converted to WOFF2 with fontTools; the design is unchanged.
|
sextile-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sextile
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A framework for Prestel-style Viewdata services
|
|
5
|
+
Project-URL: Homepage, https://github.com/rob-smallshire/sextile
|
|
6
|
+
Project-URL: Documentation, https://rob-smallshire.github.io/sextile/
|
|
7
|
+
Project-URL: Repository, https://github.com/rob-smallshire/sextile
|
|
8
|
+
Project-URL: Issues, https://github.com/rob-smallshire/sextile/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/rob-smallshire/sextile/blob/master/CHANGELOG.md
|
|
10
|
+
Author-email: Robert Smallshire <robert@smallshire.org.uk>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
License-File: NOTICE.md
|
|
14
|
+
Keywords: bbc-micro,prestel,retrocomputing,teletext,videotex,viewdata
|
|
15
|
+
Classifier: Development Status :: 3 - Alpha
|
|
16
|
+
Classifier: Framework :: AsyncIO
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Communications
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
+
Classifier: Topic :: Terminals
|
|
26
|
+
Requires-Python: >=3.12
|
|
27
|
+
Requires-Dist: anyascii>=0.3
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# Sextile
|
|
31
|
+
|
|
32
|
+
[](https://github.com/rob-smallshire/sextile/actions/workflows/ci.yml)
|
|
33
|
+
[](https://pypi.org/project/sextile/)
|
|
34
|
+
[](https://pypi.org/project/sextile/)
|
|
35
|
+
[](https://github.com/rob-smallshire/sextile/blob/master/LICENSE)
|
|
36
|
+
[](https://rob-smallshire.github.io/sextile/)
|
|
37
|
+
|
|
38
|
+
A framework for Viewdata services, in Python. Sextile is to a Prestel-style
|
|
39
|
+
service what Flask or Starlette is to a web application: it owns the connection,
|
|
40
|
+
the session, the page numbering and the frames on the wire, and you write what
|
|
41
|
+
the pages say. The [documentation](https://rob-smallshire.github.io/sextile/)
|
|
42
|
+
opens with what Viewdata is.
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
uv add sextile # or pip install sextile
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from sextile import Page, PageRequest, Sextile, notice_page
|
|
50
|
+
|
|
51
|
+
app = Sextile(name="My service")
|
|
52
|
+
|
|
53
|
+
@app.page("1", name="main", keywords=("MAIN",))
|
|
54
|
+
async def main(request: PageRequest) -> Page:
|
|
55
|
+
return notice_page(request, "Hello, 1981.")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
sextile serve my_service:app # answer calls on port 6850
|
|
60
|
+
nc localhost 6850 # and call it
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## What it gives you
|
|
64
|
+
|
|
65
|
+
**Routing by page number.** Patterns of literal digits and named fields, so
|
|
66
|
+
`82{post_id:int}` answers every page beginning 82 and hands the rest to the
|
|
67
|
+
handler already read as an integer. `app.address_for("post", post_id=...)` reads
|
|
68
|
+
the same pattern backwards, so a page linking to another does not respell the
|
|
69
|
+
numbering. Keywords — `*MAIN#` for `*1#` — are the route's `keywords=`.
|
|
70
|
+
|
|
71
|
+
**Sessions that last as long as the line.** A Viewdata terminal is a display and
|
|
72
|
+
nothing more: it holds the frame on screen and nothing else. So the server holds
|
|
73
|
+
where the reader is, what they have seen, and the menu they came through, and a
|
|
74
|
+
handler is a function of a request rather than of a number. The reasoning is in
|
|
75
|
+
[the explanation](https://rob-smallshire.github.io/sextile/explanation/why-sextile.html).
|
|
76
|
+
|
|
77
|
+
**The wire, measured rather than assumed.** Attributes travel as `ESC` + code +
|
|
78
|
+
0x40, a frame is 24 rows of 40 that wraps at the bottom-right back to the top
|
|
79
|
+
left, `RETURN` transmits 0x5F. Those were settled by driving real Commstar under
|
|
80
|
+
an emulator, and are written up in
|
|
81
|
+
[the encoding reference](https://rob-smallshire.github.io/sextile/reference/viewdata-encoding.html).
|
|
82
|
+
|
|
83
|
+
**Nobody is cut off without warning.** After half the idle timeout a silent
|
|
84
|
+
caller's footer becomes a bar that drains, reading `Press a key`. The first key
|
|
85
|
+
dismisses it and does nothing else, so it is safe to press whatever comes to
|
|
86
|
+
hand. Every service gets this without writing anything.
|
|
87
|
+
|
|
88
|
+
**Forty columns, accounted for.** A colour attribute occupies a character cell,
|
|
89
|
+
so a row that changes colour twice has thirty-eight columns for text. `Canvas`
|
|
90
|
+
does that arithmetic so nothing above it has to.
|
|
91
|
+
|
|
92
|
+
**Drawable without a Beeb.** `sextile render` draws any page four ways: `ansi`
|
|
93
|
+
colour as the Beeb would draw it, `grid` for the character and attribute layers,
|
|
94
|
+
`bytes` for the wire stream, and `html` for a self-contained web page with the
|
|
95
|
+
Bedstead font embedded, opening from disk with no server.
|
|
96
|
+
|
|
97
|
+
## Documentation
|
|
98
|
+
|
|
99
|
+
The full documentation is at
|
|
100
|
+
[rob-smallshire.github.io/sextile](https://rob-smallshire.github.io/sextile/):
|
|
101
|
+
[the tutorial](https://rob-smallshire.github.io/sextile/tutorial/index.html)
|
|
102
|
+
builds a service step by step, the
|
|
103
|
+
[how-to guides](https://rob-smallshire.github.io/sextile/how-to/index.html)
|
|
104
|
+
answer particular questions, the
|
|
105
|
+
[reference](https://rob-smallshire.github.io/sextile/reference/index.html) states
|
|
106
|
+
the surface, the glossary and the wire, and the
|
|
107
|
+
[explanation](https://rob-smallshire.github.io/sextile/explanation/index.html)
|
|
108
|
+
says why the framework is shaped as it is.
|
|
109
|
+
|
|
110
|
+
## Status
|
|
111
|
+
|
|
112
|
+
Young, and extracted from a working service rather than designed in the abstract.
|
|
113
|
+
Three applications use it in the
|
|
114
|
+
[source repository](https://github.com/rob-smallshire/sextile): a real Stardot
|
|
115
|
+
forum reader, a weather service, and a calendar written to be read.
|
|
116
|
+
|
|
117
|
+
MIT licensed. The bundled font faces and the Bedstead font are third-party
|
|
118
|
+
material; see
|
|
119
|
+
[NOTICE.md](https://github.com/rob-smallshire/sextile/blob/master/packages/sextile/NOTICE.md).
|
sextile-0.1.0/README.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Sextile
|
|
2
|
+
|
|
3
|
+
[](https://github.com/rob-smallshire/sextile/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/sextile/)
|
|
5
|
+
[](https://pypi.org/project/sextile/)
|
|
6
|
+
[](https://github.com/rob-smallshire/sextile/blob/master/LICENSE)
|
|
7
|
+
[](https://rob-smallshire.github.io/sextile/)
|
|
8
|
+
|
|
9
|
+
A framework for Viewdata services, in Python. Sextile is to a Prestel-style
|
|
10
|
+
service what Flask or Starlette is to a web application: it owns the connection,
|
|
11
|
+
the session, the page numbering and the frames on the wire, and you write what
|
|
12
|
+
the pages say. The [documentation](https://rob-smallshire.github.io/sextile/)
|
|
13
|
+
opens with what Viewdata is.
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
uv add sextile # or pip install sextile
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from sextile import Page, PageRequest, Sextile, notice_page
|
|
21
|
+
|
|
22
|
+
app = Sextile(name="My service")
|
|
23
|
+
|
|
24
|
+
@app.page("1", name="main", keywords=("MAIN",))
|
|
25
|
+
async def main(request: PageRequest) -> Page:
|
|
26
|
+
return notice_page(request, "Hello, 1981.")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
sextile serve my_service:app # answer calls on port 6850
|
|
31
|
+
nc localhost 6850 # and call it
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## What it gives you
|
|
35
|
+
|
|
36
|
+
**Routing by page number.** Patterns of literal digits and named fields, so
|
|
37
|
+
`82{post_id:int}` answers every page beginning 82 and hands the rest to the
|
|
38
|
+
handler already read as an integer. `app.address_for("post", post_id=...)` reads
|
|
39
|
+
the same pattern backwards, so a page linking to another does not respell the
|
|
40
|
+
numbering. Keywords — `*MAIN#` for `*1#` — are the route's `keywords=`.
|
|
41
|
+
|
|
42
|
+
**Sessions that last as long as the line.** A Viewdata terminal is a display and
|
|
43
|
+
nothing more: it holds the frame on screen and nothing else. So the server holds
|
|
44
|
+
where the reader is, what they have seen, and the menu they came through, and a
|
|
45
|
+
handler is a function of a request rather than of a number. The reasoning is in
|
|
46
|
+
[the explanation](https://rob-smallshire.github.io/sextile/explanation/why-sextile.html).
|
|
47
|
+
|
|
48
|
+
**The wire, measured rather than assumed.** Attributes travel as `ESC` + code +
|
|
49
|
+
0x40, a frame is 24 rows of 40 that wraps at the bottom-right back to the top
|
|
50
|
+
left, `RETURN` transmits 0x5F. Those were settled by driving real Commstar under
|
|
51
|
+
an emulator, and are written up in
|
|
52
|
+
[the encoding reference](https://rob-smallshire.github.io/sextile/reference/viewdata-encoding.html).
|
|
53
|
+
|
|
54
|
+
**Nobody is cut off without warning.** After half the idle timeout a silent
|
|
55
|
+
caller's footer becomes a bar that drains, reading `Press a key`. The first key
|
|
56
|
+
dismisses it and does nothing else, so it is safe to press whatever comes to
|
|
57
|
+
hand. Every service gets this without writing anything.
|
|
58
|
+
|
|
59
|
+
**Forty columns, accounted for.** A colour attribute occupies a character cell,
|
|
60
|
+
so a row that changes colour twice has thirty-eight columns for text. `Canvas`
|
|
61
|
+
does that arithmetic so nothing above it has to.
|
|
62
|
+
|
|
63
|
+
**Drawable without a Beeb.** `sextile render` draws any page four ways: `ansi`
|
|
64
|
+
colour as the Beeb would draw it, `grid` for the character and attribute layers,
|
|
65
|
+
`bytes` for the wire stream, and `html` for a self-contained web page with the
|
|
66
|
+
Bedstead font embedded, opening from disk with no server.
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
The full documentation is at
|
|
71
|
+
[rob-smallshire.github.io/sextile](https://rob-smallshire.github.io/sextile/):
|
|
72
|
+
[the tutorial](https://rob-smallshire.github.io/sextile/tutorial/index.html)
|
|
73
|
+
builds a service step by step, the
|
|
74
|
+
[how-to guides](https://rob-smallshire.github.io/sextile/how-to/index.html)
|
|
75
|
+
answer particular questions, the
|
|
76
|
+
[reference](https://rob-smallshire.github.io/sextile/reference/index.html) states
|
|
77
|
+
the surface, the glossary and the wire, and the
|
|
78
|
+
[explanation](https://rob-smallshire.github.io/sextile/explanation/index.html)
|
|
79
|
+
says why the framework is shaped as it is.
|
|
80
|
+
|
|
81
|
+
## Status
|
|
82
|
+
|
|
83
|
+
Young, and extracted from a working service rather than designed in the abstract.
|
|
84
|
+
Three applications use it in the
|
|
85
|
+
[source repository](https://github.com/rob-smallshire/sextile): a real Stardot
|
|
86
|
+
forum reader, a weather service, and a calendar written to be read.
|
|
87
|
+
|
|
88
|
+
MIT licensed. The bundled font faces and the Bedstead font are third-party
|
|
89
|
+
material; see
|
|
90
|
+
[NOTICE.md](https://github.com/rob-smallshire/sextile/blob/master/packages/sextile/NOTICE.md).
|