Skip to content

Instantly share code, notes, and snippets.

@Shinichi-Ohki
Created September 11, 2025 17:20
Show Gist options
  • Save Shinichi-Ohki/4955a79643fbfd0f883db3062b5a0df9 to your computer and use it in GitHub Desktop.
Save Shinichi-Ohki/4955a79643fbfd0f883db3062b5a0df9 to your computer and use it in GitHub Desktop.
ページ内の元号を西暦に置き換えるtampermonkey用スクリプト
// ==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