6

I'm trying to create an Automator Service that will act on selected text, converting dashes to spaces, and also making word caps for all the text.

A friend gave me this python script (I know nothing about python or shell scripting):

#! /usr/bin/python

cliptext = "%clipboard"
print cliptext.replace('-', ' ').replace('%', ' ').replace('&', ' and ').replace('#', ' ').title()

It works great as a TextExpander snippet, but I'd like to have it available in the Services menu as well. I don't need it to use any specific scripting language, it just needs to run within Automator. My coding buddy had no experience with Automator so he couldn't help out. His script requires copying the text to the clipboard, and then runs the formatting and pastes the result. I'd like to be able to just run this on the selected text and not have to deal with the Clipboard (at least manually).

The particular use for this is to rename photo uploads on Flickr, since Flickr uses the filename to generate the photo name. When exporting artwork via Photoshop or Illustrator using Save For Web, the lowercase and dashes are my default settings. I want to be able to highlight the Flickr title, and then run the Service to reformat the file name to a properly formatted title.

2 Answers 2

9

This isn't too difficult to do, you just need to know the right magic. I'll walk you through it.

  1. Open Automator, and when prompted to choose a type for your document, select Service. If you're not prompted, just hit ⌘N to make a new automator file.
  2. At the top of the rightmost panel, make sure that Output replaces selected text is checked, and the first drop-down is set to text: service input settings
    • You can change the any application part to a specific application if you only want it to work in that program.
  3. In the Actions Library in the left panel, find Run Shell Script and double click it to add it to the workflow.
  4. Change the Shell drop down to /usr/bin/python, and make sure that Pass input is set to stdin.
  5. Delete the existing text in the script box, and replace it with the code below.
  6. Save it with a descriptive name. Automator will save it in the ~/Library/Services/ folder.
  7. Optional: Go to Keyboard Preferences, and find your service in the Services section of the Keyboard Shortcuts tab. You can assign a system-wide shortcut for it there.

Script Code

import sys

for f in sys.stdin:
    print f.replace('-', ' ').replace('%', ' ').replace('&', ' and ').replace('#', ' ').title(),
1
  • thank you, this worked perfectly! I have limited understanding of AppleScript, but none with shell scripts.
    – George C
    Commented Aug 6, 2012 at 18:06
0

The answer from @robmathers is fine but today we should use Python3, which is available from the dropdown as well on current macOSes.

Then the print statement changes to a function print().

To avoid newlines when printing multiple lines you can change the lineending of the print() to print(data, end='')

To fiddle with the clipboard you can use these snippets in the python block:

import sys
import subprocess

def getClipboardData():
    p = subprocess.Popen(['pbpaste'], stdout=subprocess.PIPE)
    retcode = p.wait()
    data = p.stdout.read()
    return data

def setClipboardData(data):
    p = subprocess.Popen(['pbcopy'], stdin=subprocess.PIPE)
    p.stdin.write(data)
    p.stdin.close()
    retcode = p.wait()

# A prefix like b"text" for a string or proper encoded bytes conversion is required before entering data to setClipboardData(data) as argument to avoid:
# ``TypeError: a bytes-like object is required, not 'str'``

data = list(sys.stdin)

# To replace data in place use
# print("".join(data), end='')

# copy data/result to the clipboard
data = "".join(data).encode('utf_8')
setClipboardData(data)

This example does not provide any template to modify the data. Use the approach by @robmathers above and extend.

clipboard functions courtesy: https://gist.github.com/XuankangLin/7ec82f80a0044a52330720244de2d15a

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .