1- // Making this more complex than needed for this program. There are some other things I can use this for and I want to start developing it.
2- /** This class acts static. You pass in the wikicode variable to each method, and each method outputs the modified wikicode variable. */
1+ /**
2+ * Utilities that help user scripts that manipulate wikicode properly follow English Wikipedia's MOS:ORDER.
3+ */
34export class MOSOrderPositionFinder {
5+
6+ /**
7+ * Determines whether the given wikitext has the specified MOS:ORDER section
8+ *
9+ * @param {string } wikicode
10+ * @param {string } section One of: top, shortDescription, displayTitle, hatnotes, featured, deletionAndProtection, maintenanceTags, engvar, infoboxes, languageScriptNeeded, sidebars, lead, tableOfContents, body, worksOrPublications, seeAlso, notesAndReferences, furtherReading, externalLinks, successionAndGeographyBoxes, navboxes, portalBar, taxonBar, authorityControl, geographicalCoordinates, defaultSort, categories, improveCategories, stubTemplates, bottom
11+ * @return {boolean } whether the section is present
12+ */
13+ hasSection ( wikicode , section ) {
14+ this . wikitext = wikicode ;
15+ this . _calculate ( ) ;
16+ return this . _getSectionStartPosition ( section ) !== - 1 ;
17+ }
18+
19+ /**
20+ * Returns the numerical position of an MOS:ORDER section in wikitext
21+ *
22+ * @param {string } wikicode
23+ * @param {string } section One of: top, shortDescription, displayTitle, hatnotes, featured, deletionAndProtection, maintenanceTags, engvar, infoboxes, languageScriptNeeded, sidebars, lead, tableOfContents, body, worksOrPublications, seeAlso, notesAndReferences, furtherReading, externalLinks, successionAndGeographyBoxes, navboxes, portalBar, taxonBar, authorityControl, geographicalCoordinates, defaultSort, categories, improveCategories, stubTemplates, bottom
24+ * @return {number } sectionPosition: -1 if no section, integer if section. Counting starts at 0.
25+ */
26+ getSectionPosition ( wikicode , section ) {
27+ this . wikitext = wikicode ;
28+ this . _calculate ( ) ;
29+ let position = this . _getSectionStartPosition ( section ) ;
30+ if ( position === - 1 ) {
31+ position = this . _getPositionOfClosestSection ( section ) ;
32+ }
33+ return position ;
34+ }
35+
36+ /**
37+ * Insert a string at the specified section in the wikitext. If section is absent, will guess where the section should go. Do not add whitespace, it will be computed for you.
38+ *
39+ * @param {string } wikicode
40+ * @param {string } needle The string to insert
41+ * @param {string } section One of: top, shortDescription, displayTitle, hatnotes, featured, deletionAndProtection, maintenanceTags, engvar, infoboxes, languageScriptNeeded, sidebars, lead, tableOfContents, body, worksOrPublications, seeAlso, notesAndReferences, furtherReading, externalLinks, successionAndGeographyBoxes, navboxes, portalBar, taxonBar, authorityControl, geographicalCoordinates, defaultSort, categories, improveCategories, stubTemplates, bottom
42+ * @return {number } sectionPosition: -1 if no section, integer if section. Counting starts at 0.
43+ */
44+ insertAtSection ( wikicode , needle , section ) {
45+ this . wikitext = wikicode ;
46+
47+ // fix more than two enters in a row
48+ // this.wikitext = this.wikitext.replace(/\n{3,}/g, '\n\n');
49+
50+ this . _calculate ( ) ;
51+
52+ let position = this . _getSectionStartPosition ( section ) ;
53+ if ( typeof position === 'undefined' ) {
54+ throw new Error ( 'MOSOrderPositionFinder: invalid section supplied to function insertAtSection()' ) ;
55+ }
56+ let hadToCreateNewSection = false ;
57+ if ( position === - 1 ) {
58+ position = this . _getPositionOfClosestSection ( section ) ;
59+ hadToCreateNewSection = true ;
60+ }
61+
62+ let topHalf = this . wikitext . slice ( 0 , position ) ;
63+ let bottomHalf = this . wikitext . slice ( position ) ;
64+
65+ // TODO: these are band aid fixes, they need a rewrite. should probably add the ideal # of blank lines beneath each section to the list of sections, and then do a foreach loop through that
66+ // if too much whitespace, reduce amount of whitespace
67+ topHalf = topHalf . replace ( / \n { 3 , } $ / , '\n\n' ) ;
68+ bottomHalf = bottomHalf . replace ( / ^ \n { 3 , } / , '\n\n' ) ;
69+
70+ if ( topHalf . endsWith ( '\n\n' ) ) {
71+ // intentionally left blank
72+ } else if ( topHalf . endsWith ( '\n' ) ) {
73+ topHalf += '\n' ;
74+ } else {
75+ topHalf += '\n\n' ;
76+ }
77+
78+ if ( ! bottomHalf . startsWith ( '\n' ) ) {
79+ bottomHalf = '\n' + bottomHalf ;
80+ }
81+
82+ if ( hadToCreateNewSection && ! bottomHalf . startsWith ( '\n\n' ) ) {
83+ bottomHalf = '\n' + bottomHalf ;
84+ }
85+
86+ this . wikitext = topHalf + needle + bottomHalf ;
87+
88+ if ( section === 'shortDescription' ) {
89+ // if template beneath the insertion point, don't put a blank line between SD and other template
90+ this . wikitext = this . wikitext . replace ( / ( \{ \{ (?: S h o r t d e s c r i p t i o n | S h o r t d e s c | S h o r t d e s c r i p t i o n | S h o r t d e s c ) \| [ ^ } ] + \} \} \n ) \n ( \{ \{ ) / is, '$1$2' ) ;
91+ }
92+
93+ // this.wikitext = this.wikitext.trim();
94+ return this . wikitext ;
95+ }
96+
97+ /**
98+ * Useful for testing. Returns all section positions.
99+ */
100+ getAllSectionPositions ( wikicode ) {
101+ this . wikitext = wikicode ;
102+ this . _calculate ( ) ;
103+ return this . sectionStartPositions ;
104+ }
105+
106+ /**
107+ * Useful for testing. Returns all section positions that exist (that aren't -1).
108+ */
109+ getAllExistingSectionPositions ( wikicode ) {
110+ this . wikitext = wikicode ;
111+ this . _calculate ( ) ;
112+ const sections = { } ;
113+ for ( const key in this . sectionStartPositions ) {
114+ if ( this . sectionStartPositions [ key ] !== - 1 ) {
115+ sections [ key ] = this . sectionStartPositions [ key ] ;
116+ }
117+ }
118+ return sections ;
119+ }
120+
4121 _calculate ( ) {
5122 this . sectionOrder = [
6123 'top' ,
@@ -634,23 +751,6 @@ export class MOSOrderPositionFinder {
634751 return matches ? matches . index : - 1 ;
635752 }
636753
637- hasSection ( wikicode , section ) {
638- this . wikitext = wikicode ;
639- this . _calculate ( ) ;
640- return this . _getSectionStartPosition ( section ) !== - 1 ;
641- }
642-
643- /** @return {number } sectionPosition: -1 if no section, integer if section */
644- getSectionPosition ( wikicode , section ) {
645- this . wikitext = wikicode ;
646- this . _calculate ( ) ;
647- let position = this . _getSectionStartPosition ( section ) ;
648- if ( position === - 1 ) {
649- position = this . _getPositionOfClosestSection ( section ) ;
650- }
651- return position ;
652- }
653-
654754 _getSectionStartPosition ( section ) {
655755 const validSection = section in this . sectionStartPositions ;
656756 if ( ! validSection ) {
@@ -659,80 +759,6 @@ export class MOSOrderPositionFinder {
659759 return this . sectionStartPositions [ section ] ;
660760 }
661761
662- /** Useful for testing. Returns all section positions. */
663- getAllSectionPositions ( wikicode ) {
664- this . wikitext = wikicode ;
665- this . _calculate ( ) ;
666- return this . sectionStartPositions ;
667- }
668-
669- /** Useful for testing. Returns all section positions that exist (that aren't -1). */
670- getAllExistingSectionPositions ( wikicode ) {
671- this . wikitext = wikicode ;
672- this . _calculate ( ) ;
673- const sections = { } ;
674- for ( const key in this . sectionStartPositions ) {
675- if ( this . sectionStartPositions [ key ] !== - 1 ) {
676- sections [ key ] = this . sectionStartPositions [ key ] ;
677- }
678- }
679- return sections ;
680- }
681-
682- /** If section is absent, we will guess where the section should go. Do not add whitespace, we will figure it out for you. */
683- insertAtSection ( wikicode , needle , section ) {
684- this . wikitext = wikicode ;
685-
686- // fix more than two enters in a row
687- // this.wikitext = this.wikitext.replace(/\n{3,}/g, '\n\n');
688-
689- this . _calculate ( ) ;
690-
691- let position = this . _getSectionStartPosition ( section ) ;
692- if ( typeof position === 'undefined' ) {
693- throw new Error ( 'MOSOrderPositionFinder: invalid section supplied to function insertAtSection()' ) ;
694- }
695- let hadToCreateNewSection = false ;
696- if ( position === - 1 ) {
697- position = this . _getPositionOfClosestSection ( section ) ;
698- hadToCreateNewSection = true ;
699- }
700-
701- let topHalf = this . wikitext . slice ( 0 , position ) ;
702- let bottomHalf = this . wikitext . slice ( position ) ;
703-
704- // TODO: these are band aid fixes, they need a rewrite. should probably add the ideal # of blank lines beneath each section to the list of sections, and then do a foreach loop through that
705- // if too much whitespace, reduce amount of whitespace
706- topHalf = topHalf . replace ( / \n { 3 , } $ / , '\n\n' ) ;
707- bottomHalf = bottomHalf . replace ( / ^ \n { 3 , } / , '\n\n' ) ;
708-
709- if ( topHalf . endsWith ( '\n\n' ) ) {
710- // intentionally left blank
711- } else if ( topHalf . endsWith ( '\n' ) ) {
712- topHalf += '\n' ;
713- } else {
714- topHalf += '\n\n' ;
715- }
716-
717- if ( ! bottomHalf . startsWith ( '\n' ) ) {
718- bottomHalf = '\n' + bottomHalf ;
719- }
720-
721- if ( hadToCreateNewSection && ! bottomHalf . startsWith ( '\n\n' ) ) {
722- bottomHalf = '\n' + bottomHalf ;
723- }
724-
725- this . wikitext = topHalf + needle + bottomHalf ;
726-
727- if ( section === 'shortDescription' ) {
728- // if template beneath the insertion point, don't put a blank line between SD and other template
729- this . wikitext = this . wikitext . replace ( / ( \{ \{ (?: S h o r t d e s c r i p t i o n | S h o r t d e s c | S h o r t d e s c r i p t i o n | S h o r t d e s c ) \| [ ^ } ] + \} \} \n ) \n ( \{ \{ ) / is, '$1$2' ) ;
730- }
731-
732- // this.wikitext = this.wikitext.trim();
733- return this . wikitext ;
734- }
735-
736762 // https://stackoverflow.com/a/13109786/3480193
737763 _arraySearch ( arr , val ) {
738764 for ( let i = 0 ; i < arr . length ; i ++ ) {
0 commit comments