WaniKani Even Kana? (ModAnswerChecker)

Check that the okurigana matches the answer

  1. // ==UserScript==
  2. // @name WaniKani Even Kana? (ModAnswerChecker)
  3. // @namespace http://www.wanikani.com
  4. // @version 1.2.1
  5. // @description Check that the okurigana matches the answer
  6. // @author polv
  7. // @match https://www.wanikani.com/extra_study/session*
  8. // @match https://www.wanikani.com/review/session*
  9. // @match https://www.wanikani.com/subjects/*
  10. // @match https://preview.wanikani.com/extra_study/session*
  11. // @match https://preview.wanikani.com/review/session*
  12. // @match https://preview.wanikani.com/subjects/*
  13. // @icon https://www.google.com/s2/favicons?sz=64&domain=wanikani.com
  14. // @license MIT
  15. // @require https://gf.qytechs.cn/scripts/470201-wanikani-answer-checker/code/WaniKani%20Answer%20Checker.js?version=1215595
  16. // @homepage https://gf.qytechs.cn/en/scripts/478704-wanikani-even-kana-modanswerchecker
  17. // @supportURL https://community.wanikani.com/t/do-you-even-kana-okurigana-matcher/8440/56
  18. // @source https://github.com/patarapolw/wanikani-userscript/blob/master/userscripts/even-kana.user.js
  19. // @grant none
  20. // ==/UserScript==
  21.  
  22. // @ts-check
  23. /// <reference path="./types/answer-checker.d.ts" />
  24. (function () {
  25. 'use strict';
  26.  
  27. window.modAnswerChecker.register((e) => {
  28. if (e.questionType === 'reading' && e.item.type === 'Vocabulary') {
  29. console.log(e);
  30. if (!matchOkurigana(e.item.characters, e.response.trim())) {
  31. return {
  32. action: 'retry',
  33. message: {
  34. text: 'Bro, Do you even Kana?',
  35. type: 'answerException',
  36. },
  37. };
  38. }
  39. }
  40. return null;
  41. });
  42.  
  43. const CP_KATA_A = 'ア'.charCodeAt(0);
  44. const CP_HIRA_A = 'あ'.charCodeAt(0);
  45.  
  46. /**
  47. * @param {string} s
  48. * @returns {string}
  49. */
  50. function toHiragana(s) {
  51. return s.replace(/\p{sc=Katakana}/gu, (c) =>
  52. ['ヶ'].includes(c)
  53. ? c
  54. : String.fromCharCode(c.charCodeAt(0) - CP_KATA_A + CP_HIRA_A),
  55. );
  56. }
  57.  
  58. /**
  59. *
  60. * @param {string} key
  61. * @param {string} userAnswer
  62. * @returns {boolean}
  63. */
  64. function matchOkurigana(key, userAnswer) {
  65. return new RegExp(
  66. '^' +
  67. toHiragana(key.replace(/〜/g, '')).replace(
  68. /[^\p{sc=Hiragana}ー]+/gu,
  69. '.+',
  70. ) +
  71. '$',
  72. ).test(toHiragana(userAnswer));
  73. }
  74. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址