Making my content accessible

One Ruby script at a time

Hi 👋, I'mJason Gedge

Why?

Data sovereignty

I want to own my content
A robot holding an orange halo in its arms, in a garden, near a brick wall

Simplicity

I want to keep it simple
A graph with various edges and nodes, with some edges erased, and a red pencil and white eraser sitting nearby

Accessibility

Easily available to everyone
A bunch of people in a viewing area, looking at a copy of this presentation

Consistency

All presentations look and work the same way
A playground with two slides of roughly the same shape and colour

Learning

An opportunity to play around with some AI tech
A pencil sketch of a red textbook on a desk looking out at a classroom full of desks, with a window looking out at a tree

Fun

I enjoy writing code, especially little scripts
A watercolour with a canvas-like texture of a family in a park. Two parents sit on a gingham blanket, with children playing in the background with a kite. A city skyline can be seen in the distance.
A scrolling view of the Google Slides presentation being discussed in this presentation
A screenshot of the download options for a Google Slides presentation

ODP, what's that?

Open Document Format

"An XML schema for office documents. Office documents include text documents, spreadsheets, charts and graphical documents like drawings or presentations, and other forms of documents."
A screenshot of the ODP spec website
├── Pictures
│   ├── 10000000000002A80000017F6C1C798C.jpg
│   ├── 1000000000000438000002A33ABEA1C5.jpg
│   ├── 100000000000050000000355A29595A0.jpg
│   ├── 10000000000006AB00000800BEE43A5C.jpg
│   ├── 100000010000006400000080A8DBB75F.png
│   ├── ...
│   ├── 10000039000001E00000016AEBE3056B.gif
│   └── TablePreview1.svm
├── content.xml
├── meta.xml
├── settings.xml
└── styles.xml
<office:automatic-styles>
  <style:style style:family="drawing-page" style:name="dp1">
    <style:drawing-page-properties
      presentation:background-objects-visible="true"
      presentation:background-visible="true"
      presentation:display-date-time="false"
      presentation:display-footer="false"
      presentation:display-page-number="false"
    />
  </style:style>
</office:automatic-styles>
<office:body>
  <office:presentation>
    <draw:page
      draw:master-page-name="TITLE"
      draw:name="page1"
      draw:style-name="dp1"
      presentation:presentation-page-layout-name="AL1T0"
    >
      <!-- Slide content -->
    </draw:page>
  </office:presentation>
</office:body>
<draw:frame
  draw:name="Google Shape;63;p13"
  draw:text-style-name="P2"
  presentation:className="title"
  presentation:style-name="pr1"
  svg:height="2.5cm"
  svg:width="22cm"
  svg:x="1cm"
  svg:y="5cm"
>
  <draw:text-box>
    <text:p text:style-name="P1">
      <text:span text:style-name="T1">Building resilient systems</text:span>
    </text:p>
  </draw:text-box>
</draw:frame>
<presentation:notes draw:style-name="dp2">
  <draw:page-thumbnail draw:style-name="gr2" svg:height="11cm" svg:width="19cm" svg:x="1cm" svg:y="2cm" />
  <draw:frame draw:text-style-name="P7" svg:height="11cm" svg:width="15cm" svg:x="2cm" svg:y="12cm">
    <draw:text-box>
      <text:p text:style-name="P1">
        <text:span text:style-name="T1">Some notes</text:span> about the slide
      </text:p>
    </draw:text-box>
  </draw:frame>
</presentation:notes>
<draw:custom-shape
  draw:style-name="gr9"
  draw:transform="skewX (-0.00035) translate (3cm 2cm)"
  svg:height="6.5"
  svg:width="2cm"
>
  <draw:enhanced-geometry
    draw:enhanced-path="M 0 ?f5 L ?f8 ?f5 ?f8 0 ?f9 0 ?f9 ?f5 ?f14 ?f5 ?f7 ?f13 Z N"
    draw:text-areas="?f8 0 ?f9 ?f12"
    draw:type="ooxml-downArrow"
    svg:viewBox="0 0 0 0"
  >
    <draw:equation draw:formula="min(logwidth,logheight)" draw:name="f0" />
    <!-- ... -->
    <draw:equation draw:formula="logwidth" draw:name="f14" />
  </draw:enhanced-geometry>
</draw:custom-shape>
Let's create a plan for a script that can read in an open document presentation file and produce a set of MDX (markdown + react) files for each slide (for an example of an existing presentation, see @(../src/pages/presentations/2024-05-28_static_analysis_of_ruby.mdx).

## Requirements

- This should be a simple script. Keep the code short and simple, and all in one file.
- Read in an ODP file and produce an MDX file.
- Script should ask for the presentation date in the `YYYY-MM-DD` format (clearly specify this when prompting the user too).
- Look for a presentation name in the file. If one can't be found, prompt for it.
- The filename should be an "underscored" version of the date and title. For example, if the presentation date is July 17th, 1987 and the presentation is titled "Some cool stuff", the filename would be `1987_07_17_some_cool_stuff.mdx` (remove punctuation and any non-alphanumeric characters when producing the filename).
- Images should be placed in `./src/static/img/presentations/`, under a folder with the same name as the file (without the extension).
module Draw
  class Frame < Base
    include Mixins::PositionableElement

    def to_mdx
      style_object = generate_positioning_style_object
      <<~MDX
        <div style={#{style_object}}>
          #{content}
        </div>
      MDX
    end

    register_for "draw:frame"
  end
end

Heuristics

Convert cm → percentage

<----------- 27cm ----------->
┌─────────────────────────────┐
│      <------ 10cm ------>   │        x = 4cm / 27cm
│ 4cm  ┌──────────────────┐   │          ≈ 14.8%
│<---->│                  │   │
│      │                  │   │    width = 10cm / 27cm
│      │ draw:frame       │   │          ≈ 37.0%
│      └──────────────────┘   │
│ draw:page                   │
└─────────────────────────────┘

Centered slides

Combine adjacent spans

<span className="t12">text</span>
<span className="t12">with</span>
<span className="t13">the</span>
<span className="t12">same</span>
<span className="t12">style</span>
<span className="t12">text with</span>
<span className="t12">the</span>
<span className="t12">same style</span>

Remove empty/unused styles

Utility classes

.t1 {
  font-size: 12pt;
  font-weight: normal;
  font-decoration: none;
  color: #000000;
}
.t2 {
  font-size: 14pt;
  font-weight: bold;
  font-decoration: none;
  color: #000000;
}
.t3 {
  font-size: 12pt;
  font-weight: bold;
  font-decoration: none;
  color: #000000;
}
.c1 {
  font-size: 12pt;
}
.c2 {
  font-size: 14pt;
}
.c3 {
  font-weight: bold;
}

Demo time!

David Rose from CBC's Schitt's Creek saying 'I have asked you thrice'
David Rose from CBC's Schitt's Creek saying 'very uninterested in that option'
David Rose from CBC's Schitt's Creek saying 'what the actual fuck'
🥁
Kevin, from the office, saying 'it's bad'