Получение данных RTF из буфера обмена Mac OS X (буфер обмена)

Согласно man страница для pbpaste,

   -Prefer {txt | rtf | ps}
          tells pbpaste what type of data to look for  in  the  pasteboard
          first.   As stated above, pbpaste normally looks first for plain
          text data; however,  by  specifying  -Prefer  ps  you  can  tell
          pbpaste to look first for Encapsulated PostScript.  If you spec-
          ify -Prefer rtf, pbpaste looks first for Rich Text  format.   In
          any  case,  pbpaste looks for the other formats if the preferred
          one is not found.  The txt option replaces the deprecated  ascii
          option,  which continues to function as before.  Both indicate a
          preference for plain text.

Однако (по моему опыту с 10.6 Snow Leopard по крайней мере), pbpaste -Prefer rtf никогда, никогда не откажется от данных RTF, даже если они существуют на монтажном столе. Есть ли другой простой способ получить RTF-текст того, что готово для вставки?

Я пробовал AppleScript, но osascript -e 'the clipboard as «class RTF »' дает ответ «data RTF 7Bтонна шестнадцатеричного закодированного дерьма7D», Может ли AppleScript преобразовать эти шестнадцатеричные данные в текст, с которым я могу играть?

6 ответов

Решение

Я не вижу никакого способа сделать это изнутри AppleScript, но так как вы все равно работаете в оболочке, я просто постобработаю это: "шестнадцатеричное дерьмо" - это данные RTF, которые вы хотите. Самый простой сценарий, который я могу придумать,

perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'

Объяснение: substr($_,11,-3) снимает с «data RTF а также »\n биты (каждый из guillemets составляет два байта); pack("H*", ...) упаковывает шестнадцатеричные данные в байтовый поток; unpack("C*", ...) распаковывает байтовый поток в массив символьных значений; print chr foreach ... преобразует каждое целое число в массиве в соответствующий ему символ и печатает его; и -ne Опции оценивают сценарий, заданный для каждой строки, причем эта строка неявно хранится в $_, (Если вы хотите этот скрипт в своем собственном файле, просто убедитесь, что строка shebang #!/usr/bin/perl -ne.) Затем бегом

osascript -e 'the clipboard as «class RTF »' | \
  perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'

даст вам сырой RTF вывод.

Я думаю, что по крайней мере на OS X 10.8 это будет работать, если вы скопировали HTML-контент из Chrome:

osascript -e 'the clipboard as "HTML"'|perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))'

Простое решение AppleScript от меня. Это быстрее, чем предлагалось в других ответах:

      -- script: Get raw RTF content from the clipboard
-- written: by me, right now

clipboard_as_raw_RTF()

on clipboard_as_raw_RTF()
    -- catch the hext text from the error message
    try
        (the clipboard as «class RTF ») as text
    on error errorMessage
        set hexRTFData to errorMessage
    end try
    -- clear the garbage text 
    set ATID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to {"«data RTF ", "»"}
    set hexRTFData to text item 2 of hexRTFData
    set AppleScript's text item delimiters to ATID
    -- convert hexadecimal text to ASCII text
    do shell script "/bin/echo -n " & hexRTFData & " | xxd -r -p" without altering line endings
end clipboard_as_raw_RTF

А вот интересное решение AsObjC от пользователя @ionah на MacScripter. Этот код еще быстрее:

      use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

on clipboard_as_raw_RTF()
    set thePasteboard to current application's NSPasteboard's generalPasteboard()
    set theData to (thePasteboard's dataForType:(current application's NSPasteboardTypeRTF))
    if (theData is missing value) then return theData -- If no RTF data.
    return (current application's NSString's alloc()'s initWithData:(theData) encoding:(current application's NSUTF8StringEncoding)) as text
end clipboard_as_raw_RTF

clipboard_as_raw_RTF()

По моему опыту, невозможно получить данные RTF, даже если на странице руководства указано иное.

Самое простое решение - использовать вместо него pbv , который был разработан как раз для того, чтобы обойти ограничения.

Пример: после копирования следующей строки форматированного текста в буфер обмена: «Привет, я форматированный текст »

pbv может вернуть вам правильные данные RTF:

      $ pbv public.rtf | textutil -stdin -info
File:  stdin
  Type:  rich text format (RTF)
  Length:  19 characters
  Contents:  "Hi, I'm rich text"

В то время как pbpaste всегда будет выводить простой текст, даже если указано предпочесть RTF:

      $ pbpaste -Prefer rtf | textutil -stdin -info
File:  stdin
  Type:  plain text
  Length:  19 characters
  Contents:  "Hi, I'm rich text"

Найдено с помощью этого аналогичного вопроса .

Это очень легко с помощью AppleScript (протестировано в 10.11 El Capitan):

set the clipboard to (the clipboard as «class RTF »)

Вы можете создать Сервис через Automator:

  1. открыть автомат
  2. сделать новый сервис ("Dienst" на немецком языке)
  3. добавить "выполнить AppleScript"
  4. вход: ничего; выход; заменяет выбор

Сценарий:

-- name: convert to RTF
on run {input, parameters}
    set the clipboard to (the clipboard as «class RTF »)
    return the clipboard
end run

Готово. Теперь сохраните новый сервис и попробуйте его: выделите текст, затем перейдите в меню приложения и выберите "Сервисы" > "конвертировать в RTF"

Я нашел разговор об этом с помощью быстрого поиска в Google

Другие вопросы по тегам