Tengo un Servicio de Automator que toma el texto actual en el portapapeles y lo escribe en un nuevo archivo .txt. Esto se ejecuta simplemente con la siguiente pieza de código AppleScript:
do shell script "pbpaste > /path/to/your/clipboard-file.txt"
Este código es de la siguiente respuesta de desbordamiento de pila:
AppleScript para pegar texto del portapapeles en un archivo
Sin embargo, este código convierte el contenido del portapapeles en texto sin formato, eliminando todo el formato del texto.
¿Es posible usar AppleScript para escribir el contenido del portapapeles en un archivo .rtf o .rtfd, conservando el formato original del contenido del portapapeles? Por formato original, me refiero a datos estilísticos como énfasis tipográfico (negrita, cursiva, subrayado), tamaño de fuente y color del texto.
Por un capricho, probé el siguiente comando:
do shell script "pbpaste > /path/to/your/clipboard-file.rtf"
Pero este comando generó un archivo .rtf que mi computadora no pudo leer ni abrir.
Esta respuesta se ha actualizado para reflejar el malentendido de la esfera de rubik entre lo que es Rich Text (sobre lo que se preguntó originalmente) y lo que realmente se está trabajando desde Google Chrome, siendo HTML. (Ver comentarios movidos al chat ).
Dejo la respuesta original tal como está, y debajo de este nuevo contenido, ya que técnicamente responde a la pregunta original tal como se hizo. También contiene información relevante para el proceso general de tratar con el contenido del Portapapeles en el contexto de la pregunta original y modificada.
El siguiente código es un código de ejemplo que se probará y ejecutará en (Apple) Script Editor, ya que aparte de la primera oración de la pregunta, todavía no se ha proporcionado ningún uso explícito y específico dentro de Automator. Es posible que sea necesario editar el código para que funcione dentro del uso desconocido en Automator. Dicho esto, tal como está escrito, si todo el script a continuación se colocó solo en una acción Ejecutar AppleScript, solo, en Automator... funciona como está. Si usa solo segmentos del código , es posible que sea necesario realizar algunos cambios en el código existente .
El siguiente código contiene suficientes comentarios para comprender en general lo que está haciendo el script .
-- #
-- # Change the 'New RichText Filename.rtf' name to the wanted filename for the target file.
-- # Make sure you leave the double-quotes even if the filename does not contain spaces!
-- # Note that '(path to desktop as text)' can also be modified as needed, e.g. changed to,
-- # '(path to documents folder as text)' or the entire segment after 'set theRichTextFileName to'
-- # can be a fully qualified POSIX pathname, e.g.: set theRichTextFileName to "/path/to/filename.rtf"
-- #
set theRichTextFileName to POSIX path of (path to desktop as text) & "New RichText Filename.rtf"
-- # THE REMAINING CODE SHOULD NOT NEED TO BE MODIFIED.
-- #
-- # Note: This code, as is, works as written and intended when run from within (Apple) Script Editor.
-- # Some AppleScript code when wrapped in Automator may not work the same as in (Apple) Script Editor.
-- # In cases where is does not work from a Run AppleScript action in Automator, editing will be required.
-- #
-- # This AppleScript code preforms the following actions, sans errors caught during File I/O operations.
-- #
-- # 1. See it the target file exists and prompts to be overwritten if it does. If yes is selected, it continues.
-- #
-- # 2. If the Clipboard contains RTF content, writes it to the target file using plain AppleScript.
-- #
-- # 3. If the Clipboard contains HTML content, writes it to the target file as RTF using a 'do shell script' command.
-- #
-- # 4. If the Clipboard does not contain any RTF/HTML content, notify the user.
--
-- # Notes: The 'do shell script' makes use of the following:
-- #
-- # 'osascript' to get the HTML content from the Clipboard.
-- # The content is a Hex stream within a data wrapper and
-- # 'awk' will be used to remove/replace the data wrapper.
-- #
-- # 'awk' to remove the data wrapper from 'osascript' output
-- # replacing it with proper HTML opening/closing Tags to
-- # ensure it actually gets processed by 'textutil' after 'xxd'.
-- # Without the HTML opening/closing Tags 'textutil' does not
-- # properly, within limits, convert the HTML Clipboard content to RTF.
-- #
-- # 'xxd' to convert the Hex data from 'osascript/awk' to ASCII text.
-- #
-- # 'textutil' to convert the ASCII text HTML from 'xxd' to RTF
-- # formatted data and write it to the target file.
tell application "Finder"
if exists theRichTextFileName as POSIX file then
tell current application
display dialog "The file \"" & theRichTextFileName & "\" already exists!" & "\n\n" & "Do you want to overwrite the file?" buttons {"No", "Yes"} default button 1 with title "File Already Exists..." with icon caution
if the button returned of the result is "No" then
return
else
tell application "Finder"
delete the file (theRichTextFileName as POSIX file)
end tell
end if
end tell
end if
tell current application
-- # Find out what class types are available for the Clipboard content
-- # and use this information to determine which action will be taken.
set cbInfo to get (clipboard info) as string
if cbInfo contains "RTF" then
try
set richTextfromClipboard to get the clipboard as «class RTF »
on error eStr number eNum
display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
return
end try
try
set fileHandle to open for access theRichTextFileName with write permission
write richTextfromClipboard to fileHandle
close access fileHandle
on error eStr number eNum
display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with title "File I/O Error..." with icon caution
try
close access fileHandle
end try
end try
else if cbInfo contains "HTML" then
try
do shell script "osascript -e 'try' -e 'get the clipboard as «class HTML»' -e 'end try' | awk '{sub(/«data HTML/, \"3C68746D6C3E\") sub(/»/, \"3C2F68746D6C3E\")} {print}' | xxd -r -p | textutil -convert rtf -stdin -stdout > " & quoted form of theRichTextFileName
on error eStr number eNum
display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with icon caution
end try
else
display dialog "The Clipboard does not contain\nany usable RTF/HTML content!" buttons {"OK"} default button 1 with title "No RTF/HTML Content on Clipboard..." with icon caution
end if
end tell
end tell
Respuesta original a la pregunta original:
Para obtener contenido de texto enriquecido del Portapapeles en un archivo usando AppleScript , es un poco más complejo que un simple comando .do shell script
El código AppleScript de ejemplo a continuación, si el archivo de destino aún no existe y si existe contenido de texto enriquecido en el portapapeles , lo escribirá en un archivo . Tendrá todos los atributos que tiene el contenido de RichText en el Portapapeles , como lo hizo cuando se copió en el Portapapeles .
Abra el Editor de secuencias de comandos y copie y pegue el código a continuación en un nuevo documento Sin título y luego ejecútelo desde el Editor de secuencias de comandos , revisando el resultado en Eventos/Respuestas . Ejecútelo un par de veces, con y sin contenido de texto enriquecido en el Portapapeles y con y sin la existencia del archivo , en el disco duro, definido por al inicio del script .set theRichTextFileName ...
Verá que el código se asegura de que el archivo no exista, para no sobrescribir un archivo existente del nombre y la ubicación de destino y si el Portapapeles no contiene contenido de texto enriquecido , también muestra un mensaje para eso.
Ahora, si usa esto en un Servicio de Automator , por ejemplo, donde el Servicio recibe texto enriquecido seleccionado , entonces el código puede modificarse para que no detecte un error si el contenido de Texto enriquecido no está en el Portapapeles , ya que el servicio no aparecerá en el menú Servicios si El texto enriquecido no está seleccionado en un documento. Además, si desea sobrescribir el archivo de destino en su ubicación designada, el código que lo rodea también se puede eliminar. También daré esos ejemplos de código .
Código de ejemplo para pegar en el Editor de secuencias de comandos para probarlo y revisarlo:
set theRichTextFileName to POSIX path of (path to documents folder as text) & "New RichText Filename.rtf"
tell application "Finder"
if exists theRichTextFileName as POSIX file then
tell current application
display dialog "The file \"" & theRichTextFileName & "\" already exists!" buttons {"OK"} default button 1 with title "File Already Exists..." with icon caution
end tell
else
tell current application
try
set richTextfromClipboard to get the clipboard as «class RTF »
on error eStr number eNum
display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with title "No Rich Text Content on Clipboard..." with icon caution
return
end try
try
set fileHandle to open for access theRichTextFileName with write permission
write richTextfromClipboard to fileHandle
close access fileHandle
on error eStr number eNum
display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with title "File I/O Error..." with icon caution
try
close access fileHandle
end try
return
end try
end tell
end if
end tell
Código de ejemplo para usar en un Servicio de Automator , por ejemplo, donde el Servicio recibe texto enriquecido seleccionado :
set theRichTextFileName to POSIX path of (path to documents folder as text) & "New RichText Filename.rtf"
tell application "Finder"
if exists theRichTextFileName as POSIX file then
tell current application
display dialog "The file \"" & theRichTextFileName & "\" already exists!" buttons {"OK"} default button 1 with title "File Already Exists..." with icon caution
end tell
else
tell current application
set richTextfromClipboard to get the clipboard as «class RTF »
set fileHandle to open for access theRichTextFileName with write permission
write richTextfromClipboard to fileHandle
close access fileHandle
end tell
end if
end tell
Código de ejemplo para usar en un Servicio de Automator , por ejemplo, donde el Servicio recibe texto enriquecido seleccionado y sobrescribe el archivo de destino existente :
set theRichTextFileName to POSIX path of (path to documents folder as text) & "New RichText Filename.rtf"
tell current application
set richTextfromClipboard to get the clipboard as «class RTF »
set fileHandle to open for access theRichTextFileName with write permission
write richTextfromClipboard to fileHandle
close access fileHandle
end tell
La siguiente imagen es de un servicio de Automator de ejemplo que crea el archivo New RichText Filename.rtf a partir del texto enriquecido seleccionado del servicio Crear archivo de texto enriquecido desde el portapapeles en el menú contextual de servicios (haciendo clic con el botón derecho) o Application_name > Services > menu , cuando El texto enriquecido está seleccionado en un documento.
Ahora, estos son solo ejemplos y se puede codificar lógica adicional para adaptarlo a las necesidades de uno. Como ejemplo, se podría agregar código para incrementar automáticamente el nombre de un archivo existente para no sobrescribirlo, o solicitar un nuevo nombre de archivo y completar la operación en lugar de abortar con un mensaje de que el archivo ya existe, etc.
Actualización para usar con un do shell script
comando :
Si realmente desea hacerlo usando un do shell script
comando , use el siguiente código mientras lo reemplaza con un nombre de archivo de ruta/path/to/new rich text file.rtf
válido a una ubicación en la que tenga permisos de escritura. Tenga en cuenta que no elimine el antes y el después en el comando real , ya que esto maneja el nombre del archivo de la ruta si contiene espacios. Si el nombre del archivo de la ruta no contiene espacios, entonces no es necesario usar el antes y el después .\"
/path/to/new rich text file.rtf
\"
/path/to/new rich text file.rtf
do shell script "osascript -e 'try' -e 'get the clipboard as «class RTF »' -e 'end try' | awk '{print substr($0, 12, length($0)-13)}' | xxd -r -p > \"/path/to/new rich text file.rtf\""
Aquí está la línea de comando que se muestra como texto ajustado, para facilitar la visualización:
do shell script "osascript -e 'try' -e 'get the clipboard as «class RTF »' -e 'end try' | awk '{print substr($0, 12, length($0)-13)}' | xxd -r -p > \"/path/to/new rich text file.rtf\""
Si bien se puede copiar y pegar (recomendar) el código , aquí se explica cómo escribir las comillas de doble ángulo, que también están disponibles entre paréntesis en caracteres (especiales), por ejemplo, optioncommandTen TextEdit.
Nota: Tenga en cuenta que el espaciado «class RTF »
está destinado a compensarse en este caso de uso.
Escribir comillas de doble ángulo
Tenga en cuenta que, tal como está escrito, este do shell script
comando sobrescribe el archivo de salida si ya existe, ¡sin preguntar! Será un archivo de longitud cero si el Portapapeles no contiene ningún contenido de texto enriquecido; de lo contrario, el archivo tendrá la longitud necesaria para contener el contenido de texto enriquecido del Portapapeles. Obviamente, se podría codificar lógica adicional en el osascript
comando ; sin embargo, si necesita más complejidad, es mejor que use el método presentado por primera vez en esta respuesta. O usar un script externo llamado por do shell script
comando que maneja toda la lógica necesaria y el manejo de errores en función de la complejidad de las condiciones generales en las que se aplicará.
do shell script "pbpaste > /path/to/clipboard-file.rtf"
¿ Por qué tanta complejidad vs.Esa es una buena pregunta y, si bien pbpaste
tiene la -Prefer {txt | rtf | ps}
opción, pbpaste -Prefer rtf
es posible que no genere texto enriquecido, incluso si existe en el portapapeles. O lo que genera, si no es texto ASCII, no será una forma de texto enriquecido que se entienda, por ejemplo, TextEdit, y no contendrá todos los atributos de texto enriquecido , si los hay, que contiene el contenido del portapapeles.
Esto hace que sea necesario obtener el contenido de texto enriquecido en el Portapapeles de una manera diferente y por qué get the clipboard as «class RTF »
se usa en su lugar. Cuando se usa un do shell script
comando con esto, se requiere un procesamiento adicional para utilizar los datos devueltos, ya que están en un envoltorio de datos cuando se devuelven y no se pueden usar de inmediato, por lo que requiere un procesamiento adicional.
Como ejemplo, Hello World!
en texto enriquecido en el portapapeles puede verse así en texto ASCII:
{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400
{\fonttbl\f0\fnil\fcharset0 ComicSansMS;}
{\colortbl;\red255\green255\blue255;}
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural
\f0\b\fs36 \cf0 Hello World!}
Desafortunadamente, el formato anterior no es fácil de usar, en todo caso, en AppleScript y creo que es por eso que se requiere capturar como datos codificados en Hex.
get clipboard info
comando para el contenido del Portapapeles en este ejemplo se devuelve {«class RTF », 265}
entre la información devuelta, aunque el formato de texto ASCII de este contenido de texto enriquecido tiene 265 bytes de largo, se devuelve en formato hexadecimal en más del doble. los bytes con el contenedor de datos . El hecho de que se devuelva en hexadecimal tanto get the clipboard as «class RTF »
en el editor de scripts como en el uso osascript
respalda esta suposición.Aquí está lo mismo Hello World!
en texto enriquecido en el portapapeles en hexadecimal:
7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D
Sin embargo, lo que devuelve get the clipboard as «class RTF »
el Hello World!
ejemplo anterior es:
«data RTF 7B5C727466315C616E73695C616E7369637067313235325C636F636F61727466313138375C636F636F617375627274663430300A7B5C666F6E7474626C5C66305C666E696C5C66636861727365743020436F6D696353616E734D533B7D0A7B5C636F6C6F7274626C3B5C7265643235355C677265656E3235355C626C75653235353B7D0A5C706172645C74783732305C7478313434305C7478323136305C7478323838305C7478333630305C7478343332305C7478353034305C7478353736305C7478363438305C7478373230305C7478373932305C7478383634305C7061726469726E61747572616C0A0A5C66305C625C66733336205C6366302048656C6C6F20576F726C64217D»
La cadena codificada en hexadecimal está en un «data RTF »
envoltorio que debe eliminarse antes de convertir el contenido codificado en hexadecimal en texto ASCII para escribirlo en un archivo de disco mediante el uso de la redirección de E/S, por ejemplo, >
en el ejemplo do shell script
de comando anterior.
Por lo tanto, la salida de osascript -e 'try' -e ' get the clipboard as «class RTF »' -e 'end try'
se canaliza ( |
) a awk
donde crea una subcadena, imprimiendo solo el contenido codificado en Hex, no la parte del envoltorio de datos , ya que no se procesaría correctamente en xxd
el siguiente paso del proceso.
A continuación, debe canalizarse ( |
) para xxd
que la conversión ASCII Text
se escriba en un archivo de disco mediante la redirección de E/S, por ejemplo >
, en la ruta de destino del nombre de archivo .
La siguiente imagen es del Visor del portapapeles alternando entre las vistas de codificación de texto ASCII y hexadecimal, que muestra Hello World!
una copia de un documento de texto enriquecido, el que se usa en este ejemplo.
Espero que esto proporcione una mejor comprensión de cómo funciona AppleScript con el contenido de texto enriquecido en el portapapeles, ya que de cualquier manera debe realizarse la conversión de una cadena codificada en hexadecimal a texto ASCII y esto se realiza de forma transparente en el código de ejemplo original y requiere un procesamiento adicional . fuera del código AppleScript que se está procesando osascript
cuando se usa el do shell script
comando en este contexto.
delete the file (theRichTextFileName as POSIX file)
Finder en la rama else agregada de la declaración .
tell
if the button returned of the result is "No" then
Los archivos RTF, a diferencia de los archivos TXT, no son solo texto sin formato, sino que tienen una estructura básica. Para crear un archivo RTF, use la siguiente estructura (en lugar del texto sin formato de su teclado):
{\rtf1\ansi\deff0 {\fonttbl {\f0 Verdana;}}
\f0\fs16
Hello World!
}
Fuente: https://www.safaribooksonline.com/library/view/rtf-pocket-guide/9781449302047/ch01.html
Aquí hay funciones basadas en la respuesta del usuario 3439894 para imprimir la versión de texto enriquecido del portapapeles convertido a HTML o la versión HTML del portapapeles. La versión HTML del portapapeles se incluye para el texto copiado desde una vista web.
ppr(){ osascript -e'the clipboard as"RTF "'|sed 's/«data RTF //;s/»//'|xxd -r -p|textutil -convert html -stdin -stdout; }
pph(){ osascript -e'the clipboard as"HTML"'|sed 's/«data HTML//;s/»//'|xxd -r -p; }
Los sed
comandos anteriores también se pueden reemplazar con ruby -lpe'$_=$_[10..-2]'
(aunque eso seleccione las posiciones de byte incorrectas en la configuración regional C).
En versiones anteriores de OS X, pbpaste -Prefer rtf
se imprimía la versión RTF del portapapeles, pero ahora solo parece imprimir texto sin formato.
usuario3439894
usuario3439894