{{FrontSide}}
|
|
|
|
<hr id=answer>
|
|
|
|
{{#JapaneseAudio}}
|
|
{{JapaneseAudio}}
|
|
{{/JapaneseAudio}}
|
|
|
|
{{^JapaneseAudio}}
|
|
[sound:https://peaceful-brushlands-36451.herokuapp.com/api/tts?lang=ja&q={{kanji:Japanese}}]
|
|
{{/JapaneseAudio}}
|
|
|
|
<p>{{JapaneseAlt}}</p>
|
|
|
|
<p>
|
|
{{#Pitch}}
|
|
{{Pitch}}
|
|
{{/Pitch}}
|
|
|
|
{{^Pitch}}
|
|
{{Reading}}
|
|
{{/Pitch}}
|
|
</p>
|
|
|
|
<p>{{Meaning}}</p>
|
|
|
|
{{#Sentence}}
|
|
<p>
|
|
<div>
|
|
{{furigana:Sentence}}
|
|
|
|
{{^SentenceAudio}}
|
|
<el-tts q="{{kanji:Sentence}}" is-sentence />
|
|
{{/SentenceAudio}}
|
|
|
|
{{#SentenceAudio}}
|
|
{{SentenceAudio}}
|
|
{{/SentenceAudio}}
|
|
</div>
|
|
{{SentenceMeaning}}
|
|
</p>
|
|
{{/Sentence}}
|
|
|
|
<details>
|
|
<summary>References</summary>
|
|
{{#Takoboto}}
|
|
<a href="{{Takoboto}}">Takoboto</a>・
|
|
{{/Takoboto}}
|
|
{{#Akebi}}
|
|
<a href="{{Akebi}}">Akebi</a>・
|
|
{{/Akebi}}
|
|
<a class="ext-link" id="alc">ALC</a>・
|
|
<a class="ext-link" id="weblio">Weblio</a>・
|
|
<a class="ext-link" id="goo">Goo</a>・
|
|
<a class="ext-link" id="yourei">用例</a>・
|
|
<a class="ext-link" id="youglish">YouGlish</a>・
|
|
<a class="ext-link" id="ImmersionKit">ImmersionKit</a>・
|
|
<a href="https://peaceful-brushlands-36451.herokuapp.com?lang=ja&q={{kanji:Japanese}}">Audios</a>
|
|
</details>
|
|
|
|
{{#Mnemonic}}
|
|
<details>
|
|
<summary>Mnemonic</summary>
|
|
<p>{{Mnemonic}}</p>
|
|
</details>
|
|
{{/Mnemonic}}
|
|
|
|
<script type="module">
|
|
let linkEntries = {}
|
|
try { linkEntries = JSON.parse('{{LinkEntries}}') } catch (e) { }
|
|
|
|
document.querySelectorAll('a.ext-link').forEach(a => {
|
|
switch (a.id) {
|
|
case 'alc':
|
|
a.href = `https://eow.alc.co.jp/search?q=${encodeURIComponent(linkEntries.alc || '{{kanji:Japanese}}')}`
|
|
break
|
|
case 'weblio':
|
|
a.href = `https://www.weblio.jp/content/${encodeURIComponent(linkEntries.weblio || '{{kanji:Japanese}}')}`
|
|
break
|
|
case 'goo':
|
|
a.href = `https://dictionary.goo.ne.jp/srch/all/${encodeURIComponent(linkEntries.goo || '{{kanji:Japanese}}')}/m1u/`
|
|
break
|
|
case 'yourei':
|
|
a.href = `http://yourei.jp/${encodeURIComponent(linkEntries.yourei || '{{kanji:Japanese}}')}`
|
|
break
|
|
case 'youglish':
|
|
a.href = `https://youglish.com/pronounce/${encodeURIComponent(linkEntries.youglish || '{{kanji:Japanese}}')}/japanese?`
|
|
break
|
|
case 'ImmersionKit':
|
|
a.href = `https://v2.immersionkit.com/search?category=drama&keyword=${encodeURIComponent(linkEntries.ImmersionKit || '{{kanji:Japanese}}')}`
|
|
break
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<script type="module">
|
|
function speak(q = '', lang = 'ja-JP') {
|
|
if (window.AnkiDroidJS) {
|
|
AnkiDroidJS.ankiTtsSetLanguage?.(lang)
|
|
AnkiDroidJS.ankiTtsSpeak?.(q)
|
|
}
|
|
}
|
|
|
|
class TTSElement extends HTMLElement {
|
|
constructor() {
|
|
super()
|
|
|
|
this.attachShadow({ mode: 'open' })
|
|
|
|
this.wrapper = document.createElement('span')
|
|
this.wrapper.innerText = '▶️'
|
|
this.wrapper.style.cursor = 'pointer'
|
|
this.shadowRoot.append(this.wrapper)
|
|
}
|
|
|
|
async connectedCallback() {
|
|
let src = this.getAttribute('src')
|
|
if (!src) {
|
|
const q = this.getAttribute('q')
|
|
const isSentence = this.hasAttribute('is-sentence')
|
|
if (q) {
|
|
src = `https://peaceful-brushlands-36451.herokuapp.com/api/tts?lang=ja&is_sentence=${isSentence}=${encodeURIComponent(q)}`
|
|
}
|
|
}
|
|
|
|
const soundTag = {
|
|
pre: '[sound:',
|
|
post: ']'
|
|
}
|
|
if (src.startsWith(soundTag.pre) && src.endsWith(soundTag.post)) {
|
|
src = src.substring(soundTag.pre.length, src.length - soundTag.post.length)
|
|
}
|
|
|
|
try {
|
|
if (src) {
|
|
const elAudio = document.createElement('audio')
|
|
|
|
const setSrc = () => {
|
|
const elSource = document.createElement('source')
|
|
elSource.src = src
|
|
elAudio.append(elSource)
|
|
}
|
|
|
|
elAudio.style.display = 'none'
|
|
this.wrapper.append(elAudio)
|
|
|
|
this.onclick = async () => {
|
|
if (!elAudio.querySelector('source')) {
|
|
setSrc()
|
|
}
|
|
elAudio.play()
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error(e)
|
|
this.onclick = () => {
|
|
speak(q)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
customElements.define('el-tts', TTSElement)
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<script type="module">
|
|
const removeHTML = (h) => {
|
|
const div = document.createElement('div')
|
|
div.innerHTML = h
|
|
return div.innerText
|
|
}
|
|
|
|
const reJa = /[\p{sc=Han}\p{sc=Katakana}\p{sc=Hiragana}]/u
|
|
document.querySelectorAll('.has-tts').forEach((el) => {
|
|
const isSentence = el.classList.contains('is-sentence')
|
|
const newEls = el.innerHTML.split(/<br *\/?>/g).map((t) => {
|
|
t = removeHTML(t)
|
|
|
|
const div = document.createElement('div')
|
|
div.append(t)
|
|
|
|
if (reJa.test(t)) {
|
|
const elTTS = document.createElement('el-tts')
|
|
elTTS.setAttribute('q', t)
|
|
if (isSentence) elTTS.setAttribute('is-sentence', 'true')
|
|
div.append(elTTS)
|
|
}
|
|
|
|
return div
|
|
})
|
|
|
|
el.textContent = ''
|
|
el.append(...newEls)
|
|
})
|
|
</script>
|