Last active
February 20, 2020 01:31
-
-
Save CourteousCoder/45ec1142f3cd8a39dc327baa94a2728a to your computer and use it in GitHub Desktop.
A bookmarklet to import custom Mandarin Chinese vocabulary into Anki
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<a href="javascript:(() => { | |
const url = 'https://www.archchinese.com/type_chinese.html'; | |
if(window.location.href !== url) return (window.location.href = url); | |
let data = ['chinese', 'pinyin', 'english'] | |
.map(col => Array | |
.from(document.querySelectorAll(`#vocabtable input[name='${col}[]']`)) | |
.map(input => input.value)); | |
csv = data[0] | |
.map((col, i) => data.map(row => row[i])) | |
.map(row => JSON.stringify(row)) | |
.join('\n') | |
.replace(/(^\[)|(\]$)/mg, ''); | |
const file = encodeURI('data:text/csv;charset=utf-8,' + csv); | |
const a = document.createElement('a'); | |
a.setAttribute('href', file); | |
a.setAttribute('download', 'chinese.csv'); | |
document.body.appendChild(a); | |
a.click(); | |
document.body.removeChild(a); | |
})(); | |
">Export Chinese Flashcards to CSV for Anki</a> | |
<ol> | |
<li>Drag the above bookmarklet to your bookmarks bar.</li> | |
<li>Click the bookmarklet.</li> | |
<li>Once the page loads, add Chinese vocab to the Vocab List, one per line <small>(You can also use the pinyin input)</small>.</li> | |
<li>Click the <button disabled>Generate Vocab List</button> button.</li> | |
<li>Once it loads, click the bookmarklet again.</li> | |
<li>Save the file</li> | |
<li><a href="https://superuser.com/a/705116">Import to Anki</a></li> | |
<li>Designed to be used with a card template like <a href="https://gist.github.com/DanielSchetritt/45ec1142f3cd8a39dc327baa94a2728a#file-sample-card-template-with-online-audio-and-formatting-html">the one I made.</a> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- BEGIN Front of card --> | |
<h1>{{Simplified}}</h1> | |
<!-- END Front of card --> | |
<!-- BEGIN Back of card --> | |
{{FrontSide}} | |
<hr id="answer"> | |
<h2 id="pinyin">{{Pinyin}}</h2> | |
<p>{{Meaning}}</p> | |
<!-- This script can be in either the front or the back of the card, depending on where you want to show pinyin --> | |
<script> | |
var toneCharMap = {}; | |
toneCharMap['a']='āáǎà'; | |
toneCharMap['e']='ēéěè'; | |
toneCharMap['i']='īíǐì'; | |
toneCharMap['o']='ōóǒò'; | |
toneCharMap['u']='ūúǔù'; | |
toneCharMap['ü']='ǖǘǚǜ'; | |
function toneToColorClass(pinyinCharacter) { | |
return 'tone' + pinyinCharacter.charAt(pinyinCharacter.length - 1); | |
} | |
function numberToToneMark(pinyinCharacter) { | |
var tonelessPinyin = pinyinCharacter.substring(0, pinyinCharacter.length - 1); | |
var toneNum = pinyinCharacter.charAt(pinyinCharacter.length - 1); | |
if (toneNum < 1 || toneNum > 5 || tonelessPinyin.length < 1) { | |
return tonelessPinyin + toneNum; // not real pinyin | |
} | |
tonelessPinyin = tonelessPinyin.replace('v', 'ü'); | |
if (toneNum == 5) { | |
return tonelessPinyin; | |
} | |
var charToReplace; | |
var vowels = tonelessPinyin.replace(/[^aeiouü]/g, ''); | |
switch (vowels.length) { | |
case 0: | |
charToReplace = tonelessPinyin.charAt(0); | |
break; | |
case 1: | |
charToReplace = vowels.charAt(0); | |
break; | |
default: | |
if (vowels.indexOf("a") >= 0) { | |
charToReplace = 'a'; | |
} | |
else if (vowels.indexOf("e") >= 0) { | |
charToReplace = 'e'; | |
} | |
else if (vowels.indexOf("ou") >= 0) { | |
charToReplace = 'o'; | |
} | |
else { | |
charToReplace = vowels.charAt(1); | |
} | |
} | |
var tonesStr = toneCharMap[charToReplace]; | |
var replacementChar = tonesStr == null ? null : tonesStr.charAt(toneNum - 1); | |
if (replacementChar == null || replacementChar == ' ') { | |
return tonelessPinyin + toneNum; | |
} | |
else { | |
return tonelessPinyin.replace(charToReplace, replacementChar); | |
} | |
return pinyinCharacter; | |
} | |
function formatPinyinCharacter(pinyinCharacter) { | |
return ('<a class="'+ toneToColorClass(pinyinCharacter) + '" href="https://www.purpleculture.net/mp3/'+ pinyinCharacter + '.mp3">' + numberToToneMark(pinyinCharacter) + '</a>'); | |
} | |
function splitWords(str) { | |
var words = []; | |
if (str.length === 0) { | |
return words; | |
} | |
var word = str.charAt(0); | |
for (var c = 1; c < str.length; c++) { | |
char = str.charAt(c); | |
if (char !== ' ') { | |
word += char; | |
} | |
else if(word.length > 0) { | |
words.push(word); | |
word = ''; | |
} | |
} | |
if(word.length > 0) { | |
words.push(word); | |
} | |
return words; | |
} | |
function formatPinyin() { | |
var pinyinElement = document.getElementById('pinyin'); | |
var pinyinCharacters = splitWords(pinyinElement.innerHTML); | |
var formattedPinyin = ''; | |
for (var i = 0; i < pinyinCharacters.length; i++) { | |
formattedPinyin += formatPinyinCharacter(pinyinCharacters[i]); | |
} | |
pinyinElement.innerHTML = formattedPinyin; | |
} | |
formatPinyin(); | |
</script> | |
<!-- END Back of card. --> | |
<!--Put the contents of the <style> tag into Anki's "Styling" section. --> | |
<style> | |
.card { | |
font-family: arial; | |
font-size: 20px; | |
text-align: center; | |
color: black; | |
background-color: white; | |
} | |
.tone1 { | |
color: red; | |
} | |
.tone2 { | |
color: orange; | |
} | |
.tone3 { | |
color: green; | |
} | |
.tone4 { | |
color: blue; | |
} | |
.tone5 { | |
color: darkgrey; | |
} | |
a { | |
text-decoration: none; | |
} | |
a:visited { | |
text-decoration: none; | |
} | |
a:visited.tone1 { | |
color: red; | |
} | |
a:visited.tone2 { | |
color: orange; | |
} | |
a:visited.tone3 { | |
color: green; | |
} | |
a:visited.tone4 { | |
color: blue; | |
} | |
a:visited.tone5 { | |
color: darkgrey; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment