Paste as HTML not getting the italics (bold and the rest is ok)

The other way around is solved, now this last issue and I’ll be able to do this basic copy & paste both ways between Scrivener and the Remarkable tablet.

To reproduce:

  1. Copy the formatted text in Remarkable desktop application, something with some italics (actually also with bold, title, subtitle, bullet list).
  2. Paste into a Scrivener document
  3. Result: all good except the italics are gone. (And this is the formatting I wanted the most…)

To investigate:

Sample text formatting:

Text with some italics and some bold in it.

Content of the clipboard after copy it on Remarkable, ‘text/html’ format:

<!--StartFragment--><html><meta charset="utf-8" /><p>Text with <span style=" font-style:italic;">some italics</span> and <span style=" font-weight:700;">some bold</span> in it.</p></html><!--EndFragment-->

Same sample copied from Scrivener: (manually adding the italic before copying)

<!--StartFragment--><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Untitled</title>
<meta name="CreationTime" content="2025-11-21T15:18:28Z" />
<meta name="ModificationTime" content="2025-11-21T15:18:28Z" />
<meta name="Generator" content="Scrivener for Windows HTML Writer" />
<meta name="ScrivenerVersion" content="3.1.6.0" />
</head>
<body>
<p>Text with <em><span style="font-style:italic;">some italics</span></em> and <strong><span style="font-weight:5600;">some bold</span></strong> in it.</p>
</body>
</html>
<!--EndFragment-->

The difference between the html of each source:
Scrivener, on top of declaring ‘font-style:italic’, also put an ‘em’ tag for italics, so maybe it needs the tags and ignores the font style?
But it also put a ‘strong’ tag for bold, while Remarkable doesn’t, without having any issue accepting the bold from Remarkable conveyed only through inline style…

So why is it different for italics that are ignored?

Note: there is a similar post (14 years old), this time for copy-paste import from word, but with the same italics issue.

If anybody wants to test without the need of a tablet:

  1. Make a .html file with:
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<p>Text with <span style=" font-style:italic;">some italics</span>
and <span style=" font-weight:700;">some bold</span> in it.</p>
</body>
</html>
  1. Open in a browser, copy what it displays. It should be

Text with some italics and some bold in it.

  1. Paste into a Scrivener doc: the italics gets dropped.

I’ll try to find the simplest workaround until it gets fixed, to smooth my workflow.

I can’t help much as I’m (a) a Mac-user, and (b) only a semi-geek, but I am not surprised by the result. As I see it there is a considerable difference between "font-weight” and “font-style”. The first doesn’t require a switch of font-family variant , where the second does. So the internal RTF of Scrivener must be able to interpret font weights above a certain value as bold, but doesn’t recognise “font-style: italic” as the same as the italic variant of whatever font family is in use.

If Windows Scriv behaves like Mac Scriv, then it will wrap the text in <em>…</em> and <strong>…</strong>. The rest comes from somewhere else.

:slight_smile:
Mark

2 Likes

Thanks for you sharing this, Mark.
What I noticed: Scrivener generates the “font-style:italic;” in html buffer when we copy italic (and also < em > on top of the span). So I would see that as some acknowledgement of the former type of formatting.
But it doesn’t see it that way for paste, only for copy…

I’ll share my workaround for the import flow.

Setup:

  1. Make a local html page with the code below.
  2. Open the page in browser: “Remarkable2Scrivener”

Importing from Remarkable:

  1. Copy the text from Remarkable App
  2. Paste the text into the Remarkable2Scrivener (Ctrl-V)
  3. Click on the “convert and copy” button
  4. Paste info Scrivener.
    (now italics are handled)
html code
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Remarkable2Scrivener</title>
  <style>
    body { font-family: system-ui, sans-serif; margin: 20px; }
    textarea {
      width: 100%;
      height: 280px;
      font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
      font-size: 14px;
      padding: 12px;
      border: 1px solid #ccc;
      border-radius: 8px;
      box-sizing: border-box;
      resize: vertical;
    }
    button {
      margin-top: 10px;
      padding: 10px 14px;
      font-size: 14px;
      border: 1px solid #222;
      border-radius: 8px;
      background: #111;
      color: #fff;
      cursor: pointer;
    }
    button:active { transform: translateY(1px); }
    #preview {
      margin-top: 16px;
      padding: 12px;
      border: 1px dashed #aaa;
      border-radius: 8px;
      min-height: 80px;
      background: #fafafa;
    }
    .hint { color: #666; font-size: 12px; margin-top: 6px; }
  </style>
</head>
<body>
  <h1>Remarkable2Scrivener</h1>

  <textarea id="input" placeholder="Paste your HTML here (Ctrl-V anywhere on the page)..."></textarea>
  <div class="hint">
    Paste is captured on the whole page and uses only text/html.
  </div>

  <button id="convertCopy">convert and copy</button>

  <div id="preview" aria-live="polite"></div>

  <script>
    const inputEl = document.getElementById("input");
    const previewEl = document.getElementById("preview");
    const buttonEl = document.getElementById("convertCopy");

    function updatePreview() {
      previewEl.innerHTML = inputEl.value || "";
    }
    updatePreview();

    // 1) Ctrl-V paste anywhere in the page (text/html only)
    document.addEventListener("paste", (e) => {
      const cd = e.clipboardData || window.clipboardData;
      if (!cd) return;

      const html = cd.getData("text/html");
      if (!html) {
        alert("No text/html in clipboard!");
        return;
      }

      // Prevent default paste into the focused element
      e.preventDefault();

      inputEl.value = html;
      updatePreview();
    });

    // Helper: detect whether a span is rendered as italic
    function isItalicSpan(span) {
      if (!(span instanceof HTMLElement)) return false;

      // Inline style case
      const inline = (span.getAttribute("style") || "").toLowerCase();
      if (inline.includes("font-style") && inline.includes("italic")) return true;
      if (span.style.fontStyle && span.style.fontStyle.toLowerCase() === "italic") return true;

      // Computed style case (CSS classes, etc.)
      const cs = window.getComputedStyle(span);
      return cs && cs.fontStyle === "italic";
    }

    // Copy HTML into the text/html clipboard buffer if supported
    async function copyAsHtml(htmlString) {
      if (navigator.clipboard && window.ClipboardItem) {
        const blob = new Blob([htmlString], { type: "text/html" });
        const item = new ClipboardItem({ "text/html": blob });
        await navigator.clipboard.write([item]);
        return;
      }
      // Fallback: text/plain only
      await navigator.clipboard.writeText(htmlString);
    }

    // 2) Convert italic spans to <em><span>...</span></em>, then copy as text/html
    buttonEl.addEventListener("click", async () => {
      const spans = Array.from(previewEl.querySelectorAll("span"));

      spans.forEach(span => {
        if (!isItalicSpan(span)) return;

        // Avoid double-wrapping if already inside <em>
        const parent = span.parentElement;
        if (parent && parent.tagName.toLowerCase() === "em") return;

        const em = document.createElement("em");
        span.replaceWith(em);
        em.appendChild(span);
      });

      const resultHtml = previewEl.innerHTML;

      try {
        await copyAsHtml(resultHtml);
        buttonEl.textContent = "copied!";
        setTimeout(() => buttonEl.textContent = "convert and copy", 1200);
      } catch (err) {
        console.error(err);
        alert("Unable to copy to clipboard. Check browser permissions.");
      }
    });
  </script>
</body>
</html>