` or ``. - write!(self.buf, "{}>", name.local).unwrap(); + write!(self.buf, "{}>", name.local).unwrap(); + } } _ => {} @@ -158,7 +184,7 @@ fn test_html_to_xhtml() { let expected = r#"
- +Test
diff --git a/tests/ref/examples/blog_post/epub/blog_post.metadata.json b/tests/ref/examples/blog_post/epub/blog_post.metadata.json index a3372ca..dcbd846 100644 --- a/tests/ref/examples/blog_post/epub/blog_post.metadata.json +++ b/tests/ref/examples/blog_post/epub/blog_post.metadata.json @@ -1,6 +1,6 @@ { "filetype": "epub", - "file_size": 6720367, + "file_size": 6720194, "title": "Blog Post", "language": "en", "spine_files": [ diff --git a/tests/ref/examples/blog_post/epub/xhtml/portable_epubs.xhtml b/tests/ref/examples/blog_post/epub/xhtml/portable_epubs.xhtml index e0386e8..936eda0 100644 --- a/tests/ref/examples/blog_post/epub/xhtml/portable_epubs.xhtml +++ b/tests/ref/examples/blog_post/epub/xhtml/portable_epubs.xhtml @@ -1,8 +1,8 @@ - - + +These pros and cons can be traced back to one key fact: the PDF representation of a document is fundamentally unstructured. A PDF consists of commands like:
Move the cursor to the right by 0.5 inches.
Set the current font color to black.
Draw the text "Hello World" at the current position.
+ Move the cursor to the right by 0.5 inches.
Set the current font color to black.
Draw the text "Hello World" at the current position.
PDF commands are unstructured because a document’s organization is only clear to a person looking at the rendered document, and not clear from the commands themselves. Reflowing, accessibility, data extraction, and interaction all rely on programmatically understanding the structure of a document. Hence, these aspects are not easy to integrate with PDFs.
This raises the question: how can we design digital documents with the benefits of PDFs but without the limitations?
@@ -45,17 +45,17 @@A simple answer is to improve the PDF format. After all, we already have billions of PDFs — why reinvent the wheel?
The designers of PDF are well aware of its limitations. I carefully hedged each bullet with “easily”, because PDF does make it possible to overcome each limitation, at least partially. PDFs can be annotated with their logical structure to create a tagged PDF. Most PDF exporters will not add tags automatically — the simplest option is to use Adobe’s subscription-only Acrobat Pro, which provides an “Automatically tag PDF” action. For example, here is a recent paper of mine with added tags:
If you squint, you can see that the logical structure closely resembles the HTML document model. The document has sections, headings, paragraphs, and links. Adobe characterizes the logical structure as an accessibility feature, but it has other benefits. You may be surprised to know that Adobe Acrobat allows you to reflow tagged PDFs at different screen sizes. You may be unsurprised to know that reflowing does not always work well. For example:
EPUB is a “distribution and interchange format for digital publications and documents”, per the EPUB 3 Overview. Reductively, an EPUB is a ZIP archive of web files: HTML, CSS, JS, and assets like images and fonts. On a technical level, what distinguishes EPUB from archival formats is that EPUB includes well-specified files that describe metadata about a document. On a social level, EPUB appears to be the HTML publication format with the most adoption and momentum in 2024, compared to moribund formats like Mobi.
The EPUB spec has all the gory details, but to give you a rough sense, a sample EPUB might have the following file structure:
sample.epub
├── META-INF
│ └── container.xml
└── EPUB
├── package.opf
├── nav.xhtml
├── chapter1.xhtml
├── chapter2.xhtml
└── img
└── sample.jpg
+ sample.epub
├── META-INF
│ └── container.xml
└── EPUB
├── package.opf
├── nav.xhtml
├── chapter1.xhtml
├── chapter2.xhtml
└── img
└── sample.jpg
An EPUB contains content documents (like chapter1.xhtml and chapter2.xhtml) which contain the core HTML content. Content documents can contain relative links to assets in the EPUB, like img/sample.jpg. The navigation document (nav.xhtml) provides a table of contents, and the package document (package.opf) provides metadata about the document. These files collectively define one “rendition” of the whole document, and the container file (container.xml) points to each rendition contained in the EPUB.
The EPUB format optimizes for machine-readable content and metadata. HTML content is required to be in XML format (hence, XHTML). Document metadata like the title and author is provided in structured form in the package document. The navigation document has a carefully prescribed tag structure so the TOC can be consistently extracted.
@@ -93,27 +93,27 @@Finding a balance between consistency and flexibility is arguably the most fundamental design challenge in attempting to replace PDF with EPUB. To navigate this trade-off, we first need to talk about EPUB reading systems, or the tools that render an EPUB for human consumption. To get a sense of variation between reading systems, I tried rendering this post as an EPUB (without any styling, just HTML) on four systems: Calibre, Adobe Digital Editions, Apple Books, and Amazon Kindle. This is how the first page looks on each system (omitting Calibre because it looked the same as Adobe Digital Editions):
Calibre and Adobe Digital Editions both render the document in a plain web view, as if you opened the HTML file directly in the browser. Apple Books applies some styling, using the New York font by default and changing link decorations. Amazon Kindle increases the line height and also uses my Kindle’s globally-configured default font, Bookerly.
As you can see, an EPUB may look quite different on different reading systems. The variation displayed above seems reasonable to me. But how different is too different? For instance, I was recently reading A History of Writing on my Kindle. Here’s an example of how a figure in the book renders on the Kindle:
When I read this page, I thought, “wow, this looks like crap.” The figure is way too small (although you can long-press the image and zoom), and the position of the figure seems nonsensical. I found a PDF version online, and indeed the PDF’s figure has a proper size in the right location:
This is not a fully fair comparison, but it nonetheless exemplifies an author’s reasonable concern today with EPUB: what if it makes my document looks like crap?
@@ -127,7 +127,7 @@If someone wants to write a document such as this post, then that person need not be a frontend web developer to feel confident that their document will render reasonably. Conversely, if someone wants to stuff the entire Facebook interface into an EPUB, then fine, but it’s on them to ensure the document is responsive.
For instance, one simple version of portable HTML could be described by this grammar:
Document ::= <article> Block* </article>
Block ::= <p> Inline* </p> | <figure> Block* </figure>
Inline ::= text | <strong> Inline* </strong>
+ Document ::= <article> Block* </article>
Block ::= <p> Inline* </p> | <figure> Block* </figure>
Inline ::= text | <strong> Inline* </strong>
The EPUB spec already defines a comparable subset for navigation documents. I am essentially proposing to extend this idea for content documents, but as a soft constraint rather than a hard constraint. Finding the right subset of HTML will take some experimentation, so I can only gesture toward the broad solution here.
Worse, EPUB reading systems often don’t give you appropriate control over rendering an EPUB. For example, to emulate the experience of reading a book, most reading systems will chunk an EPUB into pages. A reader cannot scroll the document but rather “turn” the page, meaning textually-adjacent content can be split up between pages. Whether a document is paginated or scrolled should be a reader’s choice, but 3/4 reading systems I tested would only permit pagination (Calibre being the exception).
Therefore I decided to build a lighter EPUB reading system, Bene. You’re using it right now. This document is an EPUB — you can download it by clicking the button in the top-right corner. The styling and icons are mostly borrowed from pdf.js. Bene is implemented in Tauri, so it can work as both a desktop app and a browser app. Please appreciate this picture of Bene running as a desktop app:
Bene is designed to make opening and reading an EPUB feel fast and non-committal. The app is much quicker to open on my Macbook (<1sec) than other desktop apps. It decompresses files on-the-fly so no additional disk space is used. The backend is implemented in Rust and compiled to Wasm for the browser version.
@@ -173,7 +173,7 @@Encapsulating Scripts with Web Components
But what if a document wants to provide an interactive component that isn’t natively supported by the reading system? For instance, I have recently been working with The Rust Programming Language, a textbook that explains the different features of Rust. It contains a lot of passages like this one:
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {x}");
}
println!("The value of x is: {x}");
}
+ let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {x}");
}
println!("The value of x is: {x}");
}
This program first binds x to a value of 5. Then it creates a new variable x by repeating let x =, taking the original value and adding 1 so the value of x is then 6. Then, within an inner scope created with the curly brackets, the third let statement also shadows x and creates a new variable, multiplying the previous value by 2 to give x a value of 12. When that scope is over, the inner shadowing ends and x returns to being 6. When we run this program, it will output the following:
A challenge in reading this passage is finding the correspondences between the prose and the code. An interactive code reading component can help you track those correspondences, like this (try mousing-over or clicking-on each sentence):
@@ -191,7 +191,7 @@The interactive code description component is used as follows:
<code-description>
<pre><code>fn main() {
let <span id="code-1">x</span> = <span id="code-2">5</span>;
<!-- rest of the code... -->
}</code></pre>
<p>
<code-step>This program first binds <a href="#code-1"><code>x</code></a> to a value of <a href="#code-2"><code>5</code></a>.</code-step>
<!-- rest of the prose... -->
</p>
</code-description>
+ <code-description>
<pre><code>fn main() {
let <span id="code-1">x</span> = <span id="code-2">5</span>;
<!-- rest of the code... -->
}</code></pre>
<p>
<code-step>This program first binds <a href="#code-1"><code>x</code></a> to a value of <a href="#code-2"><code>5</code></a>.</code-step>
<!-- rest of the prose... -->
</p>
</code-description>
Again, the document content contains no actual script. It contains a custom element <code-description>, and it contains a series of annotations as spans and anchors. The <code-description> element is implemented as a web component.
Web components are a programming model for writing encapsulated interactive fragments of HTML, CSS, and Javascript. Web components are one of many ways to write componentized HTML, such as React, Solid, Svelte, and Angular. I see web components as the most suitable as a framework for portable EPUBs because:
diff --git a/tests/ref/examples/blog_site/epub/blog_site.metadata.json b/tests/ref/examples/blog_site/epub/blog_site.metadata.json index 3d246ea..898d337 100644 --- a/tests/ref/examples/blog_site/epub/blog_site.metadata.json +++ b/tests/ref/examples/blog_site/epub/blog_site.metadata.json @@ -1,6 +1,6 @@ { "filetype": "epub", - "file_size": 4665720, + "file_size": 4665620, "title": "Screening the Subject | Severance", "language": "en", "spine_files": [ diff --git a/tests/ref/examples/blog_site/epub/xhtml/severance-ep-1.xhtml b/tests/ref/examples/blog_site/epub/xhtml/severance-ep-1.xhtml index 3e63eaf..99d576b 100644 --- a/tests/ref/examples/blog_site/epub/xhtml/severance-ep-1.xhtml +++ b/tests/ref/examples/blog_site/epub/xhtml/severance-ep-1.xhtml @@ -1,22 +1,22 @@ - - + +Good news about hell - Severance [s1/e1]
-The first thing to notice is the colour palette. She is dressed in blue, but her hair is chestnut red. It spills out for the frame of her figure into the table around it, blockaded at its border by chairs and a carpet clad in green, yellow, then green again; then gray. The establishing shot is a bird’s eye view of an unknown woman who is soon revealed to have been put in the board room by someone else’s design, who learns about her predicament only by a man’s voice that emanates from the little device that rests on the table along with the woman, arranged so that it aims directly at her head.
This opening image is a graph of the subject’s predicament on the severed floor at Lumon. Blue is the company colour. Employees are almost invariably dressed in shades of it– navy, midnight, Prussian, Oxford, cobalt– and more reliably so as we work our way up the hierarchy. Red is unruly passion, the tone of tempers that itch to tear off the straitjacket directives, to disregulate the business-as-usual in which there is no obvious place for illicit activities. Green is the accent of Macro Data Refinement, the division of Lumon in which the show’s protagonists are employed. The device directs a man’s voice at a woman’s body in an attempt to keep her tempers in check, to ensure her firecraft does not smoke out the staid edifice of personality management, to order her “perceptual chronologies” accordingly. (Later in the episode, we learn that she almost manages to “break in” on the control room during that opening sequence: the solidity of its enclosure is threatened from the very first.)
It is instructive to attempt to articulate the dynamics that this graph indexes before we start talking about other scenes in the show. Graphs are not at one with what they represent, for in the decision to render ‘data’ in the very act of a representation, we both lose and gain distinction of the dynamics in question. The voice that opens Helly R up to the world of Lumon’s severed floor begins: “Who are you?” This question is a mistake. We retroactively learn, in a later scene, that Mark S was in fact supposed to begin with a less interrogative, more perfunctory: “Hi there, you on the table. I wonder if you’d mind taking a brief survey.” As Irving puts it: “You [Mark S] skipped the preamble”. Helly R is thrust, by this accident, immediately into questioning not only herself, but also the self-assurance of the voice that interrogates her. Does this voice in my head [she could be thinking] really know what it is doing? Or is it just a role of similarly confused actors struggling to stick to a badly written script?
This episode-length recap of the first episode names this graph ‘the Helly incident’, a poorly executed orientation of Helly’s newfound subjectivity that can be blamed at one level on Mark S (for starting with the wrong part of the manual), at another on Mr. Milchick (for misguiding Mark while he was distracted setting up the visual feed), on Ms. Cobel (for giving Mark Petey K’s old manual without redacting his obscurely scribbled notes and paper bookmarks), or even on Irving (for neglecting to intervene and clarify how Mark should begin being the more senior refiner in the situation: “Irving will be there to shadow. Just stick to the flowchart and escalate properly depending on dialectics.”). Wherever to place blame, there is doubtless a misconfiguration that takes place. Helly’s instinctual reaction seems to be to try to kill the voice pointed at her head, rather than to befriend it as Mark states he did (where Petey was Mark). (Helly will eventually have sex with the source of the voice, rather than murdering or fraternizing with it.) In this episode, however, Mark (the voice’s source) is physically assaulted by Helly, dented in his temple by the same vocalization device that mediated their first communication.
-So this is the Macro Data refiner’s situation. On the one hand, she is affronted with a voice that compels her to abide by the rules and permits her to enjoy some small reliefs (egress from a locked room) if she concedes to it. On the other, she is always teeming and thus flirting with red, considering escape routes that involve drawing blood, setting off alarms, or removing clothes.
This unruly red is what Macro Data Refinement’s greening procedures are supposed to contain to produce a completely controlled and scripted blot of blue. Perhaps this is why the glipse of the vacant desks planned for the severed floor’s expansion are draped in purple, for that shade of subjectivity would better incorporate the contrasting contours into a unified and taskable tone. The red that threatens Lumon’s corporate, calm, and collected blue (the Lumon logo is a water droplet that suspiciously resembles a camera) is splattered across scenes in the episode. It is, for example, the envelope that Petey slips Mark at the company-owned restaurant Pip’s with the suggestion that he should read it if he wants to know “what’s going on down there”. It is the sweater Mark wears to his sister’s dinnerless dinner party, punctuated by red place mats (“what a lot of people overlook, I think, is that life is not food”), where the ontological substance of his innie is called into question, and where we learn about the passions he has lost– the history of World War II, educating, whiskey– the last of which seems to have given way to an indiscriminate consumption of beer, wine, anything that will drown out the clarity of sober consciousness. It is the general hue of his sister’s house, which consisently wants him to question that placid blue of his company-subsidized housing at Baird Creek Manor.
This dinner tells us something more about the subject in question in Severance. Just as Helly’s outie had alerted us to the basic principle in the video her innie was shown in curiously lo-fi resolution to conclude her innie’s orientation– “perceptual chronologies… surgically split”– Mark’s predicament is comparably explained to him by another more or less ignorant (we can’t help but imagine) third party: “One’s memories are bifurcated, so when you’re at work, you have no recollection of what it is you do there.” As pretentious as they are, the dinner’s guests do seem to be attuned to an important dimension of the meaning of life, which is that it can’t only be about satiating biological needs such as food. What each individual ‘needs’ is a disharmonious melange of needs and demands, openings of desire that emerge not only through a graph of bare necessities– food, water, shelter– but also through capricious carapaces that emerge from more ambiguous pinings in the social sphere– company, care, love. The real question of Lumon’s smooth functioning is whether it will be able to effectively plug up these pinings, the incidental moments at work where one wonders what one is really doing with one’s life, whether the company can really manage its employees’ unsanctioned thoughts and the way in which those illicit ideas seep into the daily practice of their workerhood. More on the plasticity of our needs and drives to satisfy them in later posts.
-Ms. Cobel, in contrast to Helly’s and Mark’s doubtful and doubting red, is a stormy and icy blue. (We must wait until season two to uncover the historical and psychological depth of this colour for Harmony Cobel.) She is the figure with a body that seems to be the most in charge, of those we meet in this episode. Though Ms. Cobel is not a master in herself, it seems, for she too is subjected to a disembodied voice-via-device, ‘the board’, albeit which only appears evidently as an ear so far (“The board won’t be contributing to this meeting vocally”). Cobel is responsible for keeping the severed floor’s uncertainty in check, the ‘head’ that sits atop the variegated limbs of its disobedient body.
When Cobel reprimands Mark for his derailing of Helly’s orientation, she recalls an obscure and theological aspect of her parentage:
You know, my mother was an atheist. She used to say that there was good news and bad news about hell. The good news is, hell is just the product of a morbid human imagination. The bad news is, whatever humans can imagine, they can usually create.@@ -32,8 +32,8 @@
So the subject’s subjectivity is marked by its sense of time, and Lumon’s success (profitability?) hinges in some way on altering their employees’ stable sense of it while in the space of the severed floor.
Mark S’s temporal predicament here has been explained by a man whose last name we get by speeding up the saying of his own, Karl Marx (Mar-k-S). Logically speaking, Marx argues, there is an amount of time that goes missing in the worker’s employment by way of a wage, when he advances some portion of his time to the capitalist in exchange for a pay-check one or more weeks later. I refer the reader interested in the details to chapter 20 of Capital Vol. I: but the essential point here is that it is through an obfuscation of the real value of a worker’s time that the capitalist manages to produce surplus-value. The production of this kind of time-distorted surplus-value is the engine of capitalism as a social relation that appears, on the surface, to be equally fair to capitalist and worker alike. So the project of controlling ‘perceptual chronologies’ with which Lumon seems to be so concerned is perhaps not as esoteric and inessential as it might at first seem. Perhaps it is an embodiment of the core ingredient of the company’s success as a company, of its incorporation as an entity that ought to be sustained even at the expense of its members’ happiness, their health, and their livelihoods.
+
- Home
- Learn more about me diff --git a/tests/ref/examples/blog_site/epub/xhtml/severance-ep-2.xhtml b/tests/ref/examples/blog_site/epub/xhtml/severance-ep-2.xhtml index 58f2971..ea52878 100644 --- a/tests/ref/examples/blog_site/epub/xhtml/severance-ep-2.xhtml +++ b/tests/ref/examples/blog_site/epub/xhtml/severance-ep-2.xhtml @@ -1,20 +1,20 @@ - - + +
- Home
- Learn more about me diff --git a/tests/ref/examples/blog_site/epub/xhtml/severance-ep-3.xhtml b/tests/ref/examples/blog_site/epub/xhtml/severance-ep-3.xhtml index 3326795..94ab97b 100644 --- a/tests/ref/examples/blog_site/epub/xhtml/severance-ep-3.xhtml +++ b/tests/ref/examples/blog_site/epub/xhtml/severance-ep-3.xhtml @@ -1,13 +1,13 @@ - - + +
- Home
- Learn more about me diff --git a/tests/ref/examples/epub_inferred_spine/epub/epub_inferred_spine.metadata.json b/tests/ref/examples/epub_inferred_spine/epub/epub_inferred_spine.metadata.json index 9dd27d1..8609744 100644 --- a/tests/ref/examples/epub_inferred_spine/epub/epub_inferred_spine.metadata.json +++ b/tests/ref/examples/epub_inferred_spine/epub/epub_inferred_spine.metadata.json @@ -1,6 +1,6 @@ { "filetype": "epub", - "file_size": 4112, + "file_size": 4076, "title": "Epub Inferred Spine", "language": "en", "spine_files": [ diff --git a/tests/ref/examples/epub_inferred_spine/epub/xhtml/a.xhtml b/tests/ref/examples/epub_inferred_spine/epub/xhtml/a.xhtml index a3f0bb8..3170581 100644 --- a/tests/ref/examples/epub_inferred_spine/epub/xhtml/a.xhtml +++ b/tests/ref/examples/epub_inferred_spine/epub/xhtml/a.xhtml @@ -1,8 +1,8 @@ - - + +
- Math(s), Philosophy, History, a long-running online ~bi-weekly reading group.
- By specifying configuration in a
rheo.tomlfile at the root of the project directory.
Half Loop - Severance [s1/e2]
In the first episode, we were introduced to the two-sided subject at Lumon. On the one hand, there is Mark S, the innie, who is screened for the first and major part of the episode. On the other, Mark Scout, the outie, to whose predicament we are introduced in the concluding scenes. S1E2 opens with a rewind on how innie Helly R came to be: how Milchick handed her flowers at end of her first day (which we glimpsed in S1E1 when Mark almost ran her over), a glimpse of her confidence gliding into the operating room on a higher floor of the same Lumon complex we saw Mark leave, a stereoscopic view of the implant procedure by which she becomes an android whose existence is “spatially dictated” by Lumon’s mysterious machinations.
Lumon Industries
-Lumon is a corporate pastiche, and not only of technology companies. Lumon seems to have its hands in surgical hardware (the operating room equipment), digital technology (‘Macrodata Refinement’), and medicines and topical salves (as discussed at the dinner party in S1E1 - “What don't they make?”). It is a quintessentially American jack of all trades, a global power in its own right cohered by a family dynasty—the Eagans—recalling the Du Ponts or the Rockefellers.
The more obvious comparison to make, however, is between Lumon and Apple, perhaps in part because the show screens on Apple TV Plus. The style of the computers on the severed floor recalls the dawn of the era of personal computing in the 1970s and 80s, an aesthetic imaginary in which Apple plays an important role.
Indeed, the aura of Lumon as a futuristic computing corporation from the late 70s is reinforced by the fact that its headquarters are shot at Bell Labs in New Jersey, a building that has now been renovated as a mixed-use office for high-tech startup companies as Bell Works. Bell Labs is the quasi-mythological source in the contemporary corporate technology culture (Silicon Valley) of the idea that a certain kind of research freedom characterized by open-ended product delivery timelines and serendipitous encounters in open office plans can cultivate ground-breaking technology. (Mark Zuckerberg recommended a book on Bell Labs as one of his “important books” of 2015.) The irony of this setting, of course, both in Severance and in the technology companies it parodies in the American landscape in 2025, is that the workplace has never been more saturated with surveillance and micro-management. The overhead shot of Helly R that opened the series is indicative here again, as is the complementary overhead of MDR’s desks we get in this episode: there is always something watching from above, it seems, even if what it captures of the actual activity is a flattened and at times misrepresentative image.
There are also evocations of Microsoft and IBM in Lumon, such as the Clippy-like guide on the manual handed to Helly in the episode, or the apparent requirement of suits on the severed floor echoing IBM’s infamous strict dress code. Lumon is a melange of imaginary pasts, presents, and futures in American innovation. It is futuristic in the framing of its bio-technological project of perceptual management—and in the “data smuggling” detectors that are installed in the elevators to the severed floor, about which more soon—but retrofitted in its aesthetic, in its management style, and in its outdated repertoire of daily devices. Recall, for example, Milchick’s handheld camcorder, and the tube-activated (vacuum-tube?) camera he uses to snap the official photo of the new group of refiners.
-The overhead of Lumon Industries itself depicts a sketchy graph of a brain, one can’t help but think. Its upper floors all operate above board with normally conscious workers, whereas underground there is something sensitive enough happening so as to require extra precautions. In S1E1′s analysis, we introduced the idea that Lumon’s interest in severing workers has to do with the mechanics of capital, in that surplus value can only ever be produced (in Marx’s account) through the structural theft of time from its laborers.1 Lumon’s spatial layout suggests that there might also be a psychoanalytic metaphor at stake in severance as an operation, where the happenings that occur in the business brain’s basement are essential to what it really is, why it does what it does.
Though Freud’s theory has been popularized as a topographical notion, wherein the unconscious is the submerged part of the mind’s iceberg of which we only see the tip, there is good reason to believe that this spatial description misrepresents how the unconscious should be properly understood. Lacan thus preferred topological descriptors to suggest that, if the unconscious is a ‘place’ or ‘site’, it contradicts any over-simplistic understanding of spaces that are distinctly separable. The relationship between the conscious and the unconscious in a psychoanalytic theory of the subject, I would suggest, is better understood through the figure of a coin with two inseparable sides. The meaning of any one side (‘heads’) derives from the meaning of its opposite (‘tails’); and it is thus insensible to imagine separating one part from the other without repressing something fundamental about the structure of the subject as a whole.
Lumon, though, seems to want desperately to keep innies from being in contact with their outies. Indeed, the very project of severance seems to have something fundamental to do with managing repression effectively, with renovating the worker into a perfectly divided self that cannot complain about the conditions of her labor through the fact of not knowing anything about them. (When Mark is given a dinner coupon on account of his head injury in S1E1, the real cause of the scar—Helly R’s riotous attempt to escape the orientation room—is not revealed to outie Mark.) The subject in Severance is split and maintained as such. The ‘unconscious’ of one’s home life should not affect one’s ‘conscious’ ability to perform at work.
@@ -32,8 +32,8 @@Indeed, the audio recording that innie/outie Petey shows outie Mark in his hideout at the greenhouse reveals the insecurity of symbol detection at Lumon. In order to get a recording of what he was subjected to in the Break Room, he must have been able to get that retro handheld device back up into the ‘real’ world. So either the elevators weren’t able to pick it up, or there is some other way for innies to move between the supposedly demarcated spaces. Either way, the symbol policing at the innie/outie border seems to have some shortcomings.
A brief note on Petey’s dishevelled greenhouse to conclude, as this episode is where we are first introduced to much of the geography that will become important in the series: the break room, wellness, MDR, optics and design, Mark’s basement, the company restaurant (where Mark has his insufferably awkward date), the elevator, the MDR kitchen, the operating room, the Lumon foyer. Petey’s greenhouse, like many of the spaces in Severance, is a graph that both embodies and reflects a psycho-social moment of the show. Green like Macrodata Refinement, but much less put-together, the greenhouse reveals the underside of Lumon’s apparent glaem, the unconscious damage that its project of perfection wreaks on its workers psychologically and physically. Petey shows us that the worker, like so many words and things in the show, is not simply what it seems, but consists also of an excess signification that inevitably creeps into its conspicuous comportment. Mark is a depressed drunkard on the outside, and Irving (it seems) has his fingers in some hellish kind of black pie, a color that takes over his desk as he dozes off when he lets the distinction between his waking and unconscious self slip, we might say, when the reality of sleep threatens the security of being awake. There is, as the imagery in the poster of the ‘Whole Mind Collective’ that motivates Mark to bunk off and follow up on Petey’s enigmatic red letter suggests, a real revolution of sorts brewing beneath the surface of a fantasy of symbolic control.
+
In Perpetuity - Severance [s1/e3]
-We need to talk about Ms. Cobel
As we noted in analysis of S1E1, she typically storms the screen with an icy blue, a temper (the significance of this word we shall unpack shortly) that seeks to quell the fiery red that flickers in and out of the consciousness of workers on the severed floor. The ominous ending to that first episode intimated that, while her wintery business has its office underground, it also warrants her prying into Mark’s outie’s personal life in Baird Creek’s subsidized Lumon housing. Indeed, it seems that Miss Cobel lives in Mark’s housing complex, too. From the state of her fridge, though, which we see in the foreground of a shot that implies surreptitious surveillance at work in her intimate space– a sense that has already been produced in Mark’s home with objects littered in the frame’s foreground– it doesn’t appear that she spends very much time making a home there. (Not too unlike Mark, perhaps.)
Ms. Cobel is a kaleidoscopic vector of strange femininity in the show. She is at once old widow next door, a girl-boss superior on the severed floor, and a little girl prone to tantrums. As Mrs. Selvig, the hare-brained widow next door, she offers Mark unwanted company and cruddy cookies. Yet we know by now that this is apparanetly a ruse, a senile disguise through which the conniving Harmony Cobel can keep an eye on her employee, Mark, beyond the bounds of his time at work. At Baird Creek, she is a middle-aged executive in the clothing of an older and less cognitively composed character.
@@ -28,7 +28,7 @@Freud offers this as an “historic explanation… [of] the origin of incest” (Freud 1919, p.207), as the Primal Father’s taboo on enjoyment is what, Freud suggests, drives exogamy, wherein each of the band of brothers leaves that original tribe to start their own in which they can (finally) enjoy the women for themselves. That this is an historic explanation does not mean that Freud believes that it represents an actual state of affairs in some distant past. Indeed, he states the opposite, that “primal state of society has nowhere been observed.” (Freud 1919, p.233) The parable of the Primal Father is historic rather in the sense that narrates to us an important aspect of the structure of the subject, much like Oedipus’ tragedy.
Daddy issues at work
Okay: we now return from this Freudian digression to the stuff of Severance. What bearing do the Oedipus complex and the myth of the Primal Father have on the structure of the subject on display in the show? Let’s go now to the scene in S1E3 at the crossroads, where MDR runs into two employees in Optics and Design (O&D).
-The composition of this shot puts the reflective axis down the center, and the encounter is suggestively Oedipean in its structure (at a crossroads, unknowing of the Other at play). Note that Irving is compositionally mirrored by Burt, played by Christopher Walken, and we will explore this suggestive symmetry in detail in later episodes. The two departments (MDR and O&D) know of each other, we surmise from the dialogue that follows. But Irving isn’t supposed to know Burt by name, as he accidentally happened upon him in S1E2 on the way to a Wellness session. (Burt was coming from his Wellness session.)
While Irving greets Burt on the back of this previous encounter with gentle and flirtatious warmth, Dylan’s hostility towards O&D is clear. In place of the camaraderie that one might have hoped for between the two factions given their shared plight as severed workers, there appears to be an enmity built on a mythology (what Irving calls an “absolute fiction”) of otherness:
Kier sorted the departments by virtue. Macrodats are clever and true, while O&D’s more cruelty-centered…. O&D tried a violent coup on the others decades ago, and that’s why they reduced them down to two. And that’s why they keep us all so far apart now.@@ -39,7 +39,7 @@
The count of four in the members of MDR mirrors the exact amount of tempers that we learn about from Kier Eagan’s wax simulacrum speaking during the tour of the Perpetuity Wing. These tempers are crucial as coordinates of the Eaganic attempt to coherently quantify the subject, and Kier’s pronouncement is deeply significant for our investigation of the subject’s distorted structure on the severed floor:
I know that death is near upon me, because people have begun to ask what I see as my life’s great achievement. They wish to know how they should remember me as I rot. In my life, I have identified four components, which I call tempers, from which are derived every human soul. Woe. Frolic. Dread. Malice. Each man’s character is defined by the precise ratio that resides in him. I walked into the cave of my own mind, and there I tamed them. Should you tame the tempers as I did mine, then the world shall become but your appendage. It is this great and consecrated power that I hope to pass on to all of you, my children.
If there was any doubt that Kier Eagan embodies the Freudian Primal Father, the foundational component of absolute fiction on which the edifice of Law (the rules and taboos by which a subject is bound to abide) is constructed, the quotation above should put it to bed. Kier’s ‘philosophy’ seeks to conquer death by quantifying life, sorting its myriadic nature into a “precise ratio” of character that can be counted (completely, it seems) in four distinct tempers. Indeed, we saw the pictorial representation of this taming in s1e2, in the scene where Irving meets Burt:
-In the post-Platonic cave of his own mind, Kier is the master of his passions. He admits no unconscious contours that sneak up on him unbeknowst in Freudian slips of the tongue or unwanted symptoms. Indeed, the Eaganesque fantasy of the subject is one in which the necessary excess of language that psychoanalysis discovered does not exist. Words are detected (via sensors in the elevator, say), controlled, managed. Any psychoanalytic excess is, in Kier’s project of a precisely rationalized subject, beaten out of language. Excess meaning is ‘tamed’ as if it were a wild animal by a clear-headed, upstanding, divinely radiant visonary. (As we will see, the position of primal power that Kier occupies here is sexually overbearing, too, as we might suspect from the Freudian analogy.)
This episode ends with two scenes depicting the dark and bloody underside of Kier’s waxen vision of the precisely quantified human subject. The first is Helly’s harrowing experience in the break room, a space where the unruly distance between words as they are uttered and the meaning they convey is thought to be stamped out, suffocated by the drudgery of debilitating repetition. A subject will not exceed its authorized symbolization, the break room seems to want to claim. The worker’s unconscious will be tamed and ultimately made beholden to a regime of conscious rationality. The second, and the closing scene of the epsiode, is Petey’s psychotic demise at the convenience store, where he yells at wit’s end: “I need tokens so I can eat!” Ravaged by the failure of his complete quantification inside Lumon, Petey seems no longer to have a firm footing in either his innie’s or outie’s reality. Mark looks on from a distance as he collapses outside the store, escorted by police, attempting (it seems) to account for his disintegration.
+
The free computing lab researches the nature of computing freedom. Our research aims to demonstrate the role that the computer could and should play in a society where freedom is flourishing rather than deprecated, and to cultivate a critically grounded practice of software production, development, and maintenance.
See our GitHub page for code and more information. You can also join our Zulip to ask questions and follow our research, or drop us a note at hi@ohrg.org.
Our projects include:
@@ -14,8 +14,8 @@People
- -Document 1
diff --git a/tests/ref/examples/link_transformation/epub/xhtml/doc2.xhtml b/tests/ref/examples/link_transformation/epub/xhtml/doc2.xhtml index 31c8c84..ed92cb5 100644 --- a/tests/ref/examples/link_transformation/epub/xhtml/doc2.xhtml +++ b/tests/ref/examples/link_transformation/epub/xhtml/doc2.xhtml @@ -1,8 +1,8 @@ - - + +Document 2
diff --git a/tests/ref/examples/links_with_fragments/epub/links_with_fragments.metadata.json b/tests/ref/examples/links_with_fragments/epub/links_with_fragments.metadata.json index ff5aaa8..6519a0d 100644 --- a/tests/ref/examples/links_with_fragments/epub/links_with_fragments.metadata.json +++ b/tests/ref/examples/links_with_fragments/epub/links_with_fragments.metadata.json @@ -1,6 +1,6 @@ { "filetype": "epub", - "file_size": 4412, + "file_size": 4388, "title": "Links with Fragments Test", "language": "en", "spine_files": [ diff --git a/tests/ref/examples/links_with_fragments/epub/xhtml/page1.xhtml b/tests/ref/examples/links_with_fragments/epub/xhtml/page1.xhtml index e09a2a1..446615e 100644 --- a/tests/ref/examples/links_with_fragments/epub/xhtml/page1.xhtml +++ b/tests/ref/examples/links_with_fragments/epub/xhtml/page1.xhtml @@ -1,8 +1,8 @@ - - + +Page 1
diff --git a/tests/ref/examples/links_with_fragments/epub/xhtml/page2.xhtml b/tests/ref/examples/links_with_fragments/epub/xhtml/page2.xhtml index 5a697ff..d687b03 100644 --- a/tests/ref/examples/links_with_fragments/epub/xhtml/page2.xhtml +++ b/tests/ref/examples/links_with_fragments/epub/xhtml/page2.xhtml @@ -1,8 +1,8 @@ - - + +Page 2
diff --git a/tests/ref/examples/rheo_docs/epub/rheo_docs.metadata.json b/tests/ref/examples/rheo_docs/epub/rheo_docs.metadata.json index 86c6b67..ef3dec9 100644 --- a/tests/ref/examples/rheo_docs/epub/rheo_docs.metadata.json +++ b/tests/ref/examples/rheo_docs/epub/rheo_docs.metadata.json @@ -1,6 +1,6 @@ { "filetype": "epub", - "file_size": 53115, + "file_size": 52727, "title": "Rheo Manual", "language": "en", "spine_files": [ diff --git a/tests/ref/examples/rheo_docs/epub/xhtml/build-dir.xhtml b/tests/ref/examples/rheo_docs/epub/xhtml/build-dir.xhtml index 3c847e0..3dc499a 100644 --- a/tests/ref/examples/rheo_docs/epub/xhtml/build-dir.xhtml +++ b/tests/ref/examples/rheo_docs/epub/xhtml/build-dir.xhtml @@ -1,14 +1,14 @@ - - + +Build directory
Rheo produces outputs in a simple directory structure with one subdirectory for each kind of output. By default, Rheo produces all outputs (PDF, HTML, and EPUB) in a build directory instide the project directory:
build/
├── epub
│ └── blog_post.epub
├── html
│ ├── portable_epubs.html
│ └── style.css
└── pdf
└── portable_epubs.pdf
+ build/
├── epub
│ └── blog_post.epub
├── html
│ ├── portable_epubs.html
│ └── style.css
└── pdf
└── portable_epubs.pdf
The build directory path is calculated relative to the content directory. This is important, as if you change the content directory, then your build directory path will become relevant to that directory.
Configuration
CLI flag
diff --git a/tests/ref/examples/rheo_docs/epub/xhtml/content-dir.xhtml b/tests/ref/examples/rheo_docs/epub/xhtml/content-dir.xhtml index 7137d80..8d7afbe 100644 --- a/tests/ref/examples/rheo_docs/epub/xhtml/content-dir.xhtml +++ b/tests/ref/examples/rheo_docs/epub/xhtml/content-dir.xhtml @@ -1,8 +1,8 @@ - - + +Frequently Asked Questions
What is the difference between Typst and Rheo?
Typst is a markup/programming language that provides its own toolchain which includes a CLI. You can use the Typst CLI to compile one Typst document to one kind of output file:
-typst compile source.typ # compile to PDF
typst compile --features html --format html source.typ # compile to HTML
+ typst compile source.typ # compile to PDF
typst compile --features html --format html source.typ # compile to HTML
Rheo compiles a project folder to three outputs—PDF, HTML, and EPUB—concurrently. It allows you to configure how certain source files should be merged (to produce a ‘combined’ EPUB or PDF file, for example, via spines), and also allows you to enrich certain outputs (such as HTML via custom CSS) with non-Typst content. Rheo supports EPUB natively, which is not currently supported by the upstream Typst CLI (though it is on the roadmap). In summary, Rheo is a opinionated way to manage writing projects with Typst.
How do I read EPUBs on my system?
Mileage varies greatly on EPUB reading niceness across systems! If you’re interested to learn more, we have written more about this here. If you don’t have a good EPUB reading experience currently, we recommend trying bene, an EPUB reading system that we are developing.
diff --git a/tests/ref/examples/rheo_docs/epub/xhtml/formats.xhtml b/tests/ref/examples/rheo_docs/epub/xhtml/formats.xhtml index 1b4a38b..7df3468 100644 --- a/tests/ref/examples/rheo_docs/epub/xhtml/formats.xhtml +++ b/tests/ref/examples/rheo_docs/epub/xhtml/formats.xhtml @@ -1,8 +1,8 @@ - - + +Configuration
CLI flag
You can constrain Rheo to producing one or more formats by passing one or more of the following flags to compile or watch:
rheo compile path/to/project --pdf
rheo compile path/to/project --html
rheo compile path/to/project --epub
+ rheo compile path/to/project --pdf
rheo compile path/to/project --html
rheo compile path/to/project --epub
rheo.toml
You can also specify formats at the top level of rheo.toml in an array that contains one or more formats. The default, if formats is not specified, is an array with all three formats:
formats = ["pdf", "html", "epub"]
diff --git a/tests/ref/examples/rheo_docs/epub/xhtml/getting-started.xhtml b/tests/ref/examples/rheo_docs/epub/xhtml/getting-started.xhtml
index 86ebfe4..a351883 100644
--- a/tests/ref/examples/rheo_docs/epub/xhtml/getting-started.xhtml
+++ b/tests/ref/examples/rheo_docs/epub/xhtml/getting-started.xhtml
@@ -1,8 +1,8 @@
-
-
+
+
Rheo is packaged as a standalone binary, and doesn’t require any version of Typst on your system. (Note that even if you already have Typst on your system, Rheo will use its own embedded version of the compiler.) Refer to Rheo’s source code for more information and installation options.
Firing up
With Rheo we can produce a static site, a PDF, and an EPUB from a Typst document. Let’s create a directory with a single Typst file in it:
-mkdir project_uno
touch project_uno/index.typ
+ mkdir project_uno
touch project_uno/index.typ
As one of Rheo’s outputs is a static site, the landing page will default to one named ‘index’. (If this file doesn’t exist, Rheo will present you with a basic listing of all the other files in the site.) Let’s put some Typst in the index.typ file:
project_uno/index.typ
= Project uno
Project uno is a writing project.
+ = Project uno
Project uno is a writing project.
Rheo aims to keep out of your way as much as possible, and doesn’t require that you add any special syntax or metadata to your files to work. This single Typst file we need to get started. Provided you’ve already installed Rheo on your system, we can compile the project. You can tell Rheo to compile a folder by pointing the compile command at it:
rheo compile project_uno
This command produces a build subdirectory inside the base directory which contains a PDF, an EPUB, and a static site (HTML and CSS). Your project folder should now look like so:
.
├── build
│ ├── epub
│ │ └── project_uno.epub
│ ├── html
│ │ ├── index.html
│ │ └── style.css
│ └── pdf
│ └── index.pdf
└── index.typ
+ .
├── build
│ ├── epub
│ │ └── project_uno.epub
│ ├── html
│ │ ├── index.html
│ │ └── style.css
│ └── pdf
│ └── index.pdf
└── index.typ
It’s a little tiring to have to run the compile command every time we make a change, though. Let’s spin up a development server to see live changes across all output formats as we edit the source:
rheo watch project_uno --open
The --open flag here indicates that we’d like to open the output using our system’s default applications. Provided you have an EPUB reader on your system (if you don’t, we recommend installing bene), you should now have a PDF, an EPUB, and a website in front of you. As simple as that!
Scaling up
Let’s kill that process (with Ctrl-C). Rheo compiles documents from across your project directory towards EPUB, PDF, and HTML simultaneously, whereas the Typst compiler typically takes just one Typst file and produces one kind of output.1 Let’s add a couple of files to our project and link between them:
project_uno/about.typ
= About
Project uno is an incredible writing project that will transform the way we understand the world.
If you want to be involved, see the #link("./contact.typ")[Contact page].
+ = About
Project uno is an incredible writing project that will transform the way we understand the world.
If you want to be involved, see the #link("./contact.typ")[Contact page].
project_uno/contact.typ
#let email = "myemail@mydomain.com"
= Contact
To learn more about project uno, email me at #link("mailto:" + email)[#email]
+ #let email = "myemail@mydomain.com"
= Contact
To learn more about project uno, email me at #link("mailto:" + email)[#email]
And let’s also link to the two new pages on the index page:
project_uno/index.typ
= Project uno
Project uno is a writing project.
- #link("./about.typ")[About]
- #link("./contact.typ")[Contact]
+ = Project uno
Project uno is a writing project.
- #link("./about.typ")[About]
- #link("./contact.typ")[Contact]
Now let’s run Rheo again, but this time let’s only build the HTML and EPUB outputs:
rheo watch project_uno --html --epub --open
Note how the relative links are working across both the EPUB and the PDF. Relative linking is one of the key features in Rheo that enables you to build richer static sites and EPUBs beyond using just Typst. All of Typst’s other features such as variables are fair game, too, as Rheo just uses Typst’s compiler under the hood.
@@ -39,15 +39,15 @@One issue with the EPUB that is currently being produced is that the index.typ section shows up last, after the about.typ and contact.typ, as Rheo orders files lexicographically by default. This is probably not what we want, as the index page acts as a sort of table of contents in our writing project currently.
To sophisticate the way that Rheo produces outputs, we can add a rheo.toml config at the base of the project directory:
project_uno/rheo.toml
version = "0.1.0"
[epub.spine]
title = "Project Uno"
vertebrae = ["index.typ", "about.typ", "contact.typ"]
+ version = "0.1.0"
[epub.spine]
title = "Project Uno"
vertebrae = ["index.typ", "about.typ", "contact.typ"]
This config uses the notion of a spine to indicate a custom order for the sections. We’ll learn more about these later on in this documentation.
Let’s run the watch command again, this time with all outputs like the first time:
rheo watch project_uno --open
Great! The EPUB order is fixed. We now, however, have three distinct PDFs that are being created: one for each page. This is because Rheo defaults to producing one PDF per file in the project directory. We can configure Rheo to merge files together into a single PDF output by specifying a PDF spine, as we did with EPUB, and setting the merge attribute to true:
project_uno/rheo.toml
version = "0.1.0"
[epub.spine]
title = "Project Uno"
vertebrae = ["index.typ", "about.typ", "contact.typ"]
[pdf.spine]
title = "Project Uno"
vertebrae = ["index.typ", "about.typ", "contact.typ"]
merge = true
+ version = "0.1.0"
[epub.spine]
title = "Project Uno"
vertebrae = ["index.typ", "about.typ", "contact.typ"]
[pdf.spine]
title = "Project Uno"
vertebrae = ["index.typ", "about.typ", "contact.typ"]
merge = true
Before we run this again, let’s also clean the outputs in the build directory, as we don’t need those individual PDFs that we produced anymore:
-rheo clean project_uno
rheo watch project_uno --open
+ rheo clean project_uno
rheo watch project_uno --open
Now we have a fully featured writing project, with nice-looking and orderly outputs in PDF, EPUB, and in HTML!
-
diff --git a/tests/ref/examples/rheo_docs/epub/xhtml/index.xhtml b/tests/ref/examples/rheo_docs/epub/xhtml/index.xhtml
index 7c36f2e..049518e 100644
--- a/tests/ref/examples/rheo_docs/epub/xhtml/index.xhtml
+++ b/tests/ref/examples/rheo_docs/epub/xhtml/index.xhtml
@@ -1,8 +1,8 @@
-
-
+
+
If you compile a Rheo project directory without a rheo.toml file, the following default settings will be applied to compile your project.
version = "0.1.0"
content_dir = "./"
build_dir = "build"
formats = ["pdf", "html", "epub"]
[epub.spine]
vertebrae = ["**/*.typ"]
title = "[project directory name]"
+ version = "0.1.0"
content_dir = "./"
build_dir = "build"
formats = ["pdf", "html", "epub"]
[epub.spine]
vertebrae = ["**/*.typ"]
title = "[project directory name]"
To point Rheo to a rheo.toml file that is not at the root of the project directory, specify it directly via the CLI:
rheo compile path/to/project --config path/to/config
diff --git a/tests/ref/examples/rheo_docs/epub/xhtml/spines.xhtml b/tests/ref/examples/rheo_docs/epub/xhtml/spines.xhtml
index 811a9e5..a3449e6 100644
--- a/tests/ref/examples/rheo_docs/epub/xhtml/spines.xhtml
+++ b/tests/ref/examples/rheo_docs/epub/xhtml/spines.xhtml
@@ -1,26 +1,26 @@
-
-
+
+
Spines
A spine in Rheo is the backbone or ‘table of contents’ of Typst source files that should be compiled to an output format. It takes its name from the epub specification, in which the spine articulates—or reticulates— the set and order of chapters included.
You can specify a spine’s vertebrae for any output format using an array of glob strings in rheo.toml:
[epub.spine]
title = "My epub"
vertebrae = ["intro.typ", "*.typ"]
+ [epub.spine]
title = "My epub"
vertebrae = ["intro.typ", "*.typ"]
Notice how the first entry intro.typ is a specific file, whereas the second *.typ captures a range of files. When a glob string captures a range of source files, they will be ordered lexicographically in the spine.
EPUB
An EPUB must have a spine in order to be valid. By default, Rheo will infer the following spine if not specified:
-[epub.spine]
title = "[project folder name]"
vertebrae = ["**/*.typ"]
+ [epub.spine]
title = "[project folder name]"
vertebrae = ["**/*.typ"]
By default, Rheo generates one PDF per Typst source file. You can specify a spine for the PDF format in order to reticulate multiple source documents into a single output PDF by indicating the vertebrae and setting merge to true:
[pdf.spine]
title = "My reticulated pdf"
vertebrae = ["intro.typ", "*.typ"]
merge = true
+ [pdf.spine]
title = "My reticulated pdf"
vertebrae = ["intro.typ", "*.typ"]
merge = true
In a PDF generated in this way, relative links will resolve to internal document links that point to the relevant section.
HTML
Rheo does not currently support customizing HTML spines. The default spine uses all Typst files:
-[html.spine]
title = "[project folder name]"
vertebrae = ["**/*.typ"]
+ [html.spine]
title = "[project folder name]"
vertebrae = ["**/*.typ"]