您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a wkof filter for visually similar kanji
- // ==UserScript==
- // @name Wanikani Open Framework: Visually similar kanji filter
- // @namespace http://tampermonkey.net/
- // @version 2.0.0
- // @description Adds a wkof filter for visually similar kanji
- // @author Kumirei
- // @include https://www.wanikani.com/*
- // @include *preview.wanikani.com*
- // @grant none
- // ==/UserScript==
- /*jshint esversion: 8 */
- (function(wkof) {
- let script_id = "VSKFilter";
- if (!wkof) return;
- var visuallySimilarFilename = 'https://raw.githubusercontent.com/mwil/wanikani-userscripts/master/wanikani-similar-kanji/db/stroke_edit_dist_esc.json';
- var visuallySimilarData;
- async function get_data() {
- let data = await wkof.load_file(visuallySimilarFilename, true);
- visuallySimilarData = JSON.parse(data);
- }
- function ageCache(){
- // periodically ages the cache
- let oneMonth = 1000*60*60*24*30;
- var now = Date.now();
- if (wkof.settings[script_id] === undefined) wkof.settings[script_id] = {};
- if (wkof.settings[script_id].lastTime === undefined){
- wkof.settings[script_id].lastTime = now;
- wkof.Settings.save(script_id);
- }
- let lastTime = wkof.settings[script_id].lastTime;
- if (now > lastTime + oneMonth){
- wkof.file_cache.delete(visuallySimilarFilename);
- wkof.settings[script_id].lastTime = now;
- wkof.Settings.save(script_id);
- }
- }
- // Turns comma separated lists into arrays. Supports latin and Japanese commas. Converts Japanese periods into latin decimal points
- // Adapted from a handy function of rfindley
- function split_list(str) {return str.replace(/./g,'.').replace(/[、,]/g,',').replace(/[\s ]+/g,' ').trim().replace(/ *, */g, ',').toLowerCase().split(',').filter(function(name) {return (name.length > 0);});}
- // Translate Japanese numerals into latin so they can be parsed into numbers by Number()
- function tr(text) {
- return text.replace( /[0123456789]/g, (chr => '0123456789'.charAt('0123456789'.indexOf( chr ))));
- }
- // Create an array of visually similar kanji for all search terms
- function makeVisuallySimilarArrays(str){
- var arr = split_list(str);
- if (arr.length === 0) return [];
- // compute the similarity threshold if one is provided
- var threshold = 0.0; // default if threshold is absent
- var first = Number(tr(arr[0]));
- if (!isNaN(first)){
- // number is present - calculate threshold
- if (arr.length <= 1) return [];
- var second = Number(tr(arr[1]));
- if (isNaN(second)) {
- // decimal separator not a comma - first is threshold
- threshold = first;
- arr = arr.splice(1);
- } else {
- // decimal separator is a comma - calculate threshold
- threshold = first + second/10;
- arr = arr.splice(2);
- }
- }
- return arr.reduce(filterThreshold, []);
- function filterThreshold(running, kanji){
- if (visuallySimilarData[kanji] === undefined) return running; // ignore trash input
- for (var data of visuallySimilarData[kanji]){
- if (data.score >= threshold) running.push(data.kan);
- }
- return running;
- }
- }
- // Adds the filter to wkof
- function register_filter(data) {
- wkof.ready('ItemData.registry').then(()=>{
- wkof.ItemData.registry.sources.wk_items.filters.include_visually_similar_kanji = {
- filter_func: function(filter_value, item){if (item.object === "kanji") item.visually_similar_kanji = visuallySimilarData[item.data.characters]; return true;}
- };
- wkof.ItemData.registry.sources.wk_items.filters.visually_similar_kanji = {
- type: 'text',
- label: 'LY Visually Similar',
- placeholder: '0.5,人、能、力',
- hover_tip: 'Select the kanji whose similar kanji you want to study.\nMultiple search terms are separated by commas.\n\n'+
- 'You may specify a similarity threshold as as a real number\nbetween 0 and 1 at the beginning of the search terms.\n'+
- '0 means all similar kanji. Higher numbers give fewer kanji.\n\nThis filter uses similarity data by Lars Yencken.',
- default: '',
- filter_func: function (filterValue, item){return (item.object === 'kanji' && filterValue.indexOf(item.data.characters) >= 0);},
- filter_value_map: makeVisuallySimilarArrays,
- };
- wkof.set_state(script_id, 'ready');
- });
- }
- // startup
- get_data();
- register_filter();
- wkof.include('Settings');
- wkof.ready('Settings')
- .then(function(){return wkof.Settings.load(script_id);})
- .then(ageCache);
- })(window.wkof);