Skip to content

Commit

Permalink
Update for macOS Monterey, Python 3
Browse files Browse the repository at this point in the history
Prefers python3 if available, which is the default on Monterey.
Fallsback to plain python (2) if available. Script should work on both.
Updates icon to work better with dark themes.
  • Loading branch information
gillibrand committed Mar 24, 2022
1 parent 64eb341 commit 3d9eb58
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 38 deletions.
Binary file modified Change Case.alfredworkflow
Binary file not shown.
26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,40 @@ Changes the case of text selected, provided, or on the clipboard to UPPERCASE, l

[Download the workflow](https://github.com/gillibrand/alfred-change-case/blob/master/Change%20Case.alfredworkflow).

![Screenshot](changecase.png)
![Screenshot](changecase.jpg)

## Usage

Change the case of text on the keyboard with the keyword `case`. All six styles are previewed as Alfred results. Select one to copy it to the clipboard and paste into in the current application.

Optionally, any text typed after `case` will be changed instead of the clipboard.

To assign a global hotkey, view Change Case in Alfred's Workflow editor. Double-click Hotkey node and assign your preferred keys.

## Version History

### 3/23/2022

- Updated to work with macOS Montery (switch to Python 3). Should still work on older systems.
- Simplified icons that are more visible on dark themes.
- Fixed CamelCase to work with all words.
- Removed the default global hotkey. Users can still assign their own in Alfred's workflow editor.

### 9/9/2018

- Added CamelCase, kebab-case, and snake_case options
- Added additional keywords "tt" and "transform"
- Updated icons and added additional cases to match original style.
- Added CamelCase, kebab-case, and snake_case to icons.acorn layered file.

### 8/21/2018

- Added CamelCase, kebab-case, and snake_case options.
- Updated icons.
- Added keybinding for text selection transformation.
- Added additional keywords "tt" and "transform" to default workflow options.

### 4/19/2013

- Always sorts the case styles in the same order now: lowercase, uppercase, then title case. (Removed the `uid` from results returned to Alfred as supported in Alfred 2.0.3.)
- Always sorts the case styles in the same order now: lowercase, uppercase, then title case. (Removed the `uid` from results returned to Alfred as supported in Alfred 2.0.3.).

### 4/6/2013

Expand All @@ -31,4 +47,4 @@ Optionally, any text typed after `case` will be changed instead of the clipboard

- Workflow by Jay Gillibrand.
- `titlecase` module by [Stuart Colville](http://muffinresearch.co.uk).
- `CamelCase`, `kebab-case`, and `snake_case` additions added by [Ben Wagner](https://blizzrdof77.com)
- `CamelCase`, `kebab-case`, and `snake_case` additions added by Ben Wagner.
Binary file modified camelcase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added changecase.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed changecase.png
Binary file not shown.
57 changes: 32 additions & 25 deletions changecase.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,79 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import re, sys
from __future__ import print_function
import re
import sys
from xml.sax.saxutils import escape
from titlecase import titlecase

if len(sys.argv) > 1 and len(sys.argv[1].strip()):
text = sys.argv[1]
text = sys.argv[1]
else:
text = sys.stdin.read()
text = sys.stdin.read()

if len(text.strip()) == 0:
sys.exit(0)

always_uppercase = r'''\bXML|HTML|CSS|JSON|FYI|AOL|ATM|BBC|CD|FAQ|GAIM|GNU|GTK|HIRD|HIV
|HURD|IEEE|IOU|IRA|IUPAC|JPEG|LCD|NAACP|NAC|NATO|NCAA|NOAD|OEM|PHP|ROM|SAT|SFMOMA|SQL|USA|VHDL|VHSIC|W3C
|LOL|WTF\b'''
always_uppercase_re = re.compile(always_uppercase, re.I | re.X)


def titlecase_plus(text):
"""The titlecase module assumes words in all UPPERCASE should be ignored.
This works for words like HTML, FYI, ID, etc., but not generally. Just work
around for now by going to .lower first. Then, replace any well known
"always" uppercase"""
text = titlecase(text.lower())
def upcase(m):
return m.group().upper()
return always_uppercase_re.sub(upcase, text)
"""The titlecase module assumes words in all UPPERCASE should be ignored.
This works for words like HTML, FYI, ID, etc., but not generally. Just work
around for now by going to .lower first. Then, replace any well known
"always" uppercase"""
text = titlecase(text.lower())

def upcase(m):
return m.group().upper()
return always_uppercase_re.sub(upcase, text)


variations = {
'lower': escape(text.lower(), {'"': '"', '\n': '
'} ),
'upper': escape(text.upper(), {'"': '"', '\n': '
'} ),
'title': escape(titlecase_plus(text), {'"': '"', '\n': '
'} ),
'camel': escape(titlecase_plus(text), {'"': '"', '\n': '
'} ).replace(' ', ''),
'kebab': escape(text.lower(), {'"': '"', '\n': '
'} ).replace(' ', '-').replace('_', '-'),
'snake': escape(text.lower(), {'"': '"', '\n': '
'} ).replace(' ', '_').replace('-', '_')
'lower': escape(text.lower(), {'"': '"', '\n': '
'}),
'upper': escape(text.upper(), {'"': '"', '\n': '
'}),
'title': escape(titlecase_plus(text), {'"': '"', '\n': '
'}),
'camel': escape(text.title(), {'"': '"', '\n': '
'}).replace(' ', ''),
'kebab': escape(text.lower(), {'"': '"', '\n': '
'}).replace(' ', '-').replace('_', '-'),
'snake': escape(text.lower(), {'"': '"', '\n': '
'}).replace(' ', '_').replace('-', '_')

}

print """<?xml version="1.0"?>
print("""<?xml version="1.0"?>
<items>
<item arg="%(lower)s">
<title>%(lower)s</title>
<subtitle>lowercase</subtitle>
<subtitle>Transform text to `lowercase`</subtitle>
<icon>lowercase.png</icon>
</item>
<item arg="%(upper)s">
<title>%(upper)s</title>
<subtitle>UPPERCASE</subtitle>
<subtitle>Transform text to `UPPERCASE`</subtitle>
<icon>uppercase.png</icon>
</item>
<item arg="%(title)s">
<title>%(title)s</title>
<subtitle>Title Case</subtitle>
<subtitle>Transform text to `Title Case`</subtitle>
<icon>titlecase.png</icon>
</item>
<item arg="%(camel)s">
<title>%(camel)s</title>
<subtitle>CamelCase</subtitle>
<subtitle>Transform text to `CamelCase`</subtitle>
<icon>camelcase.png</icon>
</item>
<item arg="%(kebab)s">
<title>%(kebab)s</title>
<subtitle>kebab-case</subtitle>
<subtitle>Transform text to hyphenated `kebab-case`</subtitle>
<icon>kebabcase.png</icon>
</item>
<item arg="%(snake)s">
<title>%(snake)s</title>
<subtitle>snake_case</subtitle>
<subtitle>Transform text to `snake_case`</subtitle>
<icon>snakecase.png</icon>
</item>
</items>""" % variations
</items>""" % variations)
Binary file modified icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified icons.acorn
Binary file not shown.
84 changes: 76 additions & 8 deletions info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@
<false/>
</dict>
</array>
<key>3EEC7A2D-486C-4756-A271-FAD9448441C8</key>
<array>
<dict>
<key>destinationuid</key>
<string>B6600E5C-BB57-4054-827B-5688E776AEE7</string>
<key>modifiers</key>
<integer>0</integer>
<key>modifiersubtext</key>
<string></string>
<key>vitoclose</key>
<false/>
</dict>
</array>
<key>B6600E5C-BB57-4054-827B-5688E776AEE7</key>
<array>
<dict>
Expand Down Expand Up @@ -51,7 +64,7 @@
<key>createdby</key>
<string>Jay Gillibrand</string>
<key>description</key>
<string>Changes the case of text on the clipboard.</string>
<string>Change text to uppercase, lowercase, and more</string>
<key>disabled</key>
<false/>
<key>name</key>
Expand Down Expand Up @@ -84,7 +97,14 @@
<key>runningsubtext</key>
<string>transforming text case...</string>
<key>script</key>
<string>pbpaste | python changecase.py "{query}"</string>
<string>{
pbpaste | python3 changecase.py "{query}"
} 2&gt; /dev/null
if [[ $? -ne "0" ]] ; then
pbpaste | python changecase.py "{query}"
fi
</string>
<key>scriptargtype</key>
<integer>0</integer>
<key>scriptfile</key>
Expand Down Expand Up @@ -131,7 +151,14 @@
<key>runningsubtext</key>
<string>transforming text case...</string>
<key>script</key>
<string>pbpaste | python changecase.py "{query}"</string>
<string>{
pbpaste | python3 changecase.py "{query}"
} 2&gt; /dev/null
if [[ $? -ne "0" ]] ; then
pbpaste | python changecase.py "{query}"
fi
</string>
<key>scriptargtype</key>
<integer>0</integer>
<key>scriptfile</key>
Expand Down Expand Up @@ -169,6 +196,35 @@
<key>version</key>
<integer>2</integer>
</dict>
<dict>
<key>config</key>
<dict>
<key>action</key>
<integer>0</integer>
<key>argument</key>
<integer>1</integer>
<key>focusedappvariable</key>
<false/>
<key>focusedappvariablename</key>
<string></string>
<key>hotkey</key>
<integer>0</integer>
<key>hotmod</key>
<integer>0</integer>
<key>leftcursor</key>
<false/>
<key>modsmode</key>
<integer>0</integer>
<key>relatedAppsMode</key>
<integer>0</integer>
</dict>
<key>type</key>
<string>alfred.workflow.trigger.hotkey</string>
<key>uid</key>
<string>3EEC7A2D-486C-4756-A271-FAD9448441C8</string>
<key>version</key>
<integer>2</integer>
</dict>
<dict>
<key>config</key>
<dict>
Expand All @@ -195,7 +251,14 @@
<key>runningsubtext</key>
<string>transforming text case...</string>
<key>script</key>
<string>pbpaste | python changecase.py "{query}"</string>
<string>{
pbpaste | python3 changecase.py "{query}"
} 2&gt; /dev/null
if [[ $? -ne "0" ]] ; then
pbpaste | python changecase.py "{query}"
fi
</string>
<key>scriptargtype</key>
<integer>0</integer>
<key>scriptfile</key>
Expand All @@ -218,9 +281,9 @@
</dict>
</array>
<key>readme</key>
<string>Change the case of text on the keyboard with the keyword case. All styles are previewed as Alfred results. Select one to copy it to the clipboard and paste into in the current application.
<string>Change the case of text on the keyboard with the keyword case. All three styles are previewed as Alfred results. Select one to copy it to the clipboard and paste into in the current application.
Optionally, any text typed after `case` will be changed instead of the clipboard.</string>
Optionally, any text type after case will be changed instead of the clipboard.</string>
<key>uidata</key>
<dict>
<key>272A1B72-8F54-4B5F-831A-8787D7264102</key>
Expand All @@ -230,6 +293,13 @@ Optionally, any text typed after `case` will be changed instead of the clipboard
<key>ypos</key>
<integer>330</integer>
</dict>
<key>3EEC7A2D-486C-4756-A271-FAD9448441C8</key>
<dict>
<key>xpos</key>
<integer>260</integer>
<key>ypos</key>
<integer>220</integer>
</dict>
<key>48FA1057-4D68-48B5-BB44-CBC28130A414</key>
<dict>
<key>xpos</key>
Expand All @@ -252,8 +322,6 @@ Optionally, any text typed after `case` will be changed instead of the clipboard
<integer>110</integer>
</dict>
</dict>
<key>version</key>
<string>1.1</string>
<key>webaddress</key>
<string>https://github.com/gillibrand/alfred-change-case</string>
</dict>
Expand Down
Binary file modified kebabcase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lowercase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified snakecase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified titlecase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified uppercase.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 3d9eb58

Please sign in to comment.