User:Zackmann08/scripts/indent.js
;
// code copied from [[User:Frietjes/indent.js]]";
importScript('User:Zackmann08/scripts/wait.js');
const MAX_PARAM_LENGTH = 25
var long_labels = [ ];
// -------------------------------------------------------------------------------- //
function wpIndent(s)
{
var alignflag = 0;
// Mangle file/image link
while(s.search(/(\[\[[\t _]*(?:image|file)[\t _]*:[^\[\]=]*)=/gi) >=0 ) {
s = s.replace(/(\[\[[\t _]*(?:image|file)[\t _]*:[^\[\]=]*)=/gi, '$1<!-- FIX EQ MARKER -->');
}
// Mangle html tags
while(s.search(/(<[\t \r\n]*[a-z]+[^<>]*)=/gi) >=0 ) {
s = s.replace(/(<[\t \r\n]*[a-z]+[^<>]*)=/gi, '$1<!-- FIX EQ MARKER -->');
}
// Election box
s = s.replace(/(\{\{[_ ]*[Ee]lection[_ ]*box[^{}\|\r\n]*[a-z])[\t ]*\|[\t ]*([\r\n][\t ]*\|)/g, '$1$2');
// Mark some spacing
s = s.replace(/(= ) (\|)/g, '$1<!-- SPACE MARKER -->$2');
// Some fixes for the case where infoboxes have the pipes at the end of the line
var old = '';
while(s != old) {
old = s;
s = s.replace(/(\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ss]peciesbox|[Ff]ootball[_ ]*box)(?:\{\{(?:\{\{(?:\{\{[^{}]*\}\}|[^{}])*\}\}|[^{}])*\}\}|[^{}])*)(\|)[\t ]*([\r\n])/gim, '$1$3$2');
}
s = s.replace(/(\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ss]peciesbox|[Ff]ootball[_ ]*box)(?:\{\{(?:\{\{(?:\{\{[^{}]*\}\}|[^{}])*\}\}|[^{}])*\}\}|[^{}])*)[\t\r\n ]*\|[\t ]*([\r\n][\t ]*\}\})/gi, '$1$2');
s = s.replace(/(\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ss]peciesbox|[Ff]ootball[_ ]*box)(?:\{\{(?:\{\{(?:\{\{[^{}]*\}\}|[^{}])*\}\}|[^{}])*\}\}|[^{}])*[\r\n])[\t\r\n ]*\|[\t ]*(\}\})/gi, '$1$2');
// Space before end of line
while(s.search(/([^=])[\t ]+[\r\n]/g) >= 0) {
s = s.replace(/([^=])[\t ]+([\r\n])/g, '$1$2');
}
// Unroll infobox
if(s.search(/\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ss]peciesbox|[Ff]ootball[_ ]*box)/g) >=0 ) {
s = s.replace(/([^\t \r\n])([\t ]*\|[\t ]*[^=\|\[\]\{\]\t ][^=\|\[\]\{\]]*=)/g, '$1\n$2');
s = s.replace(/(=)([\t ]*\|[\t ]*[^=\|\[\]\{\]\t ][^=\|\[\]\{\]]*=)/g, '$1\n$2');
s = s.replace(/([^\t \r\n])[\t \r\n]*(\}\})/g, '$1\n$2'); // put trailing braces on a newline
}
// Add some markers
s = s.replace(/(\|[ ]*(?:[a-z_ ]+)[\t ]*=[^\r\n]*(?:[\r\n][\t ]*♦§[0-9][0-9]*§♦[\t ]*|)*)[\r\n]([\t ]*\|[\t ]*(?:pattern|left|right|body|shorts|socks))/g, '$1<!-- UNGAP MARKER -->\n\n$2');
s = s.replace(/(\|[ ]*(?:league|cup[0-9]+)(?:[ ]*result|)[\t ]*=[^\r\n]*(?:[\r\n][\t ]*♦§[0-9]+§♦[\t ]*|))[\r\n]([\t ]*\|[ ]*(?:[a-z]+ attendance|[a-z]+ topscorer|league scorer))/g, '$1<!-- UNGAP MARKER -->\n\n$2');
s = s.replace(/[\r\n]([\t ]*\|[ ]*prevseason[ ]*=)/g, '<!-- UNGAP MARKER -->\n\n$1');
s = s.replace(/[\t ]*[\r\n][\t ]*([\r\n][\t ]*\|[\t ]*[A-Za-z0-9_\-\t ]*=)/g, '\n<!--\n GAP MARKER\n -->$1');
s = s.replace(/[\r\n][\t ]*[\r\n]/g, '\n<!-- GAP MARKER -->\n');
// Labels that should not be indented
for(var i=0; i < long_labels.length; i++) {
var re = new RegExp('(\\|[\\t ]*)(' + long_labels[i] + ')[\\t ]*=[\\t ]*', 'g');
s = s.replace(re, '$1_FIX_ = <!-- _THIS_LONG_LABEL_ $2 -->');
}
var longRegex = new RegExp('(\\|[\\t ]*)([\\w\/]{' + MAX_PARAM_LENGTH + ',})[\\t ]*=[\\t ]*', 'g');
s = s.replace(longRegex, '$1_FIX_ = <!-- _THIS_LONG_LABEL_ $2 -->');
// uniform pre-pipe indentation
var c0 = s.split(/[\r\n]\|/g).length;
var c1 = s.split(/[\r\n][\t ]\|/g).length;
var c2 = s.split(/[\r\n][\t ][\t ][\t ]*\|/g).length;
if (c0 >= c1 && c0 >= c2) {
s = s.replace(/([\r\n])[\s]*(\|)/g, '$1$2');
} else if (c1 >= c0 && c1 >= c2 ) {
s = s.replace(/([\r\n])[\s]*(\|)/g, '$1 $2');
} else {
s = s.replace(/([\r\n])[\s]*(\|)/g, '$1 $2');
}
// uniform post-pipe indentation
c0 = s.split(/[\r\n][\t ]*\|[^=\|\[\]\{\]\t ]/g).length;
c1 = s.split(/[\r\n][\t ]*\|[\t ][\t ]*[^=\|\[\]\{\]\t ]/g).length;
if (c1 >= c0) {
s = s.replace(/([\r\n][\t ]*\|)[\t ]*([^=\|\[\]\{\]\t ])/g, '$1 $2');
} else {
s = s.replace(/([\r\n][\t ]*\|)[\t ]*([^=\|\[\]\{\]\t ])/g, '$1$2');
}
// flip space and =
s = s.replace(/(\|[^=\|\[\]\{\]\t ][\t ]*)(=)([\t ][\t ][\t ]*)/g, '$1$3$2');
var two_or_more_space_before_equal_count = s.split(/[^=\|\[\]\{\}][\s][\s][\s]*=/g).length - 1;
if (two_or_more_space_before_equal_count > 1) {
// Unalign
s = s.replace(/[\s]*\|[\s]*[\r\n]([\s]*[^=\|\[\]\{\]]*?=)[\t ]*/g, '\n|$1 ');
s = s.replace(/(\|[\s ]*[^=\|\[\]\{\]]*?)[\s]*=[\t ]*/g, '$1 = ');
s = s.replace(/[\r\n]([\s]*[^\s\|])/g, '<!-- ♦§NEWLINE§♦ -->$1');
s = s.replace(/<!--[\s]*<!-- ♦§NEWLINE§♦ -->[\s]*GAP MARKER[\s]*<!-- ♦§NEWLINE§♦ -->[\s]*-->/g, '<!--\n GAP MARKER\n -->');
// Realign
for(var i=40; i>1; i--) {
var r1 = new RegExp('([\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{'+(i)+'}=[^\\r\\n]*[\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{0,'+(i-1)+'})(=)','g');
while( s.search(r1) > -1) {
s = s.replace(r1, '$1 $2');
}
var r2 = new RegExp('([\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{0,'+(i-1)+'})(=[^\\r\\n]*[\\r\\n][\\s]*\\|[^=\\|\\[\\]\\{\\}]{'+(i)+'}=)','g');
while( s.search(r2) > -1) {
s = s.replace(r2, '$1 $2');
}
}
} else if (two_or_more_space_before_equal_count > 0) {
s = s.replace(/([^=\|\[\]\{\}][\s])[\s][\s]*(=)/g, '$1$2');
}
s = s.replace(/<!-- ♦§NEWLINE§♦ -->/g, '\n');
s = s.replace(/<!-- FIX EQ MARKER -->/g, '=');
s = s.replace(/<!-- SPACE MARKER -->/g, ' ');
s = s.replace(/<!--[\s]*GAP MARKER[\s]*-->/g, '');
s = s.replace(/<!--[\s]*UNGAP MARKER[\s]*-->[\t ]*[\r\n][\t ]*[\r\n]*([\s]*)/g, '\n$1');
s = s.replace(/_FIX_[\t ]*=[\t ]*<!--[\t ]* _THIS_LONG_LABEL_ [\t ]*([^<>]*?)[\t ]*-->[\t ]*/g, '$1 = ');
s = s.replace(/([^\|\{\t ])[\t ]*(\|)[\t ]*([\r\n])([^\*:;\{\|])/g, '$1$3$2$4');
s = s.replace(/(\{\{cite[^{}\r\n]*)[\t ][\t ]+([^{}\r\n]*\}\})/g, '$1 $2');
return s;
}
// -------------------------------------------------------------------------------- //
function wpUnsmall(s)
{
var strlist = s.split(/(\{\{[\t \r\n]*(?:[Ii]nfobox|[Ff]ootball[_ ]*box)(?:[^{}]|\{\{(?:(?:[^{}]|\{\{(?:[^{}]|\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\})*\}\})*|\{\{[^{}]*\}\})*\}\})*\}\})/);
for (i = 0; i < strlist.length; i++) {
s = strlist[i];
if(s.search(/\{\{[_\t\r\n ]*(?:[Ii]nfobox|[Ff]ootball[_ ]*box)/g) >=0 ) {
var stmp = '';
while( stmp != s ) {
stmp = s;
s = s.replace(/(\|[ ]*name[ ]*=[^\[\]\|\{\}]*sm)(all)/gi, '$1<!--MARKER DO NOT FIX MARKER-->$2');
}
s = s.replace(/<[\t ]*\/?[\t ]*small[^<>]*>/gi, '');
s = s.replace(/\{\{small(?:er|)[\t ]*\|[\t ]*1[\t ]*=[\t ]*((?:[^{}]|\{\{(?:(?:[^{}]|\{\{(?:[^{}]|\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\})*\}\})*|\{\{[^{}]*\}\})*\}\})*?)[\t ]*\}\}/gi, '$1');
s = s.replace(/\{\{small(?:er|)[\t ]*\|((?:[^{}]|\{\{(?:(?:[^{}]|\{\{(?:[^{}]|\{\{[^{}]*\}\})*\}\})*|\{\{[^{}]*\}\})*\}\})*)\}\}/gi, '$1');
s = s.replace(/<!--[ ]*MARKER DO NOT FIX MARKER[ ]*-->/g, '');
strlist[i] = s;
}
}
return strlist.join('');
}
// -------------------------------------------------------------------------------- //
function startIndent(mytxt)
{
// Regular expression which matchs a template arg
var argexp = new RegExp("(\\|[\\s]*[^=\\|\\[\\]\\{\\}]*=[\\s]*)", "gm");
// Internal for and while loop variables
var i=0; var j=0; var loopcount=0;
// Array used to hold the list of unnested templates
var tlist = [];
// Mark dollar signs which are problematic for regexp
mytxt = mytxt.replace(/\$/g, '♦§DOLLAR§♦');
// Remove comments
loopcount = 0;
while( (mytxt.search(/<!--.*?-->/g) >= 0) && (loopcount < 20) ) {
// Split into chunks, isolating the comments
var strlist = mytxt.split(/(<!--.*?-->)/);
// Loop through the chunks, removing the comments templates
for (i = 0; i < strlist.length; i++) {
if( strlist[i].search(/^<!--.*?-->$/) >= 0 ) {
tlist.push(strlist[i]);
strlist[i] = '♦§' + (tlist.length - 1) + '§♦';
}
}
// Join the chunks back together for the next iteration
mytxt = strlist.join('');
loopcount++;
}
var istart = tlist.length;
// Now start unnesting the templates
loopcount = 0;
while( (mytxt.search(/(?:\{\{|\}\})/g) >= 0) && (loopcount < 20) ) {
// Split into chunks, isolating the unnested templates
var strlist = mytxt.split(/(\{\{[^\{\}]*\}\})/);
// Loop through the chunks, removing the unnested templates
for (i = 0; i < strlist.length; i++) {
if( strlist[i].search(/^\{\{[^\{\}]*\}\}$/) >= 0 ) {
tlist.push(strlist[i]);
strlist[i] = '♦§' + (tlist.length - 1) + '§♦';
}
}
// Join the chunks back together for the next iteration
mytxt = strlist.join('');
loopcount++;
}
// Now start indenting the list of unnested templates
for(i=istart; i < tlist.length; ++i) {
tlist[i] = wpIndent(tlist[i]);
}
// Reassemble the article
while(mytxt.search(/♦§[0-9][0-9]*§♦/g) >= 0) {
var n = mytxt.match(/♦§[0-9][0-9]*§♦/)[0].replace(/♦§([0-9]*)§♦/, '$1');
mytxt = mytxt.replace(new RegExp('♦§' + n + '§♦', 'g'), tlist[Number(n)]);
}
mytxt = mytxt.replace(/[\t ]*[\r\n]*[\t ]*[\r\n][\t ]*(\{\{)[\t ]*((?:[Ii]nfobox|[Ss]peciesbox))/g, '\n$1$2');
mytxt = mytxt.replace(/(\{\{[^{}=\|\r\n]*)([\r\n])(\|)[\t ]*(\{\{)/g, '$1$3$2$4');
// Unmark dollar signs which are problematic for regexp
mytxt = mytxt.replace(/♦§DOLLAR§♦/g, '\$');
return mytxt;
}
function indentInfobox(mytxt){
mw.notify('Indenting Infobox!', {type: 'info'})
const regex = /\|\s*((?:header|label|data|class|rowclass|below)\d*[a-d]?)\s*=/g
var full_matches = [...mytxt.matchAll(regex)];
var values = full_matches.map(match => match[1]);
var longest = values.reduce((a, b) => (a.length >= b.length ? a : b));
for (const val of values) {
mytxt = mytxt.replace(new RegExp(`(\\s*)\\|\\s*${RegExp.escape(val)}\\s*=\\s*`), "$1| " + val.padEnd(longest.length+1) + '= ')
}
return mytxt;
}
jQuery(document).ready(function($) {
var myContent = $('#wpTextbox1').textSelection('getContents');
// var myContent = document.getElementsByName('wpTextbox1')[0];
// -------------------------------------------------------------------------------- //
var mysummary = "Cleaning up syntax using [[:en:User:Zackmann08/scripts/indent|indent.js]]";
// var mysummary = "";
if(typeof indenteditsummary == 'string') {mysummary = indenteditsummary;}
var linktext = "Indent";
// -------------------------------------------------------------------------------- //
// Overid default action of marking minor edit when clicking accesskey + I
$("#wpMinoredit").removeAttr("accesskey");
$(document).ready(function() {
if(mw.config.get('wgNamespaceNumber') != -1 && myContent && (mw.config.get('wgPageName') != 'User:Zackmann08/scripts/JWB.js/loader')) {
$(document).keydown(function(event) {
// Check if Control key is pressed (event.ctrlKey)
// Check if Alt key is pressed (event.altKey)
// Check if the 'I' key is pressed (event.which or event.keyCode for 'I' is 73)
if (event.ctrlKey && event.altKey && event.code === 'KeyI') {
// Prevent the default browser action for this key combination (e.g., opening developer tools)
console.log('i shortcut triggered')
event.preventDefault();
wpIndentTemplates(0);
}
});
mw.loader.using(['mediawiki.util']).done( function() {
var portletlink = mw.util.addPortletLink('p-tb', '#', linktext, 't-indent', 'Indent text');
$(portletlink).click(function(e) {
e.preventDefault();
wpIndentTemplates(0);
});
});
(async () => {
await waitForElement("wpMinoredit");
document.getElementById("wpMinoredit").removeAttribute("accesskey");
})();
// Add button to bottom toolbar after the "Show changes" button
mw.loader.using( [ 'oojs-ui-core' ] ).then( function () {
if ( document.getElementById( 'wpDiff' ) ) {
var diff = document.getElementById( 'wpDiffWidget' );
try {
var indentButton = new OO.ui.ButtonWidget();
indentButton.setElementId( 'wpIndent' ).setIcon( 'indent' ).setLabel( 'Indent' );
indentButton.on( 'click', function () {
wpIndentTemplates(0);
});
indentButton.$element.insertBefore( $(diff.nextSibling) );
} catch (err) {
mw.notify('Failed to insert ButtonWidget: ' + err.message, {type: 'warn'});
return;
}
}
});
}
});
// -------------------------------------------------------------------------------- //
function wpIndentTemplates(debugflag)
{
console.log('wpIndentTemplates RAN')
// Copy the contents of the text window so we can modify it without problems
const original = $('#wpTextbox1').textSelection('getContents');
var mytxt = original
if ((mw.config.get('wgCanonicalNamespace') == 'Template' && !mw.config.get('wgPageName').match(/(\/doc|\/testcase)/)) || mw.config.get('wgPageName') == 'User:Zackmann08/indent') {
mytxt = indentInfobox(mytxt);
} else {
mytxt = startIndent(mytxt);
}
// Remove small tags (if opt-in)
if(typeof removesmalltags == 'string' && removesmalltags == 'yes') {
var oldtxt = mytxt;
mytxt = wpUnsmall(mytxt);
if (oldtxt != mytxt) {
mysummary = mysmallsummary;
}
}
if (mytxt != original) {
mw.notify('Indent complete!', {type: 'success'});
// myContent.value = mytxt;
$('#wpTextbox1').textSelection('setContents', mytxt);
var editsummary = document.getElementsByName('wpSummary')[0];
if(typeof editsummary == 'object') {
if (editsummary.value.indexOf(mysummary) == -1) {
if (editsummary.value.match(/[^\*\/\s][^\/\s]?\s*$/)) {
editsummary.value += '; ' + mysummary;
} else {
editsummary.value += mysummary;
}
}
}
} else {
mw.notify('Nothing to indent...', {type: 'error'});
}
}
mw.hook( 'wikiEditor.toolbarReady' ).add( function ( $textarea ) {
$textarea.wikiEditor( 'addToToolbar', {
section: 'main', // Options: 'main', 'advanced'
group: 'insert', // Options: 'format', 'insert', etc.
tools: {
'indent-button': {
type: 'button',
label: 'Indent text', // Button text
icon: '//upload.wikimedia.org/wikipedia/commons/a/a3/OOjs_UI_icon_indent-ltr.svg', // Icon URL
action: {
type: 'callback',
execute: function ( context ) {
wpIndentTemplates(0);
}
}
}
}
} );
} );
// -------------------------------------------------------------------------------- //
});
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.