Word Switcher for AO3 (site-wide; user-settable)

Switches the a select word with a preferred word site-wide, across all AO3 works. User-settable.

当前为 2024-04-06 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Word Switcher for AO3 (site-wide; user-settable)
// @namespace    github.com/forceofcalm
// @version      0.1
// @description  Switches the a select word with a preferred word site-wide, across all AO3 works. User-settable.
// @author       calm
// @match        https://archiveofourown.org/works/*
// @icon         [later]
// @grant        none
// @license      MIT
// ==/UserScript==

// ADD YOUR WORD PREFERENCES HERE
// format: ['word to be replaced', 'preferred word'],
// the quotes and comma are important!
// also these are examples, you can replace them with whatever you want
const words = [
  ['oi', 'hey'],
  ['gray', 'grey'],
  ['roommates', 'flatmates'],
  ['one', 'two'],
];

(() => {
  const workText = document.querySelector('#workskin');

  words.forEach(([oldWord, newWord]) => {
      const regex = new RegExp(String.raw`\b${oldWord}\b`, 'gu');
      const regexCapitalized = new RegExp(String.raw`\b${oldWord[0].toUpperCase() + oldWord.toLowerCase().slice(1)}\b`, 'gu');
      const regexLower = new RegExp(String.raw`\b${oldWord}\b`, 'gu');
      const regexUpper = new RegExp(String.raw`\b${oldWord}\b`, 'gu');
      const regexIgnoreCase = new RegExp(String.raw`\b${oldWord}\b`, 'gui');

      const oldWordTest = regexIgnoreCase.test(workText.textContent);
      const newWordTest = regexIgnoreCase.test(workText.textContent);

      const hasBothWords = oldWordTest && newWordTest;

      // check that work only has one of the words
      if (hasBothWords) {
        alert(`Word Switcher: Work contains both ${oldWord} and ${newWord}. Please edit the work manually.`);
        return;
      }

      // work is already in preferred word
      if (newWordTest) {
        return;
      }

      function replaceWord(node, oldWord, newWord) {
        if (node.nodeType === Node.TEXT_NODE) {
            node.textContent = node.textContent.replace(oldWord, newWord);
        } else if (node.hasChildNodes()) {
            node.childNodes.forEach(childNode => {
              replaceWord(childNode, oldWord, newWord);
            });
        }
      }

      // normally cased word
      replaceWord(workText, regex, newWord);
      // capitalized word
      replaceWord(workText, regexCapitalized, newWord[0].toUpperCase() + newWord.slice(1).toLowerCase());
      // lowercased word
      replaceWord(workText, regexLower, newWord.toLowerCase());
      // uppercased word
      replaceWord(workText, regexUpper, newWord.toUpperCase());
    });
})();