[Tool] Change Case (Uppercase / Lowercase)  SOLVED

Forum for the PDF-XChange Editor - Free and Licensed Versions

Moderators: PDF-XChange Support, Daniel - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Paul - PDF-XChange, Vasyl - PDF-XChange, Ivan - Tracker Software, Stefan - PDF-XChange

User avatar
⚜ Kenny Lemens, P.E. ᵂᴵ
User
Posts: 38
Joined: Thu Jan 23, 2025 4:09 pm

[Tool] Change Case (Uppercase / Lowercase)  SOLVED

Post by ⚜ Kenny Lemens, P.E. ᵂᴵ »

Greetings,

A bit limited, but provides some ability to cycle through Upper, Lower, and Sentence Case. Keypress: [Shift]+[F3] can be reassigned to this function. A solid "Thank You" to @Matthew;

Code: Select all

// Title: Word Processing Tools
// Version: v1.11 [2025-01-29]
// Author: ⚜ Kenny Lemens, P.E. ᵂᴵ; Cf: mathew 
// Site: https://forum.pdf-xchange.com/viewtopic.php?t=45264
// Desc: Apply text modifications (e.g., LowerCase; UpperCase; etc.) to slected text objects.
// Save this as Javascript to folder "%Appdata%\Tracker Software\PDFXEditor\3.0\Javascripts'
// Image Support: encode 20x20 Pixel PNG Images (ARGB Structure -> 8*digit HEX)
// v1.00 [RELEASE] Date: 2025-01-28
// v1.10 modified by mathew [2025-01-29]: to handle rich text word boundaries and add Title Case, added compression to icon stream, removed trusted protocols
// v1.11 modified by ⚜ Kenny Lemens, P.E. ᵂᴵ [2025-01-29]: To apply the same Case style across all selected annotations

var iconSet = {count:0, width:20, height:20, read:function(nBytes=this.data.length/2){return this.data.slice(this.count,this.count+=2*nBytes);}, data:(a=>{let[b,c]=a.split(":");c=c?.match(/.{8}/g);let d=(a,b)=>a.replace(/./g,a=>parseInt(a,10+b)-b);return b.replace(/([g-p]+)([0-9a-f]+|[q-z]+)/gi,(a,b,e)=>(/[q-z]/.test(e)?c[d(e,26)]:e).repeat(d(b,16)));})("iiqhnthkqhthnqh087F0000hqhthqh0C7F0000nqhsh010000FFi280C39FFhsiqh387F0000huhqhthqhuh4C7F0000mqhsh6D0A38FFiAE0C39FFh380B38FFjqhuhvhthvhyhwlqhsh060F3FFFhzirh790B38FFjqhvhuhthuhrqmqhsh1A0D3BFFhrhF90C38FFhrhB80B39FFkqhuhthyhwlqish580C38FFhrhD50C38FFhrhF40B39FFh0E0F3FFFjqhvhthrqmqish970C38FFhrh7A0B38FFhF80C39FFhrh430C38FFkqhA77F0000hwmqhsh090A3DFFhD20C39FFhrhrrhzhrh820C38FFhiqhsh230A3BFFhrhF30C38FFhsh7B0A38FFhrhC00C39FFh030A35FFiqh500C39FFh8E0C39FFhxh890B39FFh3F0C38FFkqhsh610A38FFhrhAD0C38FFhsh280938FFhrhF60C39FFh150A35FFhqh530C3AFFirhD60B39FFirh480A38FFjqhsh9F0B38FFhrhDC0C38FFh9F0C39FFhA90B38FFirh4C0A37FFhqh400B37FFh5E0A38FFiqh6C0B38FFhrh8D0C38FFjqh0C0F36FFhD70C39FFhrkED0C38FFhrh8B0B38FFiqh050033FFh620D39FFh720B3AFFhAD0B39FFhrhA70C38FFjqh2B0D36FFhrhF20B39FFjB60C38FFhB90B37FFhrhC70C39FFhqh3D0C3AFFhEF0B38FFirhDA0B39FFhrhA90C39FFiqhsh6A0A37FFhrhA80B39FFj1A0C38FFh2F0B36FFhrhF70C39FFhqhAC0B39FFhrh7B0A3AFFhqh510C38FFhrhAB0B38FFiqhshA70A38FFhrh660A39FFjsh090A35FFhD70B39FFhrh410B37FFhA00C39FFhrhC00B39FFh420B39FFhC50B38FFhrhxjqh7B0B38FFhrshrrksh780B39FFhrsh440B39FFh2B0B3BFFhD10C39FFirh980B39FFhrhxjqhsh0E0C3CFFkqish150C3CFFhsiqh290C37FFh0B172EFFlq:00FFFFFFFF0C39FF00000000FF7F0000CF7F0000507F0000047F0000AC0B38FFDB7F0000CC0B39FF607F00002C0A39FFA70C39FF")};
   

app.addToolButton({
   cName: "RICE.changeCase",
   cLabel: "Change Case",
   oIcon: iconSet,
   cTooltext: "Cycle through UPPER CASE, lower case, Sentence case, Title Case.",
   cEnable: 'event.rc = this.selectedAnnots?.length',
   cExec: "onClick_changeCase(this)" }
);


function onClick_changeCase(doc) {

   //Consider Selected Annotations
   var lstAnnotations = doc.selectedAnnots;
   var caseTier = -1

   for(let j=0; j<lstAnnotations.length; j++) {
      let ann = lstAnnotations[j];
      let aryTreatedStr = treatString( ann.contents, caseTier);
      caseTier = aryTreatedStr[1];

      let aProps = ann.richContents;
      if (aProps.length>0) {
         // working with rich contents; get a plain text version
         let newString = aryTreatedStr[0];
         // now go through the richContents and keep track of character position
         let charPos = 0;
         for (let i=0; i<aProps.length; i++) {
            aProps[i].text = newString.slice( charPos, charPos + aProps[i].text.length );
            charPos += aProps[i].text.length;
         }
         ann.richContents = aProps;
      } else {
         ann.contents = aryTreatedStr[0];
      }
   }


   function treatString( _string, _level = -1){
      var returnVal = [_string, _level];
      const wordCap = (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();

      var strTitleCase =  _string.replace(/(\S+)(\s*)/g, (m,p1,p2) => wordCap(p1) + p2); 
      var strSentence = wordCap( _string );

      if((_string == strSentence && _level == -1 ) || (_level == 0) ){ 
         returnVal[0] = _string.toLowerCase();
         returnVal[1] = 0;
      }else if((_string == _string.toLowerCase() && _level == -1 ) || (_level == 1)){
         returnVal[0] = _string.toUpperCase();
         returnVal[1] = 1;
      }else if((_string == _string.toUpperCase() && _level == -1 ) || (_level == 2)){
         returnVal[0] = strTitleCase;
         returnVal[1] = 2;
      }else{
         returnVal[0] = strSentence;
         returnVal[1] = 3;
      }

      return returnVal;
   }
}
Current 🢃Download:
ricePlugin_wordProcessor_v1.11.zip


Archive:
  • v1.00 🢃Download:
    ricePlugin_wordProcessor_v1.00.zip

pdf-xchange_ChangeCase.png
Version Notes:
  • v1.11
    • Title Case / Sentence Case applied correctly to Rich Text - @Matthew
    • I added in a Title Case into the rotation - @Matthew
    • Compressed icon stream - @Matthew
    • Removed 'trusted function'; redundant - @Matthew
    • Case style is applied uniformly across all selected text annotations - @KennyLemens

Limitations:
  • Will treat each annotation independently - v1.11
  • Cycles through cases, doesn't apply a Case Type across the Board- v1.11
  • Supports RichText, but "Camel Case/Sentence Case" does not work per sentence, but rather by Formatted Groups...- v1.11
  • Does not work on selected text within an annotation or on the base level, only those selected annotations/text objects.
  • Will not cycle through 'Sentence Case' if first selected annotation contains just (1) word.
Comments:
  • Mathew wrote: Wed Jan 29, 2025 7:54 pm ... I like this tool - I took the liberty of making a new version - plus maybe you could add a post to the above topic with links to your scripts? ...
May this be of Good Help;
⚜ Kenny Lemens, P.E. ᵂᴵ
You do not have the required permissions to view the files attached to this post.
Last edited by ⚜ Kenny Lemens, P.E. ᵂᴵ on Thu Jan 30, 2025 3:38 am, edited 2 times in total.
User Plugins: https://is.gd/A9HMPG || PDF-XChange Icons: https://is.gd/Z4GeG8
[Migration] Revu Bluebeam 17 to PDF-XChange Editor: https://is.gd/8Xs1OF
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11039
Joined: Wed Jan 03, 2018 6:52 pm

Re: [Tool] Change Case (Uppercase / Lowercase)

Post by Daniel - PDF-XChange »

Hello, ⚜ Kenny Lemens, P.E. ᵂᴵ

Thank you very much for this, I am happy to see another JS fluent writer on our forums!

Kind regards,
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Mathew
User
Posts: 578
Joined: Thu Jun 19, 2014 7:30 pm

Re: [Tool] Change Case (Uppercase / Lowercase)

Post by Mathew »

Hey this is great. Love it.

Maybe we can get
MedBooster wrote:@medbooster
to rename the sticky topic "PDF-XCE JavaScript Index" or something similar. Would be great to have one place that linked to the work everyone contributes.

:D
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11039
Joined: Wed Jan 03, 2018 6:52 pm

Re: [Tool] Change Case (Uppercase / Lowercase)

Post by Daniel - PDF-XChange »

Hello, Mathew

I'm not sure if the OP of a thread can directly change the thread name and default reply header, but Ive gone ahead and made the suggested change to that topic. Do feel free to post links to any "new script" topics in there as well.

Kind regards,
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Mathew
User
Posts: 578
Joined: Thu Jun 19, 2014 7:30 pm

Re: [Tool] Change Case (Uppercase / Lowercase)

Post by Mathew »

Daniel - PDF-XChange wrote: Wed Jan 29, 2025 6:43 pm I'm not sure if the OP of a thread can directly change the thread name and default reply header, but Ive gone ahead and made the suggested change to that topic. Do feel free to post links to any "new script" topics in there as well.
:D

@Kenny Lemens:

I like this tool - I took the liberty of making a new version - plus maybe you could add a post to the above topic with links to your scripts?
  1. Dealing with rich text is a bit tricky. I fiddled your script to try to handle rich text by changing the case on a plain text string, then keeping track of the character position as I replace into each span element. Seems to work for me.
  2. I added in a Title Case into the rotation
  3. I added compression to the icon stream text to reduce the amount of text in the script.
  4. I don't think this tool needs to be a trusted function

Code: Select all

// Title: Word Processing Tools
// Version: v1.00
// Author: ⚜ Kenny Lemens, P.E. ᵂᴵ  || Date: 2025-01-28
// Site: https://forum.pdf-xchange.com/viewtopic.php?t=45264
// Desc: Apply text modifications (e.g., LowerCase; UpperCase; etc.) to slected text objects.
// Save this as Javascript to folder "%Appdata%\Tracker Software\PDFXEditor\3.0\Javascripts'
// Image Support: encode 20x20 Pixel PNG Images (ARGB Structure -> 8*digit HEX)

// v1.10 modified by mathew 2025-01-29 to handle rich text word boundaries and add Title Case, added compression to icon stream

var iconSet = {count:0, width:20, height:20, read:function(nBytes=this.data.length/2){return this.data.slice(this.count,this.count+=2*nBytes);}, data:(a=>{let[b,c]=a.split(":");c=c?.match(/.{8}/g);let d=(a,b)=>a.replace(/./g,a=>parseInt(a,10+b)-b);return b.replace(/([g-p]+)([0-9a-f]+|[q-z]+)/gi,(a,b,e)=>(/[q-z]/.test(e)?c[d(e,26)]:e).repeat(d(b,16)));})("iiqhnthkqhthnqh087F0000hqhthqh0C7F0000nqhsh010000FFi280C39FFhsiqh387F0000huhqhthqhuh4C7F0000mqhsh6D0A38FFiAE0C39FFh380B38FFjqhuhvhthvhyhwlqhsh060F3FFFhzirh790B38FFjqhvhuhthuhrqmqhsh1A0D3BFFhrhF90C38FFhrhB80B39FFkqhuhthyhwlqish580C38FFhrhD50C38FFhrhF40B39FFh0E0F3FFFjqhvhthrqmqish970C38FFhrh7A0B38FFhF80C39FFhrh430C38FFkqhA77F0000hwmqhsh090A3DFFhD20C39FFhrhrrhzhrh820C38FFhiqhsh230A3BFFhrhF30C38FFhsh7B0A38FFhrhC00C39FFh030A35FFiqh500C39FFh8E0C39FFhxh890B39FFh3F0C38FFkqhsh610A38FFhrhAD0C38FFhsh280938FFhrhF60C39FFh150A35FFhqh530C3AFFirhD60B39FFirh480A38FFjqhsh9F0B38FFhrhDC0C38FFh9F0C39FFhA90B38FFirh4C0A37FFhqh400B37FFh5E0A38FFiqh6C0B38FFhrh8D0C38FFjqh0C0F36FFhD70C39FFhrkED0C38FFhrh8B0B38FFiqh050033FFh620D39FFh720B3AFFhAD0B39FFhrhA70C38FFjqh2B0D36FFhrhF20B39FFjB60C38FFhB90B37FFhrhC70C39FFhqh3D0C3AFFhEF0B38FFirhDA0B39FFhrhA90C39FFiqhsh6A0A37FFhrhA80B39FFj1A0C38FFh2F0B36FFhrhF70C39FFhqhAC0B39FFhrh7B0A3AFFhqh510C38FFhrhAB0B38FFiqhshA70A38FFhrh660A39FFjsh090A35FFhD70B39FFhrh410B37FFhA00C39FFhrhC00B39FFh420B39FFhC50B38FFhrhxjqh7B0B38FFhrshrrksh780B39FFhrsh440B39FFh2B0B3BFFhD10C39FFirh980B39FFhrhxjqhsh0E0C3CFFkqish150C3CFFhsiqh290C37FFh0B172EFFlq:00FFFFFFFF0C39FF00000000FF7F0000CF7F0000507F0000047F0000AC0B38FFDB7F0000CC0B39FF607F00002C0A39FFA70C39FF")};
   

app.addToolButton({
   cName: "RICE.changeCase",
   cLabel: "Change Case",
   oIcon: iconSet,
   cTooltext: "Cycle through UPPER CASE, lower case, Sentence case, Title Case.",
   cEnable: 'event.rc = this.selectedAnnots?.length',
   cExec: "onClick_changeCase(this)" }
);


function onClick_changeCase(doc) {

   // Get selected annotations on the current page
   var lstAnnotations = doc.selectedAnnots;  //this.getAnnots({nPage: this.pageNum});

   for (let ann of lstAnnotations){
      let aProps = ann.richContents;
      if (aProps.length>0) {
         // working with rich contents
         // get a plain text version
         let newString = treatString( ann.contents );
         // now go through the richContents and keep track of character position
         let charPos = 0;
         //let changed = false;
         for (let i=0; i<aProps.length; i++) {
            aProps[i].text = newString.slice( charPos, charPos + aProps[i].text.length );
            charPos += aProps[i].text.length;
            //aProps[i].text = treatString(aProps[i].text); 
            //changed = true;
         }
         ann.richContents = aProps;
      } else {
         aProps = ann.contents;
         ann.contents = treatString(aProps);
      }
   }

   function treatString( _string){
      var returnVal = "";
      const wordCap = (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();

      var strTitleCase =  _string.replace(/(\S+)(\s*)/g, (m,p1,p2) => wordCap(p1) + p2); 
      //var strCamelCase =  _string.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
      //                    return index === 0 ? word.toLowerCase() : word.toUpperCase(); })//.replace(/\s+/g, ' ');
      var strSentence = wordCap( _string );
      if(_string == _string.toUpperCase() ){ 
         returnVal = _string.toLowerCase();
      }else if(_string == _string.toLowerCase()){
         returnVal = strSentence;
      }else if(_string == strSentence){
         returnVal = strTitleCase;
      }else{
         returnVal = _string.toUpperCase();
      }      
      return returnVal;
   }
}
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11039
Joined: Wed Jan 03, 2018 6:52 pm

[Tool] Change Case (Uppercase / Lowercase)

Post by Daniel - PDF-XChange »

:)
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
MedBooster
User
Posts: 1372
Joined: Mon Nov 15, 2021 8:38 pm

Re: [Tool] Change Case (Uppercase / Lowercase)

Post by MedBooster »

Wow we have another coding-expert here, I edited in a link to this thread in the 1st post
Great work!

I just noticed Mathew's (2nd reply) post in the thread below is a good categorized overview of the scripts and links, which he seems to update frequently

viewtopic.php?t=42190&hilit=mathew

It used to be Mathew's javascripts, but now it is "PDF-XCE JavaScript Index" (tracker support has apparently renamed it, a fitting title, I guess) (you can see it in the "hilit=mathew"-part
My wishlist https://forum.pdf-xchange.com/viewtopic.php?p=187394#p187394
Disable SPACE page navigation, fix kb shortcut for highlighting advanced search tool search field, bookmarks with numbers, toolbar small icon size, AltGr/Ctrl+Alt keyboard issues
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19868
Joined: Mon Jan 12, 2009 8:07 am

[Tool] Change Case (Uppercase / Lowercase)

Post by Stefan - PDF-XChange »

:)