# The Unreasonable Effectiveness of ProseMirror Model in Rich Text Transformation

**URL:** <https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020>\
**Category:** Show\
**Created:** [May 19, 2026, 11:58am UTC](https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020 "2026-05-19T11:58:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![SMores](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/smores/32/3356_2.png) [@SMores](https://discuss.prosemirror.net/u/SMores)\
**Post date:** [May 19, 2026, 11:58am UTC](https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020/1 "2026-05-19T11:58:15Z")

</div>

> **[The Unreasonable Effectiveness of ProseMirror Model in Rich Text Transformation](https://smoores.dev/post/unreasonable_effectiveness_of_prosemirror/)**
>
> About month a go I might have added a minimal implementation of ProseMirror Model in Storyteller’s alignment package. But I can explain! It’s not my fault! It’s just that ProseMirror’s data model is such a good fit for rich text. I couldn’t resist. I...

Hopefully this is interesting to some folks! I found myself reaching for ProseMirror while working on a rare non-text-editor project of mine, which nonetheless needed to transform rich text. Wrote a bit about how I ported over a minimal ProseMirror model and transform implementation for that use case, and how much it simplified the transformation!

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [May 19, 2026, 12:55pm UTC](https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020/2 "2026-05-19T12:55:05Z")

</div>

Hah, okay, that works I guess. Thanks for sharing.

---

<div class="post-metadata">

**Author:** ![SMores](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/smores/32/3356_2.png) [@SMores](https://discuss.prosemirror.net/u/SMores)\
**Post date:** [May 19, 2026, 1:14pm UTC](https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020/3 "2026-05-19T13:14:37Z")

</div>

It almost sounds like you _didn’t_ have marking up EPUBs in mind when you designed ProseMirror? Crazy, could have fooled me!

---

<div class="post-metadata">

**Author:** ![mustafa0x](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/mustafa0x/32/1045_2.png) [@mustafa0x](https://discuss.prosemirror.net/u/mustafa0x)\
**Post date:** [May 19, 2026, 1:20pm UTC](https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020/4 "2026-05-19T13:20:21Z")

</div>

> That means that we can only synchronize audio clips at the level of HTML elements (and only if those elements have unique IDs)! This is a pretty significant limitation, since nearly all EPUBs only have textblock-level markup, and rarely with IDs on every element. What do we do, if we want to provide a sentence-level synchronization? What about word-level?

This is indeed a difficult problem. I had a similar challenge where I had word-level timings for words, and wanted to highlight words during playing. But the text was post-processed. And the post-processing rules were arbitrary. Thus I had to “project” the word-timing indexes onto the post processed text. It was messy.

---

<div class="post-metadata">

**Author:** ![SMores](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/smores/32/3356_2.png) [@SMores](https://discuss.prosemirror.net/u/SMores)\
**Post date:** [May 19, 2026, 3:32pm UTC](https://discuss.prosemirror.net/t/the-unreasonable-effectiveness-of-prosemirror-model-in-rich-text-transformation/9020/5 "2026-05-19T15:32:14Z")

</div>

Yeeeeup! I don’t know if you saw, but in the post I linked to [this proposal](https://github.com/w3c/epub-specs/issues/2934) to encourage better support for URI text fragments in media overlays. A text fragment would let you target a span of text in an HTML document without having to rely on pre-existing markup. But this is similarly challenging to produce on the production side, _and_ it’s much, much harder to implement on the reading system side! We’re working on adding support for it to Thorium/Readium, but it’s tough 😅
