Created
September 11, 2025 17:20
-
-
Save Shinichi-Ohki/4955a79643fbfd0f883db3062b5a0df9 to your computer and use it in GitHub Desktop.
ページ内の元号を西暦に置き換えるtampermonkey用スクリプト
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
// ==UserScript== | |
// @name 元号を西暦に置き換える | |
// @namespace http://tampermonkey.net/ | |
// @version 1.0 | |
// @description ページ内の元号を西暦に置き換えます | |
// @author Shinichi Ohki | |
// @match *://*/* | |
// @grant none | |
// ==/UserScript== | |
(function () { | |
'use strict'; | |
// 各元号の開始年 | |
const eraStartYears = { | |
'令和': 2019, | |
'平成': 1989, | |
'昭和': 1926, | |
'大正': 1912, | |
'明治': 1868 | |
}; | |
// 元号を西暦に置き換える関数 | |
function replaceEraWithWesternYear(text) { | |
// 元号のパターンをマッチさせる正規表現 | |
const escapedEras = Object.keys(eraStartYears).map(era => | |
era.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') | |
).join('|'); | |
// 年号のパターンをマッチ(半角・全角数字両対応) | |
const re = new RegExp(`(${escapedEras})([\\d0-9]+|元)年度?`, 'g'); | |
return text.replace(re, (match, era, year) => { | |
const startYear = eraStartYears[era]; | |
if (startYear !== undefined) { | |
let westernYear; | |
if (year === '元') { | |
westernYear = startYear; | |
} else { | |
// 全角数字を半角に変換してから計算 | |
let numericYear = year; | |
const zenToHan = { | |
'0': '0', '1': '1', '2': '2', '3': '3', '4': '4', | |
'5': '5', '6': '6', '7': '7', '8': '8', '9': '9' | |
}; | |
for (let zen in zenToHan) { | |
numericYear = numericYear.replace(new RegExp(zen, 'g'), zenToHan[zen]); | |
} | |
westernYear = startYear + parseInt(numericYear) - 1; | |
} | |
return `西暦${westernYear}年${match.includes('年度') ? '度' : ''}`; | |
} | |
return match; // 変換できなければそのまま | |
}); | |
} | |
// テキストノードを走査して置換する関数 | |
function replaceTextNodes(node) { | |
if (node.nodeType === Node.TEXT_NODE) { | |
const text = node.textContent; | |
const newText = replaceEraWithWesternYear(text); | |
if (newText !== text) { | |
node.textContent = newText; | |
} | |
} else { | |
// 子要素も再帰的に処理 | |
for (let i = 0; i < node.childNodes.length; i++) { | |
replaceTextNodes(node.childNodes[i]); | |
} | |
} | |
} | |
// DOMが読み込まれた後に実行 | |
if (document.readyState === 'loading') { | |
document.addEventListener('DOMContentLoaded', () => { | |
replaceTextNodes(document.body); | |
}); | |
} else { | |
replaceTextNodes(document.body); | |
} | |
// 動的に追加されるコンテンツにも対応 | |
const observer = new MutationObserver((mutations) => { | |
mutations.forEach((mutation) => { | |
mutation.addedNodes.forEach((node) => { | |
if (node.nodeType === Node.ELEMENT_NODE) { | |
replaceTextNodes(node); | |
} | |
}); | |
}); | |
}); | |
observer.observe(document.body, { | |
childList: true, | |
subtree: true | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment