Skip to content

Commit 8529502

Browse files
kwagyemanclaude
andcommitted
docs: Redesign landing page with Shibuya theme.
Switch from sphinx-rtd-theme to Shibuya, drop the ReadTheDocs configuration scaffolding, and rebuild the index page as a custom landing with hero, quickstart steps, hello-world tabbed code card, core libraries grid, board grid with hero photos, more-resources cards, and community links. - conf.py: switch theme to shibuya, expose openmv_version, micropython_version, and build_date in html_context, render the seven landing-page code examples through Pygments at build time so they pick up the site syntax theme, drop sphinxcontrib.jquery and the legacy sphinx_rtd_theme extension, and update copyright to read "by OpenMV, Damien P. George, and others." - topindex.html: full rewrite as a custom landing page extending Shibuya's landing layout, with seven hand-written examples that all use the csi module rather than the deprecated sensor module. - foot-copyright.html: new footer partial showing the firmware version, MicroPython base version, build date, and copyright on a single line. - Add OpenMV light/dark logos plus an openmv-hero.mp4 background loop. - Drop docs/readthedocs/, docs/templates/layout.html, and the legacy customstyle.css that were carried over from upstream MicroPython. - .gitattributes: mark .mp4/.webm/.webp as binary. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d25c1aa commit 8529502

13 files changed

Lines changed: 1414 additions & 169 deletions

File tree

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
*.dxf binary
1515
*.mpy binary
1616
*.der binary
17+
*.mp4 binary
18+
*.webm binary
19+
*.webp binary
1720

1821
# These should also not be modified by git.
1922
tests/basics/string_cr_conversion.py -text

docs/conf.py

Lines changed: 231 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,21 @@
2626
micropy_all_versions = (os.getenv("MICROPY_ALL_VERSIONS") or "latest").split(",")
2727
url_pattern = "%s/en/%%s" % (os.getenv("MICROPY_URL_PREFIX") or "/",)
2828

29-
# The OpenMV firmware version this documentation describes.
29+
# =============================================================================
30+
# Documentation versions and build date — bump these for each release.
31+
# =============================================================================
32+
import datetime as _dt
33+
34+
# OpenMV firmware version this documentation covers.
3035
openmv_version = "5.0.0"
3136

37+
# MicroPython version that the firmware is built on top of.
38+
# (Also used as the Sphinx ``version`` / ``release`` variables below.)
39+
micropython_version = "1.28"
40+
41+
# Build date is computed automatically each time Sphinx runs.
42+
build_date = _dt.date.today().strftime("%d %b %Y")
43+
3244
# The members of the html_context dict are available inside topindex.html
3345
html_context = {
3446
"cur_version": micropy_version,
@@ -38,6 +50,200 @@
3850
],
3951
"is_release": micropy_version != "latest",
4052
"openmv_version": openmv_version,
53+
"micropython_version": micropython_version,
54+
"build_date": build_date,
55+
}
56+
57+
# -- Landing page code examples (rendered via Pygments to match site code style) --
58+
from pygments import highlight as _pygments_highlight
59+
from pygments.lexers import PythonLexer as _PythonLexer
60+
from pygments.formatters import HtmlFormatter as _HtmlFormatter
61+
62+
_landing_examples_src = {
63+
"yolo": '''
64+
import csi
65+
import time
66+
import ml
67+
from ml.postprocessing.ultralytics import YoloV8
68+
69+
csi0 = csi.CSI()
70+
csi0.reset()
71+
csi0.pixformat(csi.RGB565)
72+
csi0.framesize(csi.VGA)
73+
74+
# Built-in single-class person detector model.
75+
model = ml.Model("/rom/yolov8n_192.tflite",
76+
postprocess=YoloV8(threshold=0.4))
77+
clock = time.clock()
78+
79+
while True:
80+
clock.tick()
81+
img = csi0.snapshot()
82+
# predict returns a list per class of ((x, y, w, h), score) tuples.
83+
for class_dets in model.predict([img]):
84+
for rect, score in class_dets:
85+
img.draw_rectangle(rect, color=(0, 255, 0))
86+
print(clock.fps(), "fps")
87+
''',
88+
"apriltag": '''
89+
import csi
90+
import math
91+
import time
92+
93+
csi0 = csi.CSI()
94+
csi0.reset()
95+
csi0.pixformat(csi.RGB565)
96+
csi0.framesize(csi.QVGA)
97+
csi0.auto_gain(False)
98+
csi0.auto_whitebal(False)
99+
100+
clock = time.clock()
101+
102+
while True:
103+
clock.tick()
104+
img = csi0.snapshot()
105+
for tag in img.find_apriltags():
106+
img.draw_detection(tag, color1=(255, 0, 0), color2=(0, 255, 0))
107+
deg = math.degrees(tag.rotation)
108+
print("ID %d rotation %.1f deg" % (tag.id, deg))
109+
print(clock.fps(), "fps")
110+
''',
111+
"blazeface": '''
112+
import csi
113+
import time
114+
import ml
115+
from ml.postprocessing.mediapipe import BlazeFace
116+
117+
csi0 = csi.CSI()
118+
csi0.reset()
119+
csi0.pixformat(csi.RGB565)
120+
csi0.framesize(csi.VGA)
121+
csi0.window((400, 400)) # square window for best results
122+
123+
model = ml.Model("/rom/blazeface_front_128.tflite",
124+
postprocess=BlazeFace(threshold=0.4))
125+
clock = time.clock()
126+
127+
while True:
128+
clock.tick()
129+
img = csi0.snapshot()
130+
for rect, score, keypoints in model.predict([img]):
131+
img.draw_rectangle(rect, color=(0, 0, 255))
132+
ml.utils.draw_keypoints(img, keypoints, color=(255, 0, 0))
133+
print(clock.fps(), "fps")
134+
''',
135+
"qrcode": '''
136+
import csi
137+
import time
138+
139+
csi0 = csi.CSI()
140+
csi0.reset()
141+
csi0.pixformat(csi.RGB565)
142+
csi0.framesize(csi.QVGA)
143+
csi0.auto_gain(False)
144+
145+
clock = time.clock()
146+
147+
while True:
148+
clock.tick()
149+
img = csi0.snapshot()
150+
for code in img.find_qrcodes():
151+
img.draw_rectangle(code.rect, color=(255, 0, 0))
152+
print(code.payload)
153+
print(clock.fps(), "fps")
154+
''',
155+
"color": '''
156+
import csi
157+
import time
158+
159+
csi0 = csi.CSI()
160+
csi0.reset()
161+
csi0.pixformat(csi.RGB565)
162+
csi0.framesize(csi.QVGA)
163+
csi0.auto_gain(False)
164+
csi0.auto_whitebal(False)
165+
166+
# LAB thresholds: (L_min, L_max, A_min, A_max, B_min, B_max)
167+
thresholds = [
168+
(30, 100, 15, 127, 15, 127), # red
169+
(30, 100, -64, -8, -32, 32), # green
170+
]
171+
172+
clock = time.clock()
173+
174+
while True:
175+
clock.tick()
176+
img = csi0.snapshot()
177+
for blob in img.find_blobs(thresholds, pixels_threshold=200):
178+
img.draw_rectangle(blob.rect, color=(255, 0, 0))
179+
img.draw_cross((blob.cx, blob.cy))
180+
print(clock.fps(), "fps")
181+
''',
182+
"barcode": '''
183+
import csi
184+
import time
185+
186+
csi0 = csi.CSI()
187+
csi0.reset()
188+
csi0.pixformat(csi.GRAYSCALE)
189+
csi0.framesize(csi.VGA)
190+
csi0.window((640, 80)) # narrow strip for fast linear scanning
191+
csi0.auto_gain(False)
192+
csi0.auto_whitebal(False)
193+
194+
clock = time.clock()
195+
196+
while True:
197+
clock.tick()
198+
img = csi0.snapshot()
199+
for code in img.find_barcodes():
200+
img.draw_rectangle(code.rect, color=(0, 255, 0))
201+
print(code.payload, "(quality %d)" % code.quality)
202+
print(clock.fps(), "fps")
203+
''',
204+
"hand": '''
205+
import csi
206+
import time
207+
import ml
208+
from ml.postprocessing.mediapipe import HandLandmarks
209+
210+
csi0 = csi.CSI()
211+
csi0.reset()
212+
csi0.pixformat(csi.RGB565)
213+
csi0.framesize(csi.VGA)
214+
csi0.window((400, 400)) # square window for the model
215+
216+
# Connections between the 21 keypoints — palm + 5 fingers.
217+
hand_lines = ((0, 1), (1, 2), (2, 3), (3, 4), (0, 5), (5, 6),
218+
(6, 7), (7, 8), (5, 9), (9, 10), (10, 11), (11, 12),
219+
(9, 13), (13, 14), (14, 15), (15, 16), (13, 17), (17, 18),
220+
(18, 19), (19, 20), (0, 17))
221+
222+
model = ml.Model("/rom/hand_landmarks_full_224.tflite",
223+
postprocess=HandLandmarks(threshold=0.4))
224+
clock = time.clock()
225+
226+
while True:
227+
clock.tick()
228+
img = csi0.snapshot()
229+
# predict returns a list per hand: index 0 = left, index 1 = right.
230+
for detections in model.predict([img]):
231+
for rect, score, keypoints in detections:
232+
ml.utils.draw_skeleton(img, keypoints, hand_lines,
233+
kp_color=(255, 0, 0),
234+
line_color=(0, 255, 0))
235+
print(clock.fps(), "fps")
236+
''',
237+
}
238+
239+
def _render_landing_code(src):
240+
return _pygments_highlight(
241+
src.strip(), _PythonLexer(),
242+
_HtmlFormatter(nowrap=False, cssclass="highlight"),
243+
)
244+
245+
html_context["landing_examples"] = {
246+
k: _render_landing_code(v) for k, v in _landing_examples_src.items()
41247
}
42248

43249
# Authors used in various parts of the documentation.
@@ -58,8 +264,6 @@
58264
"sphinx.ext.intersphinx",
59265
"sphinx.ext.todo",
60266
"sphinx.ext.coverage",
61-
"sphinxcontrib.jquery",
62-
"sphinx_rtd_theme",
63267
]
64268

65269
# Add any paths that contain templates here, relative to this directory.
@@ -76,15 +280,15 @@
76280

77281
# General information about the project.
78282
project = "MicroPython"
79-
copyright = "- The MicroPython Documentation is Copyright © 2014-2026, Damien P. George, Paul Sokolovsky, OpenMV LLC, and contributors"
283+
copyright = "The OpenMV MicroPython Documentation is Copyright © 2014-2026 by OpenMV, Damien P. George, and others."
80284

81285
# The version info for the project you're documenting, acts as replacement for
82286
# |version| and |release|, also used in various other places throughout the
83287
# built documents.
84288
#
85289
# We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags"
86290
# breakdown, so use the same version identifier for both to avoid confusion.
87-
version = release = "1.28"
291+
version = release = micropython_version
88292

89293
# The language for content autogenerated by Sphinx. Refer to documentation
90294
# for a list of supported languages.
@@ -207,25 +411,29 @@
207411

208412
# -- Options for HTML output ----------------------------------------------
209413

210-
import sphinx_rtd_theme
211-
212-
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
213-
214-
if not on_rtd: # only import and set the theme if we're building docs locally
215-
try:
216-
import sphinx_rtd_theme
217-
218-
html_theme = "sphinx_rtd_theme"
219-
except:
220-
html_theme = "default"
221-
html_theme_path = ["."]
222-
else:
223-
html_theme_path = ["."]
414+
html_theme = "shibuya"
224415

225416
# Theme options are theme-specific and customize the look and feel of a theme
226417
# further. For a list of options available for each theme, see the
227418
# documentation.
228-
# html_theme_options = {}
419+
html_theme_options = {
420+
"light_logo": "_static/openmv-logo-light.png",
421+
"dark_logo": "_static/openmv-logo-dark.png",
422+
"accent_color": "blue",
423+
"color_mode": "auto",
424+
"github_url": "https://github.com/openmv/openmv",
425+
"discussion_url": "https://forums.openmv.io/",
426+
"globaltoc_expand_depth": 1,
427+
"toctree_collapse": True,
428+
"show_ai_links": False,
429+
"nav_links": [
430+
{"title": "Home", "url": "index"},
431+
{"title": "Quick start", "url": "openmvcam/tutorial/software_setup"},
432+
{"title": "Tutorial", "url": "openmvcam/tutorial/index"},
433+
{"title": "Library", "url": "library/index"},
434+
{"title": "Boards", "url": "openmvcam/quickref"},
435+
],
436+
}
229437

230438
# Add any paths that contain custom themes here, relative to this directory.
231439
# html_theme_path = ['.']
@@ -326,7 +534,7 @@
326534
master_doc,
327535
"MicroPython.tex",
328536
"MicroPython Documentation",
329-
"Damien P. George, Paul Sokolovsky, OpenMV LLC, and contributors",
537+
"OpenMV, Damien P. George, and others",
330538
"manual",
331539
),
332540
]
@@ -363,7 +571,7 @@
363571
"index",
364572
"micropython",
365573
"MicroPython Documentation",
366-
["Damien P. George, Paul Sokolovsky, OpenMV LLC, and contributors"],
574+
["OpenMV, Damien P. George, and others"],
367575
1,
368576
),
369577
]
@@ -382,7 +590,7 @@
382590
master_doc,
383591
"MicroPython",
384592
"MicroPython Documentation",
385-
"Damien P. George, Paul Sokolovsky, OpenMV LLC, and contributors",
593+
"OpenMV, Damien P. George, and others",
386594
"MicroPython",
387595
"One line description of project.",
388596
"Miscellaneous",

docs/license.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MicroPython license information
33

44
The MIT License (MIT)
55

6-
Copyright (c) 2013-2026 Damien P. George, Paul Sokolovsky, OpenMV LLC, and others
6+
Copyright (c) 2013-2026 by OpenMV, Damien P. George, and others
77

88
Permission is hereby granted, free of charge, to any person obtaining a copy
99
of this software and associated documentation files (the "Software"), to deal

docs/readthedocs/settings/local_settings.py

Lines changed: 0 additions & 10 deletions
This file was deleted.

docs/requirements.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
sphinx~=7.2.6
2-
sphinxcontrib.jquery==4.1
3-
sphinx-rtd-theme==3.0.2
1+
sphinx>=7.2
2+
shibuya>=2024.0.0

docs/static/custom.css

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
1-
/* Workaround to force Sphinx to render tables to 100% and wordwrap */
2-
/* See https://stackoverflow.com/questions/69359978/grid-table-does-not-word-wrap for more details */
3-
.wy-table-responsive table td, .wy-table-responsive table th {
4-
white-space: inherit;
1+
/* Allow table cells to wrap rather than overflow horizontally. */
2+
table.docutils td, table.docutils th {
3+
white-space: normal;
4+
}
5+
6+
/* MicroPython "difference to CPython" admonition styling. */
7+
.admonition-difference-to-cpython {
8+
border: 1px solid var(--sy-c-border, currentColor);
9+
}
10+
.admonition-difference-to-cpython .admonition-title {
11+
margin: 4px;
12+
}
13+
14+
/* Slightly rounded corners on code blocks. */
15+
.highlight {
16+
border-radius: 4px;
17+
}
18+
19+
/* Spacing between the footer copyright lines. */
20+
.sy-foot-copyright p {
21+
margin: 0 0 8px;
22+
}
23+
.sy-foot-copyright p:last-child {
24+
margin-bottom: 0;
25+
}
26+
27+
/* Let the breadcrumb wrap on narrow screens instead of getting a horizontal
28+
scrollbar (Shibuya defaults to white-space:nowrap + overflow:auto). */
29+
.sy-breadcrumbs ol {
30+
white-space: normal;
31+
flex-wrap: wrap;
32+
overflow: visible;
533
}

0 commit comments

Comments
 (0)