Skip to content

Commit ac71d4a

Browse files
authored
Merge pull request #113 from makeabilitylab/feat/htmlproofer-gate
Add html-proofer link-check gate (+ complementary check_a11y) (#110)
2 parents 3fb62f2 + cc85d85 commit ac71d4a

20 files changed

Lines changed: 149 additions & 40 deletions

‎.github/workflows/content-lint.yml‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,64 @@ jobs:
2727

2828
- name: Check per-page SEO front matter (description:)
2929
run: python scripts/check_seo_frontmatter.py
30+
31+
media-a11y:
32+
# Source-level a11y conventions that html-proofer does NOT cover: YouTube
33+
# iframe title=, <video> aria-label, and lazy empty alt (alt=""). See
34+
# scripts/check_a11y.py. Complements the link-check job below.
35+
runs-on: ubuntu-latest
36+
steps:
37+
- name: Checkout
38+
uses: actions/checkout@v4
39+
40+
- name: Setup Python
41+
uses: actions/setup-python@v5
42+
with:
43+
python-version: "3.x"
44+
45+
- name: Check media a11y (iframe title, video aria-label, image alt)
46+
run: python scripts/check_a11y.py --ci
47+
48+
link-check:
49+
# Validate the BUILT site with html-proofer: broken internal links, broken
50+
# anchors, missing image alt, and malformed HTML. External links are NOT
51+
# checked here (slow/flaky); a separate non-blocking job can cover those.
52+
runs-on: ubuntu-latest
53+
steps:
54+
- name: Checkout
55+
uses: actions/checkout@v4
56+
57+
- name: Setup Ruby
58+
uses: ruby/setup-ruby@v1
59+
with:
60+
ruby-version: "3.3.11"
61+
bundler-cache: true
62+
cache-version: 0
63+
64+
- name: Build site (production baseurl)
65+
run: bundle exec jekyll build --baseurl "/physcomp"
66+
env:
67+
JEKYLL_ENV: production
68+
69+
- name: Install html-proofer
70+
run: gem install html-proofer -v 5.0.9
71+
72+
- name: Proof built site (internal links, anchors, image alt, HTML)
73+
# --swap-urls strips the /physcomp baseurl so absolute internal links
74+
# resolve against _site/. External link checking is disabled (slow/flaky).
75+
#
76+
# --ignore-files: each entry is tracked debt, not a silent skip:
77+
# * signals .+/index.html + IntroTo*.html -> stale generated nbconvert
78+
# notebooks (issue #115)
79+
# * /arduino/accel.html -> WIP draft, missing screenshot (issue #115)
80+
# * /esp32/capacitive-touch.html -> WIP lesson, missing diagrams (issue #114)
81+
# Remove an entry once its issue is resolved so the gate covers that page.
82+
# Each --ignore-files pattern must be wrapped in /slashes/ to be treated
83+
# as a regex (a bare string is an exact-path match); internal slashes are
84+
# escaped as \/.
85+
run: |
86+
htmlproofer ./_site \
87+
--disable-external \
88+
--swap-urls "^/physcomp:" \
89+
--no-enforce-https \
90+
--ignore-files "/\/signals\/.+\/index\.html/,/\/signals\/IntroTo[A-Za-z]+\.html/,/\/arduino\/accel\.html/,/\/esp32\/capacitive-touch\.html/"

‎_config.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ callouts:
102102
# Aux links for the upper right navigation
103103
aux_links:
104104
"Makeability Lab":
105-
- "//makeabilitylab.cs.washington.edu"
105+
- "https://makeabilitylab.cs.washington.edu"
106106

107107
# Heading anchor links appear on hover over h1-h6 tags in page content
108108
# allowing users to deep link to a particular heading on a page.
Binary file not shown.

‎advancedio/servo.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ The Engineering Mindset YouTube channel did this for real with an oscilloscope,
372372

373373
### Activity 3: Sensor-driven servo gauge
374374

375-
For our final activity, let's build a **physical gauge**—a servo-powered pointer that displays sensor data in the real world, like an analog speedometer or a VU meter needle. This is the physical output equivalent of the [OLED analog graph](oled.md#demo-3-basic-real-time-analog-graph) and the [NeoPixel level meter](addressable-leds.md#activity-4-led-level-meter). Where the OLED drew data on screen and the NeoPixels lit up LEDs proportionally, here we'll sweep a physical pointer across a scale.
375+
For our final activity, let's build a **physical gauge**—a servo-powered pointer that displays sensor data in the real world, like an analog speedometer or a VU meter needle. This is the physical output equivalent of the [OLED analog graph](oled.md#demo-3-basic-real-time-analog-graph) and the [NeoPixel level meter](addressable-leds.md). Where the OLED drew data on screen and the NeoPixels lit up LEDs proportionally, here we'll sweep a physical pointer across a scale.
376376

377377
We'll read an analog sensor on `A0` and map it to the servo's range. To make it more interesting, we'll add two buttons: one to "freeze" the gauge at its current reading (like a max-hold feature on a multimeter), and one to reset it.
378378

‎advancedio/smoothing-input.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ You can find our full implementation on GitHub as [MovingAverageFilter.ino](http
157157

158158
#### Simple C++ class
159159

160-
Signal filtering is a perfect opportunity to create a class to hide complexity, avoid code redundancy, and handle data processing. In our [Makeability Lab Arduino Library](https://github.com/makeabilitylab/arduino/tree/master/MakeabilityLab_Arduino_Library/src), we created the [`MovingAveragefilter.hpp`](https://github.com/makeabilitylab/arduino/blob/master/MakeabilityLab_Arduino_Library/src/MovingAverageFilter.hpp) class, which simplifies using a moving average filter. But you could make your own, of course, or use [other libraries](#arduino-filtering-libraries.)
160+
Signal filtering is a perfect opportunity to create a class to hide complexity, avoid code redundancy, and handle data processing. In our [Makeability Lab Arduino Library](https://github.com/makeabilitylab/arduino/tree/master/MakeabilityLab_Arduino_Library/src), we created the [`MovingAveragefilter.hpp`](https://github.com/makeabilitylab/arduino/blob/master/MakeabilityLab_Arduino_Library/src/MovingAverageFilter.hpp) class, which simplifies using a moving average filter. But you could make your own, of course, or use [other libraries](#arduino-filtering-libraries)
161161

162162
Here's a demonstration of how to use [`MovingAveragefilter.hpp`](https://github.com/makeabilitylab/arduino/blob/master/MakeabilityLab_Arduino_Library/src/MovingAverageFilter.hpp):
163163

‎advancedio/vibromotor.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ In this lesson, you learned about vibration motors and how to safely control the
608608

609609
## Next Lesson
610610

611-
In the [next lesson](../smoothing-input.md), we will switch from output to input and learn how to smooth noisy sensor data using digital signal processing techniques.
611+
In the [next lesson](smoothing-input.md), we will switch from output to input and learn how to smooth noisy sensor data using digital signal processing techniques.
612612

613613
<nav class="lesson-nav" aria-label="Lesson navigation">
614614
<a href="servo.html" class="nav-prev">

‎arduino/buttons.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ However, if you do this, what will the digital input pin read when the switch is
181181
**Figure.** Animation of what happens when you press a button with the simple circuit configuration.
182182
{: .fs-1 }
183183

184-
In fact, try wiring up this configuration yourself and running the following program with the [Serial Monitor](../electronics/serial-print#step-3-open-serial-monitor-in-the-arduino-ide) open. What happens when you press the button? Try touching the button legs with your fingers but not actually pressing the button—what happens to the `digitalRead` value? Are you reliably tracking the button state?
184+
In fact, try wiring up this configuration yourself and running the following program with the [Serial Monitor](serial-print.md#step-3-open-serial-monitor-in-the-arduino-ide) open. What happens when you press the button? Try touching the button legs with your fingers but not actually pressing the button—what happens to the `digitalRead` value? Are you reliably tracking the button state?
185185

186186
{% highlight cpp %}
187187
const int INPUT_BUTTON_PIN = 2;

‎arduino/fast-analog-read.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ usetocbot: true
1010

1111
## Speeding up the Arduino
1212

13-
The Arduino `C` library attempts to provide an easy-to-understand and accessible API to program and use microcontrollers. However, this comes at a cost. There are a number of interesting online discussions and blog posts analyzing Arduino code and providing faster techniques for I/O. Importantly, as Willem Maes—a faculty of engineering in Belgium—notes in his [Speeding Up the Arduino]((http://www.optiloading.be/willem/Arduino/speeding.pdf)) document:
13+
The Arduino `C` library attempts to provide an easy-to-understand and accessible API to program and use microcontrollers. However, this comes at a cost. There are a number of interesting online discussions and blog posts analyzing Arduino code and providing faster techniques for I/O. Importantly, as Willem Maes—a faculty of engineering in Belgium—notes in his [Speeding Up the Arduino](http://www.optiloading.be/willem/Arduino/speeding.pdf) document:
1414
>the programmers who developed Arduino weren't just lousy coders who couldn't write fast code, they consciously made the decision to add validations and safety checks since it benefits their target customers.
1515
1616
## How fast can we read data using analogRead and ATmega328?

‎arduino/force-sensitive-resistors.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ For more details, see the Interlink [FSR 402 datasheet]({{ site.baseurl }}/asset
104104

105105
Let's make something!
106106

107-
To begin, just like we did with the [buttons](buttons.md) and [potentiometers](potentiometers.md) lessons, we'll make a simple LED circuit without a microcontroller. In fact, this circuit will be the exact same as the "rheostat" potentiometer circuit [here](potentiometers.md#build-the-potentiometer-based-led-dimmer) (but we'll replace the rheostat with an FSR).
107+
To begin, just like we did with the [buttons](buttons.md) and [potentiometers](potentiometers.md) lessons, we'll make a simple LED circuit without a microcontroller. In fact, this circuit will be the exact same as the "rheostat" potentiometer circuit [here](potentiometers.md#step-1-build-the-potentiometer-based-led-dimmer) (but we'll replace the rheostat with an FSR).
108108

109109
Below, we show two possible wiring diagrams: the first (preferred) shows the FSR circuit powered by a 9V battery while the second shows power derived from the 5V and GND pins on the Arduino. (Again, we prefer the former just to further emphasize that at this point, we're not using microcontrollers!)
110110

‎arduino/led-blink3.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ On the Arduino, the `unsigned long` data type is 32 bits (4 bytes), which ranges
126126

127127
#### Blinking without delays logic
128128

129-
We then use the same general logic as the "blinking without delays" [covered previously](led-blink#blink-without-using-delays) for each LED:
129+
We then use the same general logic as the "blinking without delays" [covered previously](led-blink.md#blink-without-using-delay) for each LED:
130130

131131
{% highlight C %}
132132
unsigned long currentTimestampMs = millis();

0 commit comments

Comments
 (0)