利用者:Sat.d.h./modern-ja-writing.js

注意: 保存後、変更を確認するにはブラウザーのキャッシュを消去する必要がある場合があります。

  • Firefox / Safari: Shift を押しながら 再読み込み をクリックするか、Ctrl-F5 または Ctrl-R を押してください (Mac では ⌘-R)
  • Google Chrome: Ctrl-Shift-R を押してください (Mac では ⌘-Shift-R)
  • Internet Explorer / Microsoft Edge: Ctrl を押しながら 最新の情報に更新 をクリックするか、Ctrl-F5 を押してください
  • Opera: Ctrl-F5を押してください
/**
 * メニューを画面上部に配置。
 * クリック時にカタカナをひらがなに、旧字体を新字体に置換
 * ※class属性がkatakanaの要素はひらがなに置換しない
 */
$(function() {
	'use strict';

	// 標準ページとユーザページとWikisourceページに適用
	var namespaceNumber = mw.config.get('wgNamespaceNumber');
	if (namespaceNumber !== 0 && namespaceNumber !== 2 && namespaceNumber !== 4) return;

	var $convertTab = $('#p-variants');
	var $hantHira = $('<li>');
	var $hanjKana = $('<li>');
	var $hanjHira = $('<li>');
	var dfd = new $.Deferred();
	var hentaigana = {
		'コト': /ヿ/g,
		'シテ': /𬼀/g,
		'トモ': /𪜈/g,
		'より': /ゟ/g,
		'なり': /𬼂/g,
		'ます': /〼/g,
		'エ': /𛀀/g,
		'あ': /(𛀂|𛀃|𛀄)/g,
		'い': /(𛀆|𛀇|𛀈|𛀉)/g,
		'う': /(𛀊|𛀋|𛀌|𛀍|𛀎)/g,
		'え': /(𛀁|𛀏|𛀐|𛀑|𛀒|𛀓)/g,
		'お': /(𛀔|𛀕|𛀖)/g,
		'か': /(𛀗|𛀘|𛀙|𛀚|𛀛|𛀜|𛀝|𛀞|𛀟|𛀠|𛀡)/g,
		'き': /(𛀣|𛀤|𛀥|𛀦|𛀧|𛀨|𛀩|𛀪)/g,
		'く': /(𛀫|𛀬|𛀭|𛀮|𛀯|𛀰|𛀱)/g,
		'け': /(𛀲|𛀳|𛀴|𛀵|𛀶|𛀷)/g,
		'こ': /(𛀸|𛀹|𛀺)/g,
		'さ': /(𛀼|𛀽|𛀾|𛀿|𛁀|𛁁|𛁂|𛁃)/g,
		'し': /(𛁄|𛁅|𛁆|𛁇|𛁈|𛁉)/g,
		'す': /(𛁊|𛁋|𛁌|𛁍|𛁎|𛁏|𛁐|𛁑)/g,
		'せ': /(𛁒|𛁓|𛁔|𛁕|𛁖)/g,
		'そ': /(𛁗|𛁘|𛁙|𛁚|𛁛|𛁜|𛁝)/g,
		'た': /(𛁞|𛁟|𛁠|𛁡)/g,
		'ち': /(𛁢|𛁣|𛁤|𛁥|𛁦|𛁧|𛁨)/g,
		'つ': /(𛁩|𛁪|𛁫|𛁬)/g,
		'て': /(𛁮|𛁯|𛁰|𛁱|𛁲|𛁳|𛁴|𛁵|𛁶)/g,
		'と': /(𛁷|𛁸|𛁹|𛁺|𛁻|𛁼)/g,
		'な': /(𛁾|𛁿|𛂀|𛂁|𛂂|𛂃|𛂄|𛂅|𛂆)/g,
		'に': /(𛂇|𛂈|𛂉|𛂊|𛂋|𛂌|𛂍|𛂎)/g,
		'ぬ': /(𛂏|𛂐|𛂑)/g,
		'ね': /(𛂒|𛂓|𛂔|𛂕|𛂖|𛂗)/g,
		'の': /(𛂙|𛂚|𛂛|𛂜|𛂝)/g,
		'は': /(𛂞|𛂟|𛂠|𛂡|𛂢|𛂣|𛂤|𛂥|𛂦|𛂧|𛂨)/g,
		'ひ': /(𛂩|𛂪|𛂫|𛂬|𛂭|𛂮|𛂯)/g,
		'ふ': /(𛂰|𛂱|𛂲)/g,
		'へ': /(𛂳|𛂴|𛂵|𛂶|𛂷|𛂸|𛂹)/g,
		'ほ': /(𛂺|𛂻|𛂼|𛂽|𛂾|𛂿|𛃀|𛃁)/g,
		'ま': /(𛃂|𛃃|𛃄|𛃅|𛃆|𛃇|𛃈)/g,
		'み': /(𛃉|𛃊|𛃋|𛃌|𛃍|𛃎|𛃏)/g,
		'む': /(𛃐|𛃑|𛃒|𛃓)/g,
		'め': /(𛃔|𛃕)/g,
		'も': /(𛃗|𛃘|𛃙|𛃚|𛃛|𛃜)/g,
		'や': /(𛃝|𛃞|𛃟|𛃠|𛃡)/g,
		'ゆ': /(𛃣|𛃤|𛃥|𛃦)/g,
		'よ': /(𛃧|𛃨|𛃩|𛃪|𛃫|𛃬)/g,
		'ら': /(𛃭|𛃮|𛃯|𛃰)/g,
		'り': /(𛃱|𛃲|𛃳|𛃴|𛃵|𛃶|𛃷)/g,
		'る': /(𛃸|𛃹|𛃺|𛃻|𛃼|𛃽)/g,
		'れ': /(𛃾|𛃿|𛄀|𛄁)/g,
		'ろ': /(𛄂|𛄃|𛄄|𛄅|𛄆|𛄇)/g,
		'わ': /(𛄈|𛄉|𛄊|𛄋|𛄌)/g,
		'ゐ': /(𛄍|𛄎|𛄏|𛄐|𛄑)/g,
		'ゑ': /(𛄒|𛄓|𛄔|𛄕)/g,
		'を': /(𛄖|𛄗|𛄘|𛄙|𛄚|𛄛|𛄜)/g,
	};

	// 表記変換メニューの表示
	$convertTab.removeClass('emptyPortlet');
	$convertTab.attr('id', 'cnv-btn');
	$('#p-variants-label').removeAttr('id');
	$convertTab.find('span').html('表記変換');
	$hantHira.append('<a id="hant-hira">ひらがな</a>');
	$hanjKana.append('<a id="hanj-kana">新字体</a>');
	$hanjHira.append('<a id="hanj-hira">新字体+ひらがな</a>');
	$convertTab.find('ul').append($hantHira, $hanjKana, $hanjHira);

	$hantHira.on('click', function() {
		// console.log('舊字ひらがな');
		execute(true, false);
	});
	$hanjKana.on('click', function() {
		// console.log('新字カタカナ');
		execute(false, true);
	});
	$hanjHira.on('click', function() {
		// console.log('新字ひらがな');
		execute(true, true);
	});

	function execute(hiraFlag, hanFlag) {
		for (var key in hentaigana) {
			document.getElementById('mw-content-text').innerHTML =
				document.getElementById('mw-content-text').innerHTML.replace(hentaigana[key], key);
		}

		if (hiraFlag) convertHira();
		if (hanFlag) convertHan();

		// 画像フォントをAlt文字に置換 (width<20は一般画像との区分け)
		$('#mw-content-text img[alt]').each(function(i, image) {
			if ($(image).width() < 20) $(image).replaceWith(document.createTextNode(image.alt));
		});

		// 原文に戻すボタンに置き換え
		$convertTab.addClass('cnv-undo');
		$convertTab.find('ul').html('<li><a>元に戻す</a></li>').addClass('cnv-undo');
		$convertTab.removeClass('menuForceShow');
	}

	function convertHira() {
		// カタカナの箇所の記録→ひらがな変換→カタカナの箇所を元に戻す
		var kanaInner = [];
		var i = 0;
		$('.katakana').each(function(){
			kanaInner[i] = this.innerHTML;
			i++;
		});

		if ($('#navigationNotes')[0]) {
			$('#navigationNotes').nextUntil('.printfooter',
				'h1, h2, h3, h4, h5, h6, p, div, ol, ul, dl, table').each(converter);
		} else if ($('#navigationHeader')[0]) {
			$('#navigationHeader').nextUntil('.printfooter',
				'h1, h2, h3, h4, h5, h6, p, div, ol, ul, dl, table').each(converter);
		} else {
			$('#mw-content-text').find('h1, h2, h3, h4, h5, h6, p, div, li, dt, dd, th, td')
				.each(converter);
		}
		function converter(i, elem) {
			elem.innerHTML = elem.innerHTML.replace(/<.+?>|([ァ-ン])/g, function(match, p1) {
				if (!p1) return match;
				return String.fromCharCode(p1.charCodeAt(0) - 0x60);
			});
		}

		i = 0;
		$('.katakana').each(function(){
			this.innerHTML = kanaInner[i];
			i++;
		});
	}

	function convertHan() {
		getDic();
		dfd.promise().then(function(dicData) {
			var content = document.getElementById('mw-content-text');
			var rp_data0 = arrangeData(dicData);

			if ($('.k-ancient1').length) {
				//html内の置換定義を取得・マージ
				var rp_data1 = setReplaceData();
				$.extend(rp_data0, rp_data1);
			}

			$.each(rp_data0, function(key, value) {
				var reg = new RegExp('<.+?>|(' + key + ')', 'g');
				content.innerHTML = content.innerHTML.replace(reg, function(match, p1) {
					if (!p1) return match;
					return value;
				});
			});

			//異体字セレクタ(U+E0100からU+E01EF)の一括削除
			content.innerHTML = content.innerHTML.replace(/\uDB40[\uDD00-\uDDEF]/g, '');
		});
	}

	//ページ内の置換文字定義を取得(区切り文字「は」→「:」、「、」→「,」に置換)
	function setReplaceData() {
		var str0 = $('.k-ancient1').text().replace(/は/g, '\":\"').replace(/、/g,'\", \"');
		var strj = JSON.parse('{\"' + str0 + '\"}');
		return strj;
	}

	//辞書データの取得
	function getDic() {
		//辞書ページのPAGEIDS:'16658'
		var pageids = '16658';

		//データの中のマーカー
		var dAstr = '*';
		$.ajax({
			type: 'GET',
			scriptCharset: 'utf-8',
			dataType: 'jsonp',
			url: 'https://ja.wikisource.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&pageids='+pageids,
			timeout: 5000,
		})
		.done(function(json) {
			var data = json.query.pages[pageids].revisions[0][dAstr];
			dfd.resolve(data);
		})
		.fail(function() {
			alert('辞書読取エラー');
		});
	}

	// データの整形、ユニコード文字化
	function arrangeData(ddata) {
		var lines = ddata.split('\n');
		var strD = [];
		var strK;
		for (var i = 1; i < lines.length-1; i++) {
			if (lines[i].match(/\*\s*([\S]*)\s*[::→]\s*([\S]*)/)) {
				if (strD.length) strD += ', ';
				strD += '\"' + RegExp.$1 + '\":\"' + RegExp.$2 + '\"';
			}
		}
		strD=strD.replace(/&#x([0-9A-F]{4,5});/gi, function() {
			var uni;
			var hi;
			var lo;
			if (arguments[1].length === 4) {
				return unescape('%u' + arguments[1]);
			} else {
				// サロゲートペアに変換
				uni = parseInt(arguments[1], 16) - 0x10000;
				hi = Math.floor(uni / 0x400) + 0xD800;
				lo = uni % 0x400 + 0xDC00;
				return unescape('%u' + hi.toString(16) + '%u' + lo.toString(16));
			}
		});

		strK = JSON.parse('{' + strD + '}');
		return strK;
	}

	// 原文に戻るボタン(リロード処理)
	$(document).on('click', '.cnv-undo', function() {
		window.location.reload();
	});
});