ผู้ใช้:Octahedron80/catcat-wiktionary.js

จาก วิกิพจนานุกรม พจนานุกรมเสรี

หมายเหตุ: หลังเผยแพร่ คุณอาจต้องล้างแคชเว็บเบราว์เซอร์ของคุณเพื่อดูการเปลี่ยนแปลง

  • ไฟร์ฟอกซ์ / ซาฟารี: กด Shift ค้างขณะคลิก Reload หรือกด Ctrl-F5 หรือ Ctrl-R (⌘-R บนแมค)
  • กูเกิล โครม: กด Ctrl-Shift-R (⌘-Shift-R บนแมค)
  • อินเทอร์เน็ตเอกซ์พลอเรอร์ และ Edge: กด Ctrl ค้างขณะคลิก Refresh หรือกด Ctrl-F5
  • โอเปร่า: กด Ctrl-F5
/* <source lang="javascript"> */

/* FOR VECTOR-2022 AND VECTOR SKINS */
/* This script works best with stylesheet: catcat-wiktionary.css */

/* Required library outside normal pages */

/* Predefined variables */
var catcatVersion = '0.9.4';
var pageName = mw.config.get('wgPageName');
var pageTitle = mw.config.get('wgTitle');
var pageNamespaceNumber = mw.config.get('wgNamespaceNumber');
var currentSkin = mw.config.get('skin');
var indexUrl = mw.util.wikiScript('index');
var apiUrl = mw.util.wikiScript('api');
var commonsUrl = '//upload.wikimedia.org/wikipedia/commons';

var restrictionEdit = mw.config.get('wgRestrictionEdit');
var editable = (restrictionEdit === null || restrictionEdit.length === 0 ||
	mw.config.get('wgUserGroups').indexOf(restrictionEdit[0]) > -1);

/* wikiNamespace, wikiNamespaceKeys, replaceHeading, replaceHeadingKeys, replaceHeadword, replaceHeadwordKeys, categoryPattern */
mw.loader.load('//th.wiktionary.org/w/index.php?title=User:Octahedron80/catcat-wiktionary-data.js&action=raw&ctype=text/javascript');

/* Escaping string for regular expression */
RegExp.escape = function(text) {
	return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
};

function regexIndexOf(text, re, i) {
	var indexInSuffix = text.slice(i).search(re);
	return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + i;
}

function getLanguageCodeByName(langName) {
	var output = null;
	$.ajax({
		'type': 'POST',
		'url': apiUrl,
		'data': {
			'action': 'expandtemplates',
			'prop': 'wikitext',
			'text': '{{#invoke:languages/templates|getByCanonicalName|' + langName + '}}',
			'format': 'json',
			'utf8': '1'
		},
		'success': function(data) {
			if (data.expandtemplates.wikitext !== '') {
				output = data.expandtemplates.wikitext;
			}
		},
		'dataType': 'json',
		'async': false
	});
	if (output === null) { // second try
		$.ajax({
			'type': 'POST',
			'url': apiUrl,
			'data': {
				'action': 'expandtemplates',
				'prop': 'wikitext',
				'text': '{{#invoke:etymology languages/templates|getByCanonicalName|' + langName + '}}',
				'format': 'json',
				'utf8': '1'
			},
			'success': function(data) {
				if (data.expandtemplates.wikitext !== '') {
					output = data.expandtemplates.wikitext;
				}
			},
			'dataType': 'json',
			'async': false
		});
	}
	return output;
}

function getFamilyCodeByName(famName) {
	var output = null;
	$.ajax({
		'type': 'POST',
		'url': apiUrl,
		'data': {
			'action': 'expandtemplates',
			'prop': 'wikitext',
			'text': '{{#invoke:families/templates|getByCanonicalName|' + famName + '}}',
			'format': 'json',
			'utf8': '1'
		},
		'success': function(data) {
			if (data.expandtemplates.wikitext !== '') {
				output = data.expandtemplates.wikitext;
			}
		},
		'dataType': 'json',
		'async': false
	});
	return output;
}

function getScriptCodeByName(scName) {
	var output = null;
	$.ajax({
		'type': 'POST',
		'url': apiUrl,
		'data': {
			'action': 'expandtemplates',
			'prop': 'wikitext',
			'text': '{{#invoke:scripts/templates|getByCanonicalName|' + scName + '}}',
			'format': 'json',
			'utf8': '1'
		},
		'success': function(data) {
			if (data.expandtemplates.wikitext !== '') {
				output = data.expandtemplates.wikitext;
			}
		},
		'dataType': 'json',
		'async': false
	});
	return output;
}

/* For language headings */
function getCategoryNameFromAlias(alias) {
	var output = null;
	$.ajax({
		'type': 'POST',
		'url': apiUrl,
		'data': {
			'action': 'expandtemplates',
			'prop': 'wikitext',
			'text': '{{#invoke:catcat-wiktionary|getCategoryNameFromAlias|' + alias + '}}',
			'format': 'json',
			'utf8': '1'
		},
		'success': function(data) {
			if (data.expandtemplates.wikitext !== '') {
				output = data.expandtemplates.wikitext.replace('\n', '');
			}
		},
		'dataType': 'json',
		'async': false
	});
	return output;
}

function customizeToolbar($textarea) {
	$textarea.wikiEditor('addToToolbar', {
		'section': 'characters',
		'page': 'ipa',
		'characters': [ 'ᵊ', 'ᴬ', 'ᴮ', 'ꟲ', 'ᴰ', 'ᴸ', '⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹', 'm̥', 'n̥', 'ɳ̊', 'ɲ̊', 'ŋ̊', 'ɴ̥', 'j̊', 'r̥', 'ɾ̥', 'l̥', 'w̥' ]
	});
	$textarea.wikiEditor('addToToolbar', {
		'section': 'main', 'group': 'format', 'tools': {
			'underline': {
				'label': 'ขีดเส้นใต้',
				'type': 'button',
				'icon': commonsUrl + '/1/13/Toolbaricon_regular_U_underline.png',
				'action': {
					'type': 'encapsulate',
					'options': {
						'pre': '<u>', 'peri': 'ข้อความขีดเส้นใต้', 'post': '</u>'
					}
				}
			},
			'stroke': {
				'label': 'ขีดฆ่า',
				'type': 'button',
				'icon': commonsUrl + '/f/f9/Toolbaricon_regular_S_stroke.png',
				'action': {
					'type': 'encapsulate',
					'options': {
						'pre': '<s>', 'peri': 'ข้อความขีดฆ่า', 'post': '</s>'
					}
				}
			},
			'comment': {
				'label': 'หมายเหตุ',
				'type': 'button',
				'icon': commonsUrl + '/1/11/Toolbaricon_hiddencomment.png',
				'action': {
					'type': 'encapsulate',
					'options': {
						'pre': '<!--', 'peri': 'ข้อความหมายเหตุ', 'post': '-->'
					}
				}
			}
		}
	});
	$textarea.wikiEditor('addToToolbar', {
		'section': 'main',
		'groups': {
			'extra': {
				'tools': {
					'cleanup': {
						'label': 'เก็บกวาด',
						'type': 'button',
						'icon': commonsUrl + '/1/1d/Broom_tiny.png',
						'action': {
							'type': 'callback',
							'execute': function() {
								var content = $textarea.val();
								var titleRegExp = new RegExp(RegExp.escape('[[' + pageName + ']]'), 'g');
								var pronRegExp = new RegExp(RegExp.escape('{{th-pron|' + pageName + '}}'), 'g');
								content = content
									.replace(/^----/gm, '')								/* remove horizontal lines */
									.replace(/\t+/g, ' ')								/* replace tabs with spaces */
									//.replace(/ ?\( ?/gm, ' (')							/* reformat opening parentheses */
									//.replace(/ ?\) ?(?![\.,;\|\]\}])/gm, ') ')					/* reformat closing parentheses */
									//.replace(/ ?(\([ʔː]\)) ?/g, '$1')						/* de-space if (ʔ) & (ː) inside IPA */
									//.replace(/ ?, ?(?![0-9๐-๙]{3})/gm, ', ')					/* reformat commas */
									.replace(/^ +/gm, '')								/* trim leading spaces */
									.replace(/\| *\}\}/gm, '}}')							/* remove unnecessary pipes */
									.replace(/^([\*#:;]+|\|[-\+\|\}]?) */gm, '$1 ')					/* align lists, blocks, leading pipes */
									.replace(/ +$/gm, '')								/* trim trailing spaces */
									.replace(/ +/g, ' ')								/* remove repeated spaces */
									.replace(/\n\n+/g, '\n\n')							/* remove more-than-two newlines */
									.replace(/^(=+) *([^\n]*?) *(=+)$/gm, '$1 $2 $1')				/* align and fix headings */
									.replace(/\[\[([^\n]*?)\|\1\]\]/g, '[[$1]]')					/* cancel same substitutions */
									.replace(titleRegExp, pageName)						/* cancel self links */

									.replace(/(เ)\1/g, 'แ')								/* fix double 'e' to 'ae' */
									.replace(/(ເ)\1/g, 'ແ')
									.replace(/(ᦵ)\1/g, 'ᦶ')
									.replace(/(ᩮ)\1/g, 'ᩯ')
									.replace(/(ꪹ)\1/g, 'ꪵ')

									.replace(/ํ([่-๋]?)า/g, '$1ำ')							/* replace ํ+า to ำ */
									.replace(/ໍ([່-໋]?)າ/g, '$1ຳ')							/* replace ໍ+າ to ຳ */
									.replace(/ำ([่-๋])/g, '$1ำ')							/* swap position between ำ and tones */
									.replace(/ຳ([່-໋])/g, '$1ຳ')							/* swap position between ຳ and tones */

									.replace(/([ฤฦ])า/g, '$1ๅ')							/* replace ฤา/ฦา to ฤๅ/ฦๅ */
									.replace(/([ะ-ฺเ-ๅ็-๎])\1+/g, '$1')						/* remove repeated vowels and tones */
									.replace(/(.) +([ะ-ฺๅ็-๎])/g, '$1$2')						/* move up vowels and tones */
									.replace(/([^\s\(\{\[\|])(ๆ)/gm, '$1 $2')					/* add spaces around yamok 1 */
									.replace(/(ๆ)([^\s'"\)\}\]\.,])/gm, '$1 $2')					/* add spaces around yamok 2 */

									.replace(/^From /gm, 'จาก')
									.replace(/, from /gm, ', จาก')
									.replace(/^Cognate with /gm, 'ร่วมเชื้อสายกับ')
									.replace(/\. Cognate with /gm, '; ร่วมเชื้อสายกับ')
									.replace(/^Compare /gm, 'เทียบ')
									.replace(/\. Compare /gm, '; เทียบ')

									.replace(/(คำอ่าน|การออกเสียง)(เป็น)?ภาษาไทย: ?(.+)$/gm, '{{th-pron|$3}}')
									.replace(/^\*? ?\{\{คำอ่านไทย\|/gm, '{{th-pron|')
									.replace(/(\* \{\{IPA\|.+?\n)+(\{\{th-pron)/g, '$2')
									.replace(/(\{\{th-pron)(\|.+?)(\|lang=th)(\}\})/g, '$1$2$4')
									.replace(pronRegExp, '{{th-pron}}')
									.replace(/\* จำนวนพยางค์:? ?\d+\n/g, '')

									.replace(/^(=+ ?)\{\{หน้าที่\|(.+?)\|(.+?)\}\}( ?=+)/gm, function($0, $1, $2, $3, $4) {
										var out_text;
										if (posLang.indexOf($2) > -1) {
											out_text = $1 + 'คำ' + $3 + $4;
											out_text += '\n{{' + $2 + '-' + posTemplate[$3] + '}}';
											out_text += '\n�CHECK�';
										} else {
											out_text = $0; // no change
										}
										return out_text;
									})
									.replace(/(\{\{.+?\}\}\n)�CHECK�\n(\1)/g, '$1')
									.replace(/(\{\{.+?\}\}\n)�CHECK�\n(\{\{pn\}\}.*?\n)/g, '$1')
									.replace(/(\{\{.+?\}\}\n)�CHECK�\n(\{\{head\|[a-z]+?\}\}\n)/g, '$1')

									.replace(/\[\[(การ|ความ)\]\] *\+ *\[\[(.+?)\]\]/gm, '{{อุปสรรค|th|$1|$2}}')
									.replace(/\{\{initialism of\|/gm, '{{อักษรย่อ|')
									.replace(/\[\[หมวดหมู่:ภาษาไทย:(.+?)\]\]/gm, '{{topics|th|$1}}')

									/* replace Thai headings */
									.replace(/^(=+ ?)(.+?)( \d+)?( ?=+)/gm, function($0, $1, $2, $3, $4) {
										var heading, trueName;
										if (replaceHeading[$2]) {
											heading = replaceHeading[$2];
										} else {
											trueName = getCategoryNameFromAlias($2);
											if (trueName) {
												heading = trueName;
											} else {
												heading = $2;
											}
										}
										return $1 + heading + (typeof $3 != 'undefined' ? $3 : '') + $4;
									})

									/* replace Thai POS in headword templates */
									.replace(/^\{\{head\|(.+?)\|([^\|\}]+)/gm, function($0, $1, $2) {
										var pos = replaceHeadword[$2];
										return '{{head|' + $1 + '|' + (pos ? pos : $2);
									})

									/* remove repeated links */
									.replace(/\[\[([^\]]+?)\]\]/g, function($0, $1, pos, self) {
										return self.indexOf($0) === pos ? $0 : $1; 
									})
									
									/* replace some namespaces */
									.replace(new RegExp('\\b(' + wikiNamespaceKeys.join('|') + ')(?=:)', 'gi'), function($0) {
										return wikiNamespace[$0.toLowerCase()];
									})
									
									/* convert Thai links */
									.replace(/\[https?:\/\/th\.wiktionary\.org\/wiki\/([^ ]+?)\]/g, function(z, tt) {
										return '[[' + decodeURIComponent(tt) + ']]';
									})
									/* convert iw links */
									.replace(/\[https?:\/\/([-a-z]+)\.wiktionary\.org\/wiki\/([^ ]+?)\]/g, function(z, lg, tt) {
										return '[[:' + lg + ':' + decodeURIComponent(tt) + ']]';
									})
									/* wikify Thai links */
									.replace(/\[https?:\/\/th\.wiktionary\.org\/wiki\/(.+?) +(.+?)\]/g, function(z, tt, sb) {
										return '[[' + decodeURIComponent(tt) + '|' + sb + ']]';
									})
									/* wikify iw links */
									.replace(/\[https?:\/\/([-a-z]+)\.wiktionary\.org\/wiki\/(.+?) +(.+?)\]/g, function(z, lg, tt, sb) {
										return '[[:' + lg + ':' + decodeURIComponent(tt) + '|' + sb + ']]';
									})
									/* apply fullurl on Thai links */
									.replace(/https?:\/\/th\.wiktionary\.org\/w\/index\.php\?title=(.+?)&(.+?)(?=[\s\|\]<])/g, function(z, tt, qs) {
										return '{{fullurl:' + decodeURIComponent(tt) + '|' + qs + '}}';
									})
									/* apply fullurl on iw links */
									.replace(/https?:\/\/([-a-z]+)\.wiktionary\.org\/w\/index\.php\?title=(.+?)&(.+?)(?=[\s\|\]<])/g, function(z, lg, tt, qs) {
										return '{{fullurl:' + lg + ':' + decodeURIComponent(tt) + '|' + qs + '}}';
									})
									/* decode URI except special symbols */
									.replace(/(%[0-9A-F][0-9A-F])+/gi, function(z) {
										try { return decodeURI(z).replace(/ /g, "%20"); } catch (exception) { return z; }
									});
								$textarea.val(content);
								$('#wpSummary').val($('#wpSummary').val() + 'เก็บกวาด ');
							}
						}
					},
					'decomment': {
						'label': 'ลบหมายเหตุทั้งหมด',
						'type': 'button',
						'icon': commonsUrl + '/c/cd/Toolbaricon_remove_comment.png',
						'action': {
							'type': 'callback',
							'execute': function() {
								var content = $textarea.val();
								content = content.replace(/<!--(.|\n)*?-->/g, '');
								$textarea.val(content);
								$('#wpSummary').val($('#wpSummary').val() + 'ลบหมายเหตุทั้งหมด ');
							}
						}
					},
					'language-sort': {
						'label': 'เรียงลำดับหัวเรื่องภาษา',
						'type': 'button',
						'icon': commonsUrl + '/thumb/c/cc/AZ_Sort.svg/20px-AZ_Sort.svg.png',
						'action': {
							'type': 'callback',
							'execute': function() {
								if (pageNamespaceNumber != 0) {
									mw.notify('ฟังก์ชันนี้ใช้กับหน้าคำศัพท์เท่านั้น');
									return;
								}
								var content = $textarea.val() + '\n';
								var positions = [0];
								var pos = 0;
								while (pos != -1) {
									pos = regexIndexOf(content, /== ?(ภาษา.+?) ?==/, pos + 1);
									positions.push(pos);
								}
								if (positions.length == 2) { // only one part
									mw.notify('เนื้อหาในหน้านี้มีเพียงส่วนเดียว ไม่ต้องเรียงลำดับ');
									return;
								}
								var preParts = [null, null, null]; // pre-location for no-heading, mul, and th
								var otherParts = [];
								var part, matches;
								for (var i = 0; i < positions.length - 1; i++) {
									part = (positions[i + 1] == -1) ? content.slice(positions[i]) : content.slice(positions[i], positions[i + 1]);
									matches = part.match(/== ?(ภาษา.+?) ?==/);
									if (matches == null) {
										preParts[0] = part;
									} else if (matches[1] == 'ภาษาร่วม') {
										preParts[1] = part;
									} else if (matches[1] == 'ภาษาไทย') {
										preParts[2] = part;
									} else {
										otherParts.push(part);
									}
								}
								otherParts.sort(new Intl.Collator('th').compare);
								var allParts = preParts.concat(otherParts); // null is auto removed
								$textarea.val(allParts.join(''));
								$('#wpSummary').val($('#wpSummary').val() + 'เรียงลำดับหัวเรื่องภาษา ');
							}
						}
					}
				}
			}
		}
	});
};


$(function() {

	/* Working space */
	var NyaNya = {};
	NyaNya.show = function($obj) {
		$('div#nyanya').remove();
		if ($obj !== undefined && $obj !== null && $obj !== '') {
			$('#contentSub').append('<div id="nyanya" class="mw-ui-vform" />')
				.find('div#nyanya').html($obj).slideDown('fast').end();
		}
	};
	NyaNya.hide = function() {
		$('div#nyanya').fadeOut('slow', function() { $(this).remove(); });
	};
	NyaNya.$cancelButton = $('<button class="mw-ui-button">ยกเลิก</button>')
		.click(function() { NyaNya.hide(); });

	/* Extra selector 'econtains' */
	$.expr.pseudos.econtains = function(obj, index, meta, stack){
		return (obj.textContent || obj.innerText || $(obj).text() || "") == meta[3];
	};

	/* Notify version */
	var reloadLink = '<a href="javascript:window.location.reload(true)">🔃</a>';
	$('.catcat-check-version').html(catcatVersion + ' ' + reloadLink);
	var $projectLink = $('<li id="pt-catcat" class="mw-list-item"><a href="' + indexUrl
		+ '?title=Project:สคริปต์แมว ๆ" title="สคริปต์แมว ๆ">' + '🐱' + catcatVersion + '</a></li>');
	$('#p-personal ul').prepend($projectLink);
	if (currentSkin == "vector-2022") {
		$('#p-personal-sticky-header ul').prepend($projectLink.clone().attr("id", "pt-catcat-sticky-header"));
	}

	// Check if we're editing a page.
	if (['edit', 'submit'].indexOf(mw.config.get('wgAction')) !== -1 && mw.config.get('wgPageContentModel') == 'wikitext') {
		// Add a hook handler.
		mw.hook('wikiEditor.toolbarReady').add(customizeToolbar);
	}

	/* Extra tab menu */
	var $extraMenu = $('#p-cactions').clone().attr('id', 'p-extra');
	$extraMenu.find('span').text('ใหม่');
	var $extraMenuList = $extraMenu.find('ul').empty();

	if ($('#ca-edit a').attr('href') !== undefined) {
		var editFirstSectionLink = $('#ca-edit a').attr('href') + '&section=0';
		$('<li id="ca-edit-first" class="mw-list-item"><a title="แก้ไขส่วนแรก" href="' + editFirstSectionLink
			+ '">แก้ไขส่วนแรก</a></li>').appendTo($extraMenuList);

		var editNewSectionLink = $('#ca-edit a').attr('href') + '&section=new';
		$('<li id="ca-edit-new" class="mw-list-item"><a title="เพิ่มส่วนใหม่" href="' + editNewSectionLink
			+ '">เพิ่มส่วนใหม่</a></li>').appendTo($extraMenuList);
	}

	if ($('#ca-history a').attr('href') !== undefined) {
		var viewLatestDiffLink = $('#ca-history a').attr('href') + 'submit&diff=0';
		$('<li id="ca-latest-diff" class="mw-list-item"><a title="ส่วนต่างล่าสุด" href="' + viewLatestDiffLink
			+ '">ส่วนต่างล่าสุด</a></li>').appendTo($extraMenuList);
	}

	if ($('body').is('.ns--2, .ns--1') === false) {
		$('<li id="ca-red-link" class="mw-list-item"></li>').append('<a title="รายชื่อลิงก์แดง" href="#">รายชื่อลิงก์แดง</a>').click(function() {
			var $redLink = $('a.new').clone();
			var $redLinkNone = $('<span>ไม่มีลิงก์แดงที่ปรากฏในหน้านี้ </span>');
			var $redLinkForm = $('<span>นี่คือรายชื่อลิงก์แดงทั้งหมดที่ปรากฏในหน้านี้ </span><ul class="red-link"></ul>')
				.filter('span').append(NyaNya.$cancelButton.clone(true)).end()
				.filter('ul').append($redLink).find('a.new').wrap('<li></li>').end().end();
			if ($redLink.length === 0) {
				mw.notify($redLinkNone);
			} else {
				NyaNya.show($redLinkForm);
			}
		}).appendTo($extraMenuList);
	}

	if ($extraMenuList.find('li').length === 0) {
		$extraMenu.addClass('emptyPortlet');
	} else {
		$extraMenu.removeClass('emptyPortlet');
	}
	$('#p-views').after($extraMenu);

	/* Tag tab menu */
	var $tagMenu = $('#p-cactions').clone().attr('id', 'p-tag');
	$tagMenu.find('span').text('ป้าย');
	var $tagMenuList = $tagMenu.find('ul').empty();

	if ($('body').is('.ns--2, .ns--1, .ns-8') === false) {
		$('<li id="ca-tag-delete" class="mw-list-item"></li>').append('<a title="แจ้งลบ" href="#">แจ้งลบ</a>').click(function() {
			var $deleteProtect = $('<span>ไม่สามารถแจ้งลบ ' + pageName + ' เนื่องจากหน้านี้ได้รับการป้องกัน </span>')
				.filter('span').append(NyaNya.$cancelButton.clone(true)).end();
			if (!editable) {
				mw.notify($deleteProtect);
				return;
			}
			var $deleteForm = $('<span>ระบุเหตุผลของการแจ้งลบ: <input type="textbox" id="delete-reason" class="mw-ui-input mw-ui-input-inline" value=""></input> <button id="delete-submit" class="mw-ui-button mw-ui-destructive">แจ้งลบ</button> </span>')
				.filter('span').append(NyaNya.$cancelButton.clone(true)).end()
				.find('#delete-reason').keyup(function(event) {
					if (event.keyCode == 13) { /* enter key */
						$('#delete-submit').click();
					}
				}).end()
				.find('#delete-submit').click(function() {
					var deleteReason = $('#delete-reason').val().replace(/=/g, '{{=}}');
					mw.notify('กำลังดำเนินการแจ้งลบ ' + pageName + ' ...');
					var prependText;
					if ($('body').is('.ns-4, .ns-10') === true) { /* project or template */
						prependText = '<noinclude>{{ลบ|' + deleteReason + '}}</noinclude>\n';
					} else {
						prependText = '{{ลบ|' + deleteReason + '}}\n';
					}
					$.post(apiUrl, {
						'action': 'edit',
						'title': pageName,
						'section': '0',
						'summary': 'แจ้งลบ',
						'minor': '1',
						'prependtext': prependText,
						'nocreate': '1',
						'token': mw.user.tokens.get('csrfToken'),
						'format': 'xml'
					}, function() {
						mw.notify('แจ้งลบ ' + pageName + ' เรียบร้อยแล้ว กรุณารอสักครู่');
						setInterval(location.assign(indexUrl + '?title=' + encodeURIComponent(pageName)), 3000);
					}, 'xml');
				}).end();
			NyaNya.show($deleteForm);
			$('#delete-reason').focus();
		}).appendTo($tagMenuList);
	}

	if ($tagMenuList.find('li').length === 0) {
		$tagMenu.addClass('emptyPortlet');
	} else {
		$tagMenu.removeClass('emptyPortlet');
	}
	$('#p-extra').after($tagMenu);

	/* Auto-creation of Thai abstract nouns */
	var thAbsNounPrefix = { 'การ':'กาน-', 'ความ':'คฺวาม-' };
	var $thSection = $('h2:contains("ภาษาไทย")').nextUntil('h2');
	$thSection.find('.abstract-noun-form-of a').each(function() {
		var $wordLink = $(this);
		if ($wordLink.hasClass('new')) {
			var $createButton = $('<button>✱</button>').click(function() {
				$(this).fadeOut();
				$wordLink.fadeOut();
				
				var the_form = $wordLink.text();
				var matches = $wordLink.text().match(/^(การ|ความ)/);
				var type = (matches === null) ? null : matches[0];
				var $reading = $thSection.find('.th-reading');
				
				var buffer = '== ภาษาไทย ==\n\n=== รากศัพท์ ===\n';
				buffer += (type === null) ? '???\n' : '{{อุปสรรค|th|' + type + '|' + pageTitle + '}}\n';
				buffer += '\n=== การออกเสียง ===\n';
				$reading.each(function() {
					var thaiReadingText = thAbsNounPrefix[type] + $(this).text();
					buffer += '{{th-pron|' + thaiReadingText + '}}\n';
				});
				buffer += '\n=== คำนาม ===\n{{th-noun}}\n\n# {{abstract noun of|th|' + pageTitle + '}}';
				
				$.post(apiUrl, {
					'action': 'edit',
					'title': the_form,
					'summary': 'สร้างคำอัตโนมัติ',
					'createonly': '1',
					'appendtext': buffer,
					'token': mw.user.tokens.get('csrfToken'),
					'format': 'xml'
				}, function() {
					mw.notify('สร้างหน้า ' + the_form + ' เรียบร้อยแล้ว');
					$wordLink.removeClass('new').attr('href', function(i, val) {
						return val.replace('&action=edit&redlink=1', '');
					}).fadeIn();
				}, 'xml');
			});
			$wordLink.after($createButton).after('&lrm;');
		}
	});

	/* Auto-creation of Lao abstract nouns (not adding pronunciation) */
	var loAbsNounPrefix = { 'ການ':'ການ-', 'ຄວາມ':'ຄວາມ-' };
	var $loSection = $('h2:contains("ภาษาลาว")').nextUntil('h2');
	$loSection.find('.abstract-noun-form-of a').each(function() {
		var $wordLink = $(this);
		if (/*$wordLink.hasClass('new')*/true) { //temp for remake
			var $createButton = $('<button>✱</button>').click(function() {
				$(this).fadeOut();
				$wordLink.fadeOut();
				
				var the_form = $wordLink.text();
				var matches = $wordLink.text().match(/^(ການ|ຄວາມ)/);
				var type = (matches === null) ? null : matches[0];
				var $reading = $loSection.find('.lo-reading');
				
				var buffer = '== ภาษาลาว ==\n\n=== รากศัพท์ ===\n';
				buffer += (type === null) ? '???\n' : '{{อุปสรรค|lo|' + type + '|' + pageTitle + '}}\n';
				buffer += '\n=== การออกเสียง ===\n';
				$reading.each(function() {
					var laoReadingText = loAbsNounPrefix[type] + $(this).text();
					buffer += '{{lo-pron|' + laoReadingText + '}}\n';
				});
				buffer += '\n=== คำนาม ===\n{{lo-noun}}\n\n# {{abstract noun of|lo|' + pageTitle + '}}';
				
				$.post(apiUrl, {
					'action': 'edit',
					'title': the_form,
					'summary': 'สร้างคำอัตโนมัติ',
					//'createonly': '1', temp for remake
					//'appendtext': buffer,
					'text': buffer,
					'token': mw.user.tokens.get('csrfToken'),
					'format': 'xml'
				}, function() {
					mw.notify('สร้างหน้า ' + the_form + ' เรียบร้อยแล้ว');
					$wordLink.removeClass('new').attr('href', function(i, val) {
						return val.replace('&action=edit&redlink=1', '');
					}).fadeIn();
				}, 'xml');
			});
			$wordLink.after($createButton).after('&lrm;');
		}
	});

	/* Auto-creation of Northern Thai abstract nouns (not adding pronunciation) */
	//var nodAbsNounPrefix = { 'ᨠᩣ᩠ᩁ':'ka-n', 'ก๋าร':'ka-n', 'ก๋าน':'ka-n', 'ᨣᩤᩴ':'kam', 'กำ':'kam', 'ᨤ᩠ᩅᩣ᩠ᨾ':'khwa-m', 'ความ':'khwa-m' };
	var $nodSection = $('h2:contains("ภาษาคำเมือง")').nextUntil('h2');
	$nodSection.find('.abstract-noun-form-of a').each(function() {
		var $wordLink = $(this);
		if ($wordLink.hasClass('new')) {
			var $createButton = $('<button>✱</button>').click(function() {
				$(this).fadeOut();
				$wordLink.fadeOut();
				
				var the_form = $wordLink.text();
				var matches = $wordLink.text().match(/^(ᨠᩣ᩠ᩁ|ก๋าร|ก๋าน|ᨣᩤᩴ|กำ|ᨤ᩠ᩅᩣ᩠ᨾ|ความ)/);
				var type = (matches === null) ? null : matches[0];
				//var $reading = $nodSection.find('.nod-reading');
				
				var buffer = '== ภาษาคำเมือง ==\n\n=== รากศัพท์ ===\n';
				buffer += (type === null) ? '???\n' : '{{อุปสรรค|nod|' + type + '|' + pageTitle + '}}\n';
				buffer += '\n=== คำนาม ===\n{{nod-noun}}\n\n# {{abstract noun of|nod|' + pageTitle + '}}';
				
				$.post(apiUrl, {
					'action': 'edit',
					'title': the_form,
					'summary': 'สร้างคำอัตโนมัติ',
					'createonly': '1',
					'appendtext': buffer,
					'token': mw.user.tokens.get('csrfToken'),
					'format': 'xml'
				}, function() {
					mw.notify('สร้างหน้า ' + the_form + ' เรียบร้อยแล้ว');
					$wordLink.removeClass('new').attr('href', function(i, val) {
						return val.replace('&action=edit&redlink=1', '');
					}).fadeIn();
				}, 'xml');
			});
			$wordLink.after($createButton).after('&lrm;');
		}
	});

	/* Auto-creation of Japanese romajis */
	var $jaSection = $('h2:contains("ภาษาญี่ปุ่น")').nextUntil('h2');
	$jaSection.find('.romanized-form-of a').each(function() {
		var $wordLink = $(this);
		if ($wordLink.hasClass('new')) {
			var $createButton = $('<button>✱</button>').click(function() {
				$(this).fadeOut();
				$wordLink.fadeOut();
				
				var the_form = $wordLink.text();
				var $kana = $jaSection.find('.kana-form-of a');
				var buffer = '== ภาษาญี่ปุ่น ==\n\n=== การถอดเป็นอักษรโรมัน ===\n{{ja-romaji}}\n\n';
				if ($kana.length !== 0) {
					$kana.each(function() {
						buffer += '# {{ja-romanization of|' + $(this).text() + '}}\n';
					});
				} else {
					buffer += '# {{ja-romanization of|' + pageTitle + '}}\n';
				}
				
				$.post(apiUrl, {
					'action': 'edit',
					'title': the_form,
					'summary': 'สร้างคำอัตโนมัติ',
					'createonly': '1',
					'appendtext': buffer,
					'token': mw.user.tokens.get('csrfToken'),
					'format': 'xml'
				}, function() {
					mw.notify('สร้างหน้า ' + the_form + ' เรียบร้อยแล้ว');
					$wordLink.removeClass('new').attr('href', function(i, val) {
						return val.replace('&action=edit&redlink=1', '');
					}).fadeIn();
				}, 'xml');
			});
			$wordLink.after($createButton).after('&lrm;');
		}
	});

	/* Auto-creation of Esparanto non-lemma forms */
	var $eoSection = $('h2:contains("ภาษาเอสเปรันโต")').nextUntil('h2');
	$eoSection.find('.form-of a').each(function() {
		var $wordLink = $(this);
		var uncountable = $wordLink.parent().parent().hasClass('uncountable-accusative-form-of');
		var capital = /^[A-ZĈĜĤĴŜŬ]/.test(pageTitle)
		if ($wordLink.hasClass('new')) {
			var $createButton = $('<button>✱</button>').click(function() {
				$(this).fadeOut();
				$wordLink.fadeOut();
				
				var the_form = $wordLink.text();
				var root = pageTitle.slice(0, -1); /* cut off last letter */
				var suffix = the_form.slice(root.length)
				
				var buffer = '== ภาษาเอสเปรันโต ==\n\n=== การออกเสียง ===\n{{eo-IPA}}\n\n';
				if (suffix == 'on' || suffix == 'oj' || suffix == 'ojn'
					|| suffix == 'anto' || suffix == 'anton' || suffix == 'antoj' || suffix == 'antojn'
					|| suffix == 'into' || suffix == 'inton' || suffix == 'intoj' || suffix == 'intojn'
					|| suffix == 'onto' || suffix == 'onton' || suffix == 'ontoj' || suffix == 'ontojn'
					|| suffix == 'ato' || suffix == 'aton' || suffix == 'atoj' || suffix == 'atojn'
					|| suffix == 'ito' || suffix == 'iton' || suffix == 'itoj' || suffix == 'itojn'
					|| suffix == 'oto' || suffix == 'oton' || suffix == 'otoj' || suffix == 'otojn') {
					if (capital) {
						buffer += '=== คำวิสามานยนาม ===\n';
					} else {
						buffer += '=== คำนาม ===\n';
					}
				} else if (suffix == 'an' || suffix == 'aj' || suffix == 'ajn'
					|| suffix == 'anta' || suffix == 'antan' || suffix == 'antaj' || suffix == 'antajn'
					|| suffix == 'inta' || suffix == 'intan' || suffix == 'intaj' || suffix == 'intajn'
					|| suffix == 'onta' || suffix == 'ontan' || suffix == 'ontaj' || suffix == 'ontajn'
					|| suffix == 'ata' || suffix == 'atan' || suffix == 'ataj' || suffix == 'atajn'
					|| suffix == 'ita' || suffix == 'itan' || suffix == 'itaj' || suffix == 'itajn'
					|| suffix == 'ota' || suffix == 'otan' || suffix == 'otaj' || suffix == 'otajn') {
					buffer += '=== คำคุณศัพท์ ===\n';
				} else if (suffix == 'is' || suffix == 'as' || suffix == 'os' || suffix == 'us' || suffix == 'u') {
					buffer += '=== คำกริยา ===\n';
				} else if (suffix == 'ante' || suffix == 'inte' || suffix == 'onte'
					|| suffix == 'ate' || suffix == 'ite' || suffix == 'ote') {
					buffer += '=== คำกริยาวิเศษณ์ ===\n';
				} else {
					buffer += '=== คำ??? ===\n';
				}
				buffer += '{{eo-head}}\n\n# {{eo-form of|' + root + '|' + suffix;
				if (uncountable) {
					if (capital) {
						buffer += '-proper';
					} else {
						buffer += '|unc=yes';
					}
				}
				buffer += '}}\n';
				
				$.post(apiUrl, {
					'action': 'edit',
					'title': the_form,
					'summary': 'สร้างคำอัตโนมัติ',
					'createonly': '1',
					'appendtext': buffer,
					'token': mw.user.tokens.get('csrfToken'),
					'format': 'xml'
				}, function() {
					mw.notify('สร้างหน้า ' + the_form + ' เรียบร้อยแล้ว');
					$wordLink.removeClass('new').attr('href', function(i, val) {
						return val.replace('&action=edit&redlink=1', '');
					}).fadeIn();
				}, 'xml');
			});
			$wordLink.after($createButton).after('&lrm;');
		}
	});

	/* Auto-creation of categories */
	var $targetSection = $('.mw-normal-catlinks, .mw-spcontent');
	$targetSection.find('a').each(function() {
		var $catLink = $(this);
		if ($catLink.hasClass('new') && $catLink.attr('title').match(/^หมวดหมู่:/)) {
			var $createButton = $('<button>✱</button>').click(function() {
				$(this).fadeOut();
				$catLink.fadeOut();

				if ($catLink.text().match(/[a-z]/i)) {
					$(this).fadeIn();
					$catLink.fadeIn();
					mw.notify('ไม่สามารถสร้างได้ เนื่องจากข้อความบางส่วนยังไม่ได้แปล');
					return; // exit
				}

				var matches = null;
				var buffer;
				for (var i = 0; i < categoryPattern.length; i++) {
					// looking for available patterns
					matches = $catLink.text().match(new RegExp(categoryPattern[i].pattern));
					if (matches !== null) {
						buffer = categoryPattern[i].content;
						// loop to replace, start at 1
						for (var j = 1; j < matches.length; j++) {
							if (buffer.indexOf('$M' + j) > -1) {
								buffer = buffer.replace('$M' + j, matches[j]);
							}
							if (buffer.indexOf('$L' + j) > -1) {
								buffer = buffer.replace('$L' + j, getLanguageCodeByName(matches[j]));
							}
							if (buffer.indexOf('$F' + j) > -1) {
								buffer = buffer.replace('$F' + j, getFamilyCodeByName(matches[j]));
							}
							if (buffer.indexOf('$S' + j) > -1) {
								buffer = buffer.replace('$S' + j, getScriptCodeByName(matches[j]));
							}
						}
						break;
					}
				}

				if (matches === null) {
					$(this).fadeIn();
					$catLink.fadeIn();
					mw.notify('ไม่สามารถสร้างได้ เนื่องจากรูปแบบยังไม่รองรับ');
					return; // exit
				}

				$.post(apiUrl, {
					'action': 'edit',
					'title': 'หมวดหมู่:' + $catLink.text(),
					'summary': 'สร้างหมวดหมู่อัตโนมัติ',
					'createonly': '1',
					'appendtext': buffer,
					'token': mw.user.tokens.get('csrfToken'),
					'format': 'xml'
				}, function() {
					mw.notify('สร้างหน้า ' + $catLink.text() + ' เรียบร้อยแล้ว');
					$catLink.removeClass('new').attr('href', function(i, val) {
						return val.replace('&action=edit&redlink=1', '');
					}).fadeIn();
				}, 'xml');
			});
			$catLink.after($createButton).after('&lrm;');
		}
	});

});

/* </source> */