You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
4.1 KiB
79 lines
4.1 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Markdown Furigana to HTML</title>
|
|
<link rel="stylesheet" href="https://unpkg.com/missing.css@1.0.9/dist/missing.min.css">
|
|
<style>:root { cursor: inherit } button { cursor: pointer }</style>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<h1>Markdown Furigana to HTML</h1>
|
|
<p>
|
|
Welcome to Elnu's Markdown <a href="https://en.wikipedia.org/wiki/Furigana" target="_blank">Furigana</a> to HTML converter utility.
|
|
This converter uses the following syntax, which is a custom and <b>unofficial</b> extension to <a href="https://commonmark.org/" target="_blank">Markdown</a>:
|
|
</p>
|
|
<p class="center">
|
|
<span>
|
|
<code>[振]{ふ}り[仮]{が}[名]{な}</code>
|
|
⟶
|
|
<span lang="ja"><ruby>振<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby>り<ruby>仮<rp>(</rp><rt>が</rt><rp>)</rp></ruby><ruby>名<rp>(</rp><rt>な</rt><rp>)</rp></ruby></span>
|
|
</span>
|
|
</p>
|
|
<details>
|
|
<summary>How does it work?</summary>
|
|
<p>This syntax gets rendered to HTML as:</p>
|
|
<p class="center"><code>
|
|
<span lang="ja"><br>
|
|
 <ruby>振<rp>(</rp><rt>ふ</rt><rp>)</rp></ruby>り<br>
|
|
 <ruby>仮<rp>(</rp><rt>が</rt><rp>)</rp></ruby><br>
|
|
 <ruby>名<rp>(</rp><rt>な</rt><rp>)</rp></ruby><br>
|
|
</span>
|
|
</code></p>
|
|
<ul>
|
|
<li>
|
|
<code><rp>(</rp></code> and <code><rp>)</rp></code>
|
|
<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp" target="_blank">ruby fallback parentheses tags</a>
|
|
are used to wrap furigana text with parentheses on legacy browsers that don't support <code><ruby></code>.
|
|
</li>
|
|
<li>
|
|
Most browsers default to displaying Chinese character variants rather than Japanese.
|
|
By wrapping the ruby text in <code><span lang="ja"></code>, we
|
|
can ensure that the Japanese variants will always be used, if available.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
For more information on this syntax, see
|
|
<a href="https://blog.elnu.com/2022/01/furigana-in-markdown-using-regular-expressions/" target="_blank">my blog post here</a>
|
|
on creating a parser regular expression and integrating it into the Hugo static site generator.
|
|
</p>
|
|
</details>
|
|
<div class="box">
|
|
<input id="input" type="text" class="width:100%" autocomplete="off" autofocus>
|
|
<br>
|
|
<textarea id="output" class="width:100% mono-font" rows="8" style="resize: none" autocomplete="off" readonly><span lang="ja"></span></textarea>
|
|
<p><button id="copy" class="padding float:right">Copy</button></p>
|
|
<br>
|
|
</div>
|
|
</main>
|
|
<script>
|
|
const input = document.getElementById("input");
|
|
const output = document.getElementById("output");
|
|
const copyButton = document.getElementById("copy");
|
|
input.addEventListener("keyup", e => {
|
|
output.value = `<span lang="ja">${input.value.replace(/\[([^\]]*)]{([^\}]*)}/g, "$1<rp>(</rp><rt>$2</rt><rp>)</rp>")}</span>`;
|
|
copyButton.innerHTML = "Copy";
|
|
});
|
|
copyButton.addEventListener("click", e => {
|
|
navigator.clipboard.writeText(output.value)
|
|
.then(
|
|
() => "Copied!",
|
|
() => "Copy failed",
|
|
)
|
|
.then(message => copyButton.innerHTML = message);
|
|
setTimeout(() => copyButton.innerHTML = "Copy", 1000);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |