summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLachlan Kermode <lachiekermode@gmail.com>2025-06-11 16:07:25 +0200
committerGitHub <noreply@github.com>2025-06-11 14:07:25 +0000
commit1f5846ce246672701fbec918db9b1d05c8920895 (patch)
treed0f8cb5cf2888a18fbd0b21012f4523b1f0ca543
parentd7e0c52dd5b6b34861c4104925d2440f5a770a47 (diff)
Render `#super` as `<sup>`, `#sub` as `<sub>` in HTML (#6422)
-rw-r--r--crates/typst-library/src/text/shift.rs19
-rw-r--r--tests/ref/html/basic-sup-sub.html11
-rw-r--r--tests/suite/text/shift.typ5
3 files changed, 34 insertions, 1 deletions
diff --git a/crates/typst-library/src/text/shift.rs b/crates/typst-library/src/text/shift.rs
index dbf1be8a..7b35dfd3 100644
--- a/crates/typst-library/src/text/shift.rs
+++ b/crates/typst-library/src/text/shift.rs
@@ -2,7 +2,10 @@ use ecow::EcoString;
use crate::diag::SourceResult;
use crate::engine::Engine;
-use crate::foundations::{elem, Content, Packed, SequenceElem, Show, StyleChain};
+use crate::foundations::{
+ elem, Content, NativeElement, Packed, SequenceElem, Show, StyleChain, TargetElem,
+};
+use crate::html::{tag, HtmlElem};
use crate::layout::{Em, Length};
use crate::text::{variant, SpaceElem, TextElem, TextSize};
use crate::World;
@@ -52,6 +55,13 @@ impl Show for Packed<SubElem> {
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
let body = self.body.clone();
+ if TargetElem::target_in(styles).is_html() {
+ return Ok(HtmlElem::new(tag::sub)
+ .with_body(Some(body))
+ .pack()
+ .spanned(self.span()));
+ }
+
if self.typographic(styles) {
if let Some(text) = convert_script(&body, true) {
if is_shapable(engine, &text, styles) {
@@ -111,6 +121,13 @@ impl Show for Packed<SuperElem> {
fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
let body = self.body.clone();
+ if TargetElem::target_in(styles).is_html() {
+ return Ok(HtmlElem::new(tag::sup)
+ .with_body(Some(body))
+ .pack()
+ .spanned(self.span()));
+ }
+
if self.typographic(styles) {
if let Some(text) = convert_script(&body, false) {
if is_shapable(engine, &text, styles) {
diff --git a/tests/ref/html/basic-sup-sub.html b/tests/ref/html/basic-sup-sub.html
new file mode 100644
index 00000000..54187215
--- /dev/null
+++ b/tests/ref/html/basic-sup-sub.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ </head>
+ <body>
+ <p>1<sup>st</sup>, 2<sup>nd</sup>, 3<sup>rd</sup>.</p>
+ <p>log<sub>2</sub>, log<sub>3</sub>, log<sub>variable</sub>.</p>
+ </body>
+</html>
diff --git a/tests/suite/text/shift.typ b/tests/suite/text/shift.typ
index 3b8d2ccb..2667ca2f 100644
--- a/tests/suite/text/shift.typ
+++ b/tests/suite/text/shift.typ
@@ -17,3 +17,8 @@ n#super[1], n#sub[2], ... n#super[N]
#underline[The claim#super[\[4\]]] has been disputed. \
The claim#super[#underline[\[4\]]] has been disputed. \
It really has been#super(box(text(baseline: 0pt, underline[\[4\]]))) \
+
+--- basic-sup-sub html ---
+1#super[st], 2#super[nd], 3#super[rd].
+
+log#sub[2], log#sub[3], log#sub[variable].