Сценарий Apple для службы автоматизации для вставки простого текста в кавычки
Я новичок в MacOS, но я не смог найти никакого решения, так что вот что мне нужно: я работаю с большим количеством PDF-файлов, и мне нужно использовать много цитат. Мне нужен сервис automator для macos sierra со следующей функцией: когда я копирую текст из PDF, мне нужно вставить его в текстовый процессор (в основном, в scrivener, но желательно куда-нибудь еще). Хитрость: мне нужно вставить его в виде обычного текста, чтобы он соответствовал форматированию получаемого документа. Мне также нужно избавиться от всех разрывов строк. И мне нужны кавычки в начале и в конце вставленного текста.
Спасибо за любые предложения!
1 ответ
Вот документация о том, как сделать общесистемный сервис с помощью Automator. Вы захотите прочитать и следовать его инструкциям, в которых приведен пошаговый пример того, как взять какой-то выделенный текст и изменить его регистр в верхний регистр, а что нет.
Таким образом, метод не будет слишком далек от того, что вам нужно использовать для достижения вашего результата.
Вы упоминали об использовании Scrivener, но неявно предполагали, что мы все также используем его. Лично я этого не делаю, поэтому я понятия не имею, какие действия Automator поставляются с ним (если таковые имеются), а также является ли AppleScriptable или нет. Поэтому я уже ограничен тем, чем могу вам помочь, поэтому я собираюсь сосредоточиться на использовании другого приложения в этом примере.
Когда я копирую текст из PDF, мне нужно вставить его в текстовый процессор
Таким образом, ваша служба Automator будет принимать выбранный текст, который может быть из любого приложения или ограничен конкретным приложением по вашему выбору, таким как предварительный просмотр или какой-либо другой просмотрщик документов PDF.
Основная часть рабочего процесса Automator будет затем сценарием, что я преимущественно делаю с AppleScript. Поэтому я бы вставил действие " Выполнить AppleScript" в качестве первого действия, которое получит выделенный текст.
Это будет отправлено и сохранено в переменной input
из run
обработчик:
on run {input, parameters}
Мне нужно вставить его как обычный текст
Итак, первая строка скрипта, вероятно, будет:
set input to input as text
Это, вероятно, преждевременно и почти наверняка избыточно, так как через мгновение будут происходить манипуляции с содержимым переменной. Но также полезно, чтобы это было объявлено явно только тогда, когда кто-то читает сценарий обратно самому себе.
Мне нужно, чтобы разрывы строк были заменены пробелом
т.е. нет параграфов, только один, единственный блок прозы, как ваш вопрос.
set the text item delimiters to {space, linefeed, return}
set input to the text items of input as text
Мне нужны кавычки в начале и в конце вставленного текста.
set input to [quote, input, quote] as text
Вот рабочий процесс на данный момент:
Отсюда есть несколько вариантов того, что вы можете сделать:
① Поместите переформатированный текст в буфер обмена, как вы видите, что я сделал там, а затем позвольте пользователю просто перейти в любое приложение и вставьте текст самостоятельно. Если это то, что вы выбрали, тогда вы закончите, и на приведенном выше снимке экрана показан ваш завершенный сервис, который после сохранения будет доступен из меню сервисов в любом приложении, которое вы выберете (или в любом приложении, если вы его оставите).
Но если вы хотите продолжить...
② Получить рабочий процесс, чтобы открыть приложение с поддержкой сценариев и установить содержание документа в соответствии с содержанием нашего input
переменная. Я продемонстрирую это с помощью Apple TextEdit.
③ Заставьте рабочий процесс открывать любое обычное (не относящееся к сценариям) приложение и используйте довольно не элегантный метод наложения ограниченного контроля над некоторыми элементами приложения. Это немного менее надежно, чем ②, но если оно хорошо протестировано на одном приложении, которое вы всегда будете использовать, нет никаких причин, по которым оно не будет надежным.
Вставьте в приложение с поддержкой скриптов, например TextEdit.
Оказалось, что это немного сложнее, чем я надеялся. Несмотря на то, что возможность написания сценариев действительно делает это намного проще, некоторые свойства AppleScript отсутствовали в таких приложениях, как TextEdit и даже в страницах Apple, что означало, что регулярные сценарии привели меня примерно на полпути к тому, к чему я стремился, поэтому пришлось использовать некоторые из ту несправедливость, о которой я упоминал, чтобы пройти остаток пути туда. Поэтому я не буду утомлять вас тем, как разобраться, как это работает. Но вот часть скрипта, ответственная за получение выделенного входного текста в TextEdit:
script TextEdit
use application "System Events"
use T : application "TextEdit"
property parent : this
to receiveTheText:(plainText as string)
activate T
repeat until name of processes ¬
contains "TextEdit"
delay 1
end repeat
if not (exists document 1 of T) then
tell T to set D to make new document
else
set D to T's first document
end if
set [a, b] to the value of ¬
attribute "AXSelectedTextRange" of ¬
text area 1 of ¬
scroll area 1 of ¬
window 1 of ¬
process "TextEdit"
set character a of D's text to plainText & linefeed
end receiveTheText:
end script
Однако он работает на удивление хорошо, сохраняя локальное форматирование документа TextEdit и сопоставляя входящий текст с локальным стилем:
https://d2ffutrenqvap3.cloudfront.net/items/0r1h3z3D3z3Y2Z1e1X3r/Paste%20As%20Quote%20(TextEdit).gif
Вставить в приложение без сценариев, например, Scrivener
Итак, я скачал пробную версию Scrivener. К сожалению, он не поддерживает AppleScript, поэтому это ограничивает нас в некоторых отношениях. А именно, в то время как TextEdit не должен быть открыт, потому что служба Automator может открыть приложение и создать новый документ, если это необходимо, Scrivener действительно должен открыть проект, готовый для получения текста. Я полагаю, что это не слишком неудобно, но с точки зрения сценариев, писать сценарий было гораздо сложнее, и он может перестать работать должным образом, если Scrivener решит изменить свою программу.
Вот сценарий для Scrivener:
script Scrivener
use scripting additions
property parent : this
to receiveTheText:(plainText as string)
tell application "System Events" to ¬
if not (exists process "Scrivener") then ¬
return display alert ¬
"Application not running." & ¬
linefeed & linefeed & ¬
"When using this service with Scrivener, an open " & ¬
"project is required into which the text can be " & ¬
"inserted. AppleScript is unable to create a project " & ¬
"for you." as critical
tell application "Scrivener" to activate
tell application "System Events"
tell process "Scrivener" to set _P to ¬
a reference to (first window whose ¬
name of attributes contains "AXDocument" and ¬
value of attribute "AXDocument" contains ".scriv")
if not (exists _P) then ¬
return display alert ¬
"No open documents." & ¬
linefeed & linefeed & ¬
"Please create a project and try again." as critical
repeat until (count _P) = 0
set _T to a reference to (UI elements of _P ¬
whose role is "AXTextArea")
if (count _T) ≠ 0 then exit repeat
set _P to a reference to UI elements of _P
end repeat
set [_T] to _T --> The text area
tell _T to set value of attribute "AXSelectedText" to plainText
end tell
end receiveTheText:
end script
В заключение...
Чтобы закончить, вам понадобится весь сценарий целиком. Скрипты отдельных компонентов, которые я вставил выше, сами по себе мало что сделают. Вам нужно будет скопировать и вставить весь этот сценарий в рабочий процесс Automator, используя действие " Запустить AppleScript", которое я показал вам ранее.
Есть только одна необязательная переменная, которую вы можете изменить, которая находится в самом низу скрипта: вы увидите две практически идентичные строки, одна из которых закомментирована с предыдущей #
, Они определяют, передает ли служба текст TextEdit или Scrivener. В настоящее время он собирается перейти на Scrivener. Просто переключите #
символ другой строке, если вы хотите попробовать его с TextEdit.
property parent : AppleScript
property this : me
--------------------------------------------------------------------------------
script TextEdit
use application "System Events"
use T : application "TextEdit"
property parent : this
to receiveTheText:(plainText as string)
activate T
repeat until name of processes ¬
contains "TextEdit"
delay 1
end repeat
if not (exists document 1 of T) then
tell T to set D to make new document
else
set D to T's first document
end if
set [a, b] to the value of ¬
attribute "AXSelectedTextRange" of ¬
text area 1 of ¬
scroll area 1 of ¬
window 1 of ¬
process "TextEdit"
set character a of D's text to plainText & linefeed
end receiveTheText:
end script
script Scrivener
use scripting additions
property parent : this
to receiveTheText:(plainText as string)
tell application "System Events" to ¬
if not (exists process "Scrivener") then ¬
return display alert ¬
"Application not running." & ¬
linefeed & linefeed & ¬
"When using this service with Scrivener, an open " & ¬
"project is required into which the text can be " & ¬
"inserted. AppleScript is unable to create a project " & ¬
"for you." as critical
tell application "Scrivener" to activate
tell application "System Events"
tell process "Scrivener" to set _P to ¬
a reference to (first window whose ¬
name of attributes contains "AXDocument" and ¬
value of attribute "AXDocument" contains ".scriv")
if not (exists _P) then ¬
return display alert ¬
"No open documents." & ¬
linefeed & linefeed & ¬
"Please create a project and try again." as critical
repeat until (count _P) = 0
set _T to a reference to (UI elements of _P ¬
whose role is "AXTextArea")
if (count _T) ≠ 0 then exit repeat
set _P to a reference to UI elements of _P
end repeat
set [_T] to _T --> The text area
tell _T to set value of attribute "AXSelectedText" to plainText
end tell
end receiveTheText:
end script
--------------------------------------------------------------------------------
on run {input, parameters}
set input to input as text
set the text item delimiters to {space, linefeed, return}
set input to the text items of input as text
set input to [quote, input, quote] as text
# tell TextEdit to receiveTheText:input
tell Scrivener to receiveTheText:input
end run
-----------------------------------------------------------------------------END