MS Word-style case change (Shift+F3 feature): change the case of selected text from upper to lower to title

Abbas
2013-08-11
2014-11-16
  • Abbas

    Abbas - 2013-08-11

    :::python

    # MS Word has the option of changing the case of selected text by pressing Shift+F3
    # The case changes in the order: UPPER CASE, lower case, Title Case
    # It was something I was missing in Notepad++ so I wrote the following script to add the change case feature
    # Remember to associate this script with Shift+F3 key combination in the Shortcut Mapper
    
    text = editor.getSelText()
    
    if text: # Do this only if some text has been selected
        checkingFuncs = [lambda s: s.isupper(), lambda s: s.islower(),  lambda s: s.istitle(),  lambda s: True]
        alteringFuncs = [lambda s: s.lower(),   lambda s: s.title(),        lambda s: s.upper(),        lambda s: s.upper()]
        numOfFuncs = len(checkingFuncs)
    
        for i in range(0, numOfFuncs): # Iterate through the list of checking functions
            if checkingFuncs[i](text): # Check the existing case of the text
                text = alteringFuncs[i](text) # Based on the result of checking function, change the case in this order: upper->lower, lower->title, title->upper, anything else->upper
                break
    
        start = editor.getSelectionStart() # Record the start and end position of the selection
        end =   editor.getSelectionEnd()
    
        editor.replaceSel(text) # Replace the originally selected text with altered-case text, this will end the selection as well
    
        editor.setSel(start, end) # Select the newly altered text
    
     
    • Abbas

      Abbas - 2014-11-16
      # Edited to include changes suggested by Rufus in the comments
      
      text = editor.getSelText()
      
      if text:
          # tuples of check and alter functions
          functable = [
                      (lambda s: s.isupper(), lambda s: s.lower()),
                      (lambda s: s.islower(), lambda s: s.title()),
                      (lambda s: s.istitle(), lambda s: s.upper()),
                      (lambda s: True,        lambda s: s.upper())
                      ]
      
          for check, alter in functable: # Iterate through the list of checking and altering functions
              if check(text):
                  text = alter(text)
                  break
      
          start = editor.getSelectionStart()
          end = editor.getSelectionEnd()
      
          editor.replaceSel(text)
      
          editor.setSel(start, end)
      
       
      Last edit: Abbas 2014-11-26
  • Rufus V. Smith

    Rufus V. Smith - 2014-09-10

    Nicely done. The only issue I have is the need for indexing into arrays. I think it is prettier Python doing the checks and alters this way:

    functable = [  # tuples of check_function, alter_function
    (lambda s: s.isupper(), lambda s: s.lower()),
    (lambda s: s.islower(), lambda s: s.title()),
    (lambda s: s.istitle(), lambda s: s.upper()),
    (lambda s: True,        lambda s: s.upper())
    ]
    for check,alter in functable:
        if check(text): 
            alter(text)
            break
    

    You've inspired me to create a "invert case" function, because I'm forever typing labels with my caps-lock on!

    P.S. if you already have the first macro in and are a lazy typer like I am, you can just put the following line after your existing function tables:

    functable = zip(checkingFuncs, alteringFuncs)
    

    (I also like having checks and alters in a single list, so I don't have two lists to keep in sync if I decide to change one.)

     
    • Abbas

      Abbas - 2014-11-16

      Excellent suggestion, indexing into the arrays always troubled me subconsciously, and while I too am a lazy typist, the improvement in code was too good to just use the zip function. I have updated my post.

      The only change I made was assign text to the alter functions return value.

      Please continue to share suggestions. Will look forward to your script contributions as well.

      Regards,

      Abbas

       
  • Dan Padric

    Dan Padric - 2017-06-05

    Hello.

    Thank you very much for sharing this code segment. It has been very nice tool to get introduced to a few concpets relating to Python and this Add-on for Notepad++.

    I do hope you do not mind me making some contribution - hoping others will learn as much as I have. See below the small expansion.

    • Dan
    '''
    Title:      MS Word-style case change (Shift+F3 feature): 
                change the case of selected text from upper to lower to title 
    Creator:    Abbas 
    Publish:    https://sourceforge.net/p/npppythonscript/discussion/1199074/thread/b0cc797e/
    
    NOTES:  
     MS Word has the option of changing the case of selected text by pressing Shift+F3 
     The case changes in the order: UPPER CASE, lower case, Title Case
     It was something I was missing in Notepad++ so I wrote the following script to add the change case feature
     Remember to associate this script with Shift+F3 key combination in the Shortcut Mapper
    
    UPDATES:                    _ver_   _description_
     2013-08-11 Abbas           1.0.0   Original release 
     2014-11-16 Abbas           1.1.0   Edited to include changes suggested by Rufus in the comments
     2017-06-05 Dan Padric      1.1.1   Formatting, commentary, add "Sentence case" & error message
    '''
    
    text = editor.getSelText() # Absorb selected text into tag
    
    if text: # PROCESSING TEXT
        # tuples of check and alter functions
        functable = [
                    (lambda s: s.isupper(),             lambda s: s.lower()), # ............ UPPER CASE     -> lower case
                    (lambda s: s.islower(),             lambda s: s[0].upper() 
                                                                    + s[1:].lower()), # .... lower case     -> Sentence case
                    (lambda s: s[0].isupper() 
                                and s[1:].islower(),    lambda s: s.title()), # ............ Sentence case  -> Title Case
                    (lambda s: s.istitle(),             lambda s: s.upper()), # ............ Title Case     -> UPPER CASE
                    (lambda s: True,                    lambda s: s.upper()) # ............. {none}         -> UPPER CASE
                    ]
    
        for check, alter in functable: # Iterate through the list of checking and altering functions
            if check(text): # ........... TEST
                text = alter(text) # .... MODIFY
                break # ................. task complete
    
        start = editor.getSelectionStart()
        end = editor.getSelectionEnd() # ... positioning of current selection
    
        editor.replaceSel(text) # ....... replace text with modified version
    
        editor.setSel(start, end) # ..... reselect text
    
    else: # NO TEXT SELECTED
        action = notepad.messageBox('No selection made', # .. error message
                                    'Text case toggle', 
                                    MESSAGEBOXFLAGS.OK) 
    
     
    Last edit: Dan Padric 2017-06-05
  • David Hansen

    David Hansen - 11 hours ago

    Nice work Dan! I just have one suggestion to make it act more like Word...

    Instead of displaying a messageBox if no selection is made, you could automatically select the current word and apply the modification to that.

        # Select the "word" at current cursor position
        pos   = editor.getCurrentPos() 
        begin = editor.wordStartPosition(pos,True)
        end   = editor.wordEndPosition(pos,True)
        editor.setSel(start, end)
    
        # Transform word case
        text = editor.getSelText()
        text = alter(text)
        editor.replaceSel(text) 
    
     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.





No, thanks