Is there a way to use KM to convert a TXT file to RTF with predetermined font and size?
I'm importing a number of TXT files into an app that requires RTF, and I want to avoid tediously reformatting each one by hand.
Your suggestions appreciated.
Is there a way to use KM to convert a TXT file to RTF with predetermined font and size?
I'm importing a number of TXT files into an app that requires RTF, and I want to avoid tediously reformatting each one by hand.
Your suggestions appreciated.
Hey @anamorph,
Sure.
Put all your files in a directory.
Open the Terminal.
cd "<path-to-directory>`
To move the working directory to the correct place.
ls
To make certain you are in the correct place.
textutil -format txt -convert rtf -encoding UTF-8 -font Times -fontsize 18 *
To convert the files. (Change font family and size to suit.)
The originals are left intact, so you're okay if you make a mistake.
-Chris
Chris, this is very cool!
Could you please show us how to convert a specific file?
I think you just put in the filename; add full path if it's in another directory.
[EDIT] As I learned from posts elsewhere on the forum, you need to enclose path varables in double quotes so that textutil will properly recognize spaces in the path.
textutil -convert html foo.rtf
textutil -convert html "foo foo.rtf"
textutil -convert html "$KMVAR_myFilePathVariable"
Here is the textutil manual.
In case anyone needs to do this kind of thing with CSS formatting from JavaScript (could also be done from AppleScript, see below), a snippet writing RTF to the desktop might look something like:
(() => {
'use strict';
ObjC.import('AppKit');
// main :: IO ()
const main = () =>
bindLR(
rtfFromTextLR('font: italic 24px Courier;')(
'Certainty and confidence - twin forms of foolishness.'
),
strRTF => writeFile('~/Desktop/test.rtf', strRTF)
);
// rtfFromTextLR :: CSS String -> String -> Either String RTF String
const rtfFromTextLR = strCSS => strText =>
rtfFromHTML(
"<span style=\"" + strCSS + "\">" + strText + "</span>"
)
// rtfFromHTML :: String -> Either String String
const rtfFromHTML = strHTML => {
const
as = $.NSAttributedString.alloc
.initWithHTMLDocumentAttributes($(strHTML)
.dataUsingEncoding($.NSUTF8StringEncoding), 0
);
return bindLR(
typeof as
.dataFromRangeDocumentAttributesError !== 'function' ? (
Left('String could not be parsed as HTML')
) : Right(as),
// Function bound if Right value obtained above:
htmlAS => {
let error = $();
const rtfData = htmlAS
.dataFromRangeDocumentAttributesError({
'location': 0,
'length': htmlAS.length
}, {
DocumentType: 'NSRTF'
},
error
);
return Boolean(ObjC.unwrap(rtfData) && !error.code) ? Right(
ObjC.unwrap($.NSString.alloc.initWithDataEncoding(
rtfData,
$.NSUTF8StringEncoding
))
) : Left(ObjC.unwrap(error.localizedDescription));
}
);
};
// GENERIC FUNCTIONS ----------------------------
// https://github.com/RobTrew/prelude-jxa
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
const bindLR = (m, mf) =>
undefined !== m.Left ? (
m
) : mf(m.Right);
// writeFile :: FilePath -> String -> IO ()
const writeFile = (strPath, strText) =>
$.NSString.alloc.initWithUTF8String(strText)
.writeToFileAtomicallyEncodingError(
$(strPath)
.stringByStandardizingPath, false,
$.NSUTF8StringEncoding, null
);
// MAIN ---
return main();
})();
Applescript version of rtfFromHTML:
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
-- rtfFromHTML :: String -> Either String String
on rtfFromHTML(strHTML)
set ca to current application
set s to ca's NSString's stringWithString:strHTML
set d to (s)'s dataUsingEncoding:(ca's NSUTF8StringEncoding)
set attStr to ca's NSAttributedString's alloc()'s initWithHTML:d documentAttributes:(missing value)
if attStr is missing value then
|Left|("String could not be parsed as HTML")
else
set {rtfData, err} to attStr's ¬
dataFromRange:{location:0, |length|:attStr's |length|()} ¬
documentAttributes:{DocumentType:"NSRTF"} ¬
|error|:(reference)
if (missing value = rtfData) or (missing value is not err) then
|Left|(err's localizedDescription() as text)
else
|Right|((ca's NSString's alloc()'s ¬
initWithData:rtfData encoding:(ca's NSUTF8StringEncoding)) as text)
end if
end if
end rtfFromHTML
-- GENERIC FUNCTIONS from
-- https://github.com/RobTrew/prelude-applescript
In my previous example the asterisk is a placeholder for any file.
textutil -format txt -convert rtf -encoding UTF-8 -font Times -fontsize 18 *
Actually, since I'm only converting text files I really should have written it like this:
textutil -format txt -convert rtf -encoding UTF-8 -font Times -fontsize 18 *.txt
To manage a single file you can do this:
cd ~/'Downloads/test_textutil/'
textutil -format txt -convert rtf -encoding UTF-8 -font Times -fontsize 18 'test_textutil.txt'
** NOTE that I'm unnecessarily single-quoting the source directory path and the file name, because they don't contain any spaces. Nevertheless it's a good habit to get into -- because if you don't you'll get bitten at some point.
-Chris