This script splits RTF(D) records at Font Sizes.
It optionally groups the resulting records according to their Font Size level.
It also optionally changes the font and font size.
Idea
While it’s not possible to get RTF headings directly it is possible to
-
analyze the text
-
assume that the font size that’s most used is the body text’s font size
-
assume that everything that’s larger than the body text’s font size * ratio X is a heading
This way it’s possible to ask the user at which ratio X a RTF should be split. Thanks for that chrillek!
Setup
You can change every property.
-
property
joinHeadings
: Join headings if there’s no body text between them -
property
dontCreateHeadingOnlyRecord
: Don’t create a record if it would only contain a heading -
property
changeFont
: Iftrue
then the resulting records’ font and font size is changed. -
property
theFontSize
: The desired font size of the body text, e.g.14.0
If set to0
then DEVONthink’s rich text font size is used (seePreferences > Edit
) -
property
theFontName
: The desired font’s family name, e.g."Lucida Grande"
If set to""
then DEVONthink’s rich text font is used (seePreferences > Edit
) -
property
theMonoFontName
: The desired mono spaced font’s family name, e.g."Courier"
If set to""
then only the font size of mono spaced fonts is changed
(There’s no DEVONthink preference that could be used, so if you want to change mono spaced fonts you’ll have to set this property) -
property
createGroups
: Group records according to their heading level.
Note: This may produce unwanted results if used with badly structured headings.
E.g. RTFs that were created by converting PDFs sometimes work fine, however often it’s necessary to remove the first “page” from the RTF before groups are created correctly. -
property
createGroups_dontGroupLastLevel
: Don’t create a group for the last heading level.
E.g. heading “1.1.1” goes into group “1.1” -
property
createScriptSettingsGroup
: Creates additional group whose name contains some of the script’s settings
For easier usage save different script versions, one for each settings combination you intend to use.
Usage
-
Select some RTF(D) record
-
Run script
-
You’ll be asked at the which ratio the record should be split.
The default is1.3
which often works fine. -
If the result isn’t the desired one try again with another ratio
It is, of course, also possible to first manually check the body text’s font size and the font size of the lowest heading level you’d like to split at. Then divide the heading thru the body text font size.
Help …
-
… it doesn’t group correctly! Grouping depends on the order of headings. If groups aren’t created correctly check the order of the first headings in your RTF. You’ll probably find that there’s something mixed up. That’s often the case with RTFs that were created by converting PDFs or by clipping from the web. Removing mixed up headings should be sufficient to fix incorrect grouping.
-
… it doesn’t split correctly! If this script doesn’t produce the desired result (even after several runs) please let me know. You can always use Script: Split RTF(D) at Delimiter.
-- Split RTF(D) at Font Sizes
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
property joinHeadings : true -- join headings if there's no text between them.
property dontCreateHeadingOnlyRecord : true -- don't create a record if it would only contain a heading
property changeFont : false -- set this to false if you don't want to change the font
property theFontSize : 0 -- if 0 DEVONthink's rich text font size is used (see preferences > edit). To use another size set this property to e.g. 14.0
property theFontName : "" -- if "" DEVONthink's rich text font is used (see preferences > edit). To use another font set this property to e.g. "Lucida Grande"
property theMonoFontName : "" -- if "" only the mono spaced font's size is changed. To use another mono spaced font set this property to e.g. "Courier"
property createGroups : true -- attempt to group records according to their heading level. this may produce unwanted results if used with badly structured headings
property createGroups_dontGroupLastLevel : true -- don't group last heading level. e.g. heading "1.1.1" goes into group "1.1"
property createSmartGroup : false
property createScriptSettingsGroup : true -- create additional group whose name contains some of the script's settings
global theRatio_Heading, theProgressSteps
tell application id "DNtp"
try
set theRecords to selected records whose type = rtfd or type = rtf
if theRecords = {} then error "Please select some RTF(D) record"
set theChooseFromListItems to {"1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2.0"}
set theChoice to choose from list theChooseFromListItems with prompt "Split at Font Sizes ≥ Body Text * " default items (item 3 of theChooseFromListItems) with title ""
if theChoice is false then return
set theRatio_Heading to (item 1 of theChoice) as real
repeat with thisRecord in theRecords
set thisRecord_Path to path of thisRecord
set thisRecord_Name to name without extension of thisRecord
my splitRTFDatFontSizes(thisRecord_Path, thisRecord_Name, thisRecord)
end repeat
on error error_message number error_number
hide progress indicator
activate
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
on splitRTFDatFontSizes(theRecord_Path, theRecord_Name, theRecord)
try
if changeFont then
set theProgressSteps to 5
else
set theProgressSteps to 3
end if
set theAttributedString to my readAttributedString(theRecord_Path)
set theAttributedString_Length to theAttributedString's |length|()
if theAttributedString_Length = 0 then return
---------------------------------------------------------- Get Font Attributes ---------------------------------------------------------------
tell application id "DNtp" to show progress indicator "Analyzing... " & theRecord_Name steps theProgressSteps with cancel button
tell application id "DNtp" to step progress indicator
set theLocation to 0
set theAttribute to current application's NSFontAttributeName
set theCharacterSet to (current application's NSCharacterSet's alphanumericCharacterSet())'s invertedSet()
set theAttributesArray to current application's NSMutableArray's new()
repeat while (theLocation < theAttributedString_Length)
set {thisFont, thisFontRange} to theAttributedString's attribute:theAttribute atIndex:(theLocation) longestEffectiveRange:(reference) inRange:{location:theLocation, |length|:(theAttributedString_Length - theLocation)}
theAttributesArray's addObject:{|Font|:thisFont, FontRange:thisFontRange, FontSize:(thisFont's pointSize()), |Substring_alphanumeric|:(((theAttributedString's attributedSubstringFromRange:thisFontRange)'s |string|())'s stringByTrimmingCharactersInSet:theCharacterSet)}
set theLocation to theLocation + (thisFontRange's |length|)
end repeat
---------------------------------------------------------- Analyze Font Sizes ----------------------------------------------------------------
set theFontSizes to ((theAttributesArray's valueForKey:"FontSize")'s valueForKeyPath:"@distinctUnionOfObjects.self")'s sortedArrayUsingDescriptors:{(current application's NSSortDescriptor's sortDescriptorWithKey:"self" ascending:false selector:"compare:")}
set theFontSizes_SortedTotalLengthsArray to current application's NSMutableArray's new()
repeat with i from 0 to ((theFontSizes's |count|()) - 1)
set thisFontSize to (theFontSizes's objectAtIndex:i)
set thisFontSizeTotalLength to (((theAttributesArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.FontSize = " & (thisFontSize))))'s valueForKeyPath:"FontRange.length")'s valueForKeyPath:"@sum.self")
(theFontSizes_SortedTotalLengthsArray's addObject:{FontSize:thisFontSize, TotalLength:thisFontSizeTotalLength})
end repeat
theFontSizes_SortedTotalLengthsArray's sortUsingDescriptors:{(current application's NSSortDescriptor's sortDescriptorWithKey:"TotalLength" ascending:false selector:"compare:")}
set theFontSize_Body to (((theFontSizes_SortedTotalLengthsArray)'s firstObject())'s valueForKey:"FontSize") as real
------------------------------------------------------------ Get Headings --------------------------------------------------------------------
set theFontSize_HeadingMin to theFontSize_Body * theRatio_Heading
set theFontSizes_Headings to (theFontSizes's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self => " & (current application's NSNumber's numberWithDouble:theFontSize_HeadingMin))))
set theFontSizes_Headings_withoutSingles to my getFontSizesHeadingsWithoutSingles(theFontSizes_Headings, theAttributesArray)
set theHeadingsArray to (theAttributesArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.FontSize IN " & "{" & (theFontSizes_Headings_withoutSingles's componentsJoinedByString:",") & "}" & " AND " & "!self.Substring_alphanumeric = ''")))
if (theHeadingsArray's |count|()) = 0 then
tell application id "DNtp" to hide progress indicator
return
end if
------------------------------------------------------- Create Substring Ranges -------------------------------------------------------------
tell application id "DNtp" to step progress indicator
set theBodyTextArray to (theAttributesArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.FontSize < " & (current application's NSNumber's numberWithDouble:theFontSize_HeadingMin))))
if joinHeadings then set theSortDescriptor to (current application's NSSortDescriptor's sortDescriptorWithKey:"FontSize" ascending:false selector:"compare:")
set i to 0
set theCount to (theHeadingsArray's |count|()) - 1
set theSubstringRanges to current application's NSMutableArray's new()
repeat while i ≤ theCount
set thisItem to (theHeadingsArray's objectAtIndex:i)
set thisLocation to (thisItem's valueForKeyPath:"FontRange.location") as integer
set thisLength to (thisItem's valueForKeyPath:"FontRange.length") as integer
if i = 0 and thisLocation ≠ 0 then
set thisLength to thisLength + thisLocation
set thisLocation to 0
end if
set thisSubstring to missing value
set createRecord to true
if i < theCount then
if joinHeadings then
set thisRangeMax to thisLocation + thisLength
set thisArray to current application's NSMutableArray's arrayWithArray:{thisItem}
set joinedHeadings to missing value
repeat with j from (i + 1) to theCount
set thisNextLocation to (((theHeadingsArray's objectAtIndex:(j)))'s valueForKeyPath:"FontRange.location") as integer
set thisBodyTextArray_filtered to (theBodyTextArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.FontRange.location BETWEEN {" & thisRangeMax & "," & (thisNextLocation - 1) & "}" & " AND " & "!self.Substring_alphanumeric = ''")))
if (thisBodyTextArray_filtered's |count|()) > 0 then
exit repeat
else
(thisArray's addObject:(theHeadingsArray's objectAtIndex:(j)))
set joinedHeadings to true
set i to i + 1
end if
end repeat
if joinedHeadings = true then
set thisSubstring to (thisArray's sortedArrayUsingDescriptors:{theSortDescriptor})'s firstObject()'s valueForKey:"Substring_alphanumeric"
end if
else
set thisNextLocation to (((theHeadingsArray's objectAtIndex:(i + 1)))'s valueForKeyPath:"FontRange.location") as integer
if dontCreateHeadingOnlyRecord then
set thisRangeMax to thisLocation + thisLength
set thisBodyTextArray_filtered to (theBodyTextArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.FontRange.location BETWEEN {" & thisRangeMax & "," & (thisNextLocation - 1) & "}" & " AND " & "!self.Substring_alphanumeric = ''")))
if (thisBodyTextArray_filtered's |count|()) = 0 then
if not (theAttributedString's containsAttachmentsInRange:{location:thisLocation, |length|:(thisNextLocation - thisLocation)}) then
set createRecord to false
end if
end if
end if
end if
set theLength to thisNextLocation - thisLocation
else if i = theCount then
set theLength to theAttributedString_Length - thisLocation
end if
set thisRange to {location:thisLocation, |length|:theLength}
if thisSubstring = missing value then set thisSubstring to thisItem's valueForKey:"Substring_alphanumeric"
(theSubstringRanges's addObject:{|Range|:thisRange, FontSize:(thisItem's valueForKey:"FontSize"), FirstLine:(paragraph 1 of (thisSubstring as string)), createRecord:createRecord})
set i to i + 1
end repeat
------------------------------------------------------------- Change Font ----------------------------------------------------------------------
if changeFont then
tell application id "DNtp" to show progress indicator "Changing Font... " & theRecord_Name steps theProgressSteps with cancel button
tell application id "DNtp" to step progress indicator
if theFontName = "" or theFontSize = 0 then
if current application's id = "com.devon-technologies.think3" then -- https://forum.latenightsw.com/t/storing-persistent-values-in-preferences/864
set theDefaults to current application's NSUserDefaults's standardUserDefaults()
else
set theDefaults to current application's NSUserDefaults's alloc()'s initWithSuiteName:"com.devon-technologies.think3"
end if
if theFontName = "" then set theFontName to (theDefaults's dictionaryRepresentation())'s stringForKey:"RichFontName"
if theFontSize = 0 then set theFontSize to (theDefaults's dictionaryRepresentation())'s doubleForKey:"RichPointSize"
end if
set theFont to current application's NSFont's fontWithName:(theFontName) |size|:theFontSize
if theFont = missing value then error "Please provide a valid Font Name"
set theFont_FamilyName to theFont's familyName()
if theMonoFontName ≠ "" then
set theMonoFont to current application's NSFont's fontWithName:(theMonoFontName) |size|:theFontSize
if (theMonoFont = missing value) or not ((theMonoFont's isFixedPitch()) as boolean) then error "Please provide a valid Mono Font Name"
set theMonoFont_FamilyName to theMonoFont's familyName()
else
set theMonoFont_FamilyName to missing value
end if
set theFontSize_Ratio to (theFontSize / theFontSize_Body)
set theFontManager to current application's NSFontManager's sharedFontManager()
set theAttribute to current application's NSFontAttributeName
set theMutableAttributedString to theAttributedString's mutableCopy()
repeat with i from 0 to ((theAttributesArray's |count|()) - 1)
set thisItem to (theAttributesArray's objectAtIndex:i)
set thisFont to (thisItem's valueForKey:"Font")
set thisFontRange to (thisItem's valueForKey:"FontRange")
set thisFontSize to (thisItem's valueForKey:"FontSize") as real
set thisNewFontSize to thisFontSize * theFontSize_Ratio
set thisNewFont to (theFontManager's convertFont:(thisFont) toSize:thisNewFontSize)
if not ((thisFont's isFixedPitch()) as boolean) then
set thisNewFont to (theFontManager's convertFont:thisNewFont toFamily:theFont_FamilyName)
else
if theMonoFont_FamilyName ≠ missing value then
set thisNewFont to (theFontManager's convertFont:thisNewFont toFamily:theMonoFont_FamilyName)
end if
end if
(theMutableAttributedString's removeAttribute:theAttribute range:thisFontRange)
(theMutableAttributedString's addAttribute:theAttribute value:thisNewFont range:thisFontRange)
end repeat
set theAttributedString to theMutableAttributedString
end if
------------------------------------------------------ Write Temp Files & Import ---------------------------------------------------------------
tell application id "DNtp" to show progress indicator "Splitting... " & theRecord_Name steps theProgressSteps with cancel button
tell application id "DNtp" to step progress indicator
set theTempDirectoryURL to my createTempDirectory()
if createGroups then
if createGroups_dontGroupLastLevel then
if ((theFontSizes_Headings_withoutSingles's |count|()) > 1) then
set theFontSize_GroupingMin to (theFontSizes_Headings_withoutSingles's objectAtIndex:(((theFontSizes_Headings_withoutSingles's |count|()) as integer) - 2)) as real
set theGroupLevelDictionary to current application's NSMutableDictionary's new()
else
set createGroups to false
end if
else
set theFontSize_GroupingMin to (theFontSizes_Headings_withoutSingles's objectAtIndex:(((theFontSizes_Headings_withoutSingles's |count|()) as integer) - 1)) as real
set theGroupLevelDictionary to current application's NSMutableDictionary's new()
end if
end if
set theMainGroup_Name to theRecord_Name
if createScriptSettingsGroup then
set theNumberFormatter to current application's NSNumberFormatter's new()
theNumberFormatter's setMaximumFractionDigits:2
theNumberFormatter's setMinimumFractionDigits:2
set theMainGroup_Name to theMainGroup_Name & " [Split at Font Sizes ≥ " & ((theNumberFormatter's stringFromNumber:theFontSize_HeadingMin) as string) & " (Ratio " & theRatio_Heading & ") | joinHeadings = " & joinHeadings & " | dontCreateHeadingOnlyRecord = " & dontCreateHeadingOnlyRecord
if createGroups then set theMainGroup_Name to theMainGroup_Name & " | dontGroupLastLevel = " & createGroups_dontGroupLastLevel
set theMainGroup_Name to theMainGroup_Name & "]"
end if
tell application id "DNtp"
if createScriptSettingsGroup then
set theContainerGroup to create record with {name:theMainGroup_Name, type:group} in location group of theRecord
set theContainerGroup_UUID to uuid of theContainerGroup
set {theMainGroup, theMainGroup_UUID} to my createGroupInGroupWithUUID(theContainerGroup_UUID, theRecord_Name)
else
set theMainGroup to create record with {name:theMainGroup_Name, type:group} in parent 1 of theRecord
set theMainGroup_UUID to uuid of theMainGroup
end if
if createGroups and createSmartGroup then create record with {type:smart group, search predicates:"{any: kind:rtf kind:group}", name:"{any: kind:rtf kind:group} in: " & theRecord_Name, search group:theMainGroup} in theMainGroup
end tell
repeat with i from 0 to ((theSubstringRanges's |count|()) - 1)
set thisItem to (theSubstringRanges's objectAtIndex:i)
set thisName to (thisItem's valueForKey:"FirstLine") as string
if createGroups then
set thisFontSize to (thisItem's valueForKey:"FontSize")
set thisHeadingLevel to ((theFontSizes_Headings_withoutSingles's indexOfObject:thisFontSize) as integer) + 1
if thisHeadingLevel = 1 then
set {thisGroup, thisGroup_UUID} to my createGroupInGroupWithUUID(theMainGroup_UUID, thisName)
(theGroupLevelDictionary's removeObjectsForKeys:(theGroupLevelDictionary's allKeys()))
(theGroupLevelDictionary's setObject:{GroupLevel:thisHeadingLevel, UUID:thisGroup_UUID, GroupName:thisName} forKey:(thisHeadingLevel as string))
else if thisHeadingLevel > 1 then
set thisGroup_UUID to (theGroupLevelDictionary's valueForKeyPath:(((thisHeadingLevel - 1) as string) & ".UUID"))
if thisGroup_UUID = missing value then
repeat with j from 1 to thisHeadingLevel
set thisGroup_UUID to (theGroupLevelDictionary's valueForKeyPath:(((thisHeadingLevel - j) as string) & ".UUID"))
if thisGroup_UUID ≠ missing value then exit repeat
end repeat
end if
if thisGroup_UUID = missing value then set thisGroup_UUID to theMainGroup_UUID
set thisGroup_UUID to thisGroup_UUID as string
if thisFontSize as real ≥ theFontSize_GroupingMin then
set {thisGroup, thisGroup_UUID} to my createGroupInGroupWithUUID(thisGroup_UUID, thisName)
(theGroupLevelDictionary's setObject:{GroupLevel:thisHeadingLevel, UUID:thisGroup_UUID, GroupName:thisName} forKey:(thisHeadingLevel as string))
else
tell application id "DNtp" to set thisGroup to get record with uuid thisGroup_UUID
end if
end if
else
set thisGroup to theMainGroup
end if
if ((thisItem's valueForKey:"createRecord") as boolean) then
set {thisAttributedString, thisTempURL} to my writeAttributedStringToTempFile(theAttributedString, (thisItem's valueForKey:"Range"), theTempDirectoryURL)
set thisTempPath to (thisTempURL's |path|()) as string
tell application id "DNtp" to import thisTempPath name thisName to thisGroup
end if
end repeat
set {successDeleteDir, theError} to (current application's NSFileManager's defaultManager()'s removeItemAtURL:(theTempDirectoryURL) |error|:(reference))
if theError ≠ missing value then error (theError's localizedDescription() as string)
tell application id "DNtp" to step progress indicator
tell application id "DNtp" to hide progress indicator
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"splitRTFDatFontSizes\"" message error_message as warning
try
current application's NSFileManager's defaultManager()'s removeItemAtURL:(theTempDirectoryURL) |error|:(missing value)
end try
error number -128
end try
end splitRTFDatFontSizes
on readAttributedString(thePath)
try
set {theAttributedString, theError} to current application's NSAttributedString's alloc()'s initWithURL:(current application's |NSURL|'s fileURLWithPath:thePath) options:(missing value) documentAttributes:({NSDocumentTypeDocumentAttribute:(current application's NSRTFDTextDocumentType)}) |error|:(reference)
if theError ≠ missing value then error (theError's localizedDescription() as string)
return theAttributedString
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"readAttributedString\"" message error_message as warning
error number -128
end try
end readAttributedString
on getFontSizesHeadingsWithoutSingles(theFontSizes_Headings, theAttributesArray)
try
set theArray to current application's NSMutableArray's new()
repeat with i from 0 to ((theFontSizes_Headings's |count|()) - 1)
set thisFontSize to (theFontSizes_Headings's objectAtIndex:i)
set thisAttributesArray_filtered to (theAttributesArray's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:("self.FontSize = " & thisFontSize)))
(theArray's addObject:{FontSize:thisFontSize, FirstLocation:(((thisAttributesArray_filtered's firstObject())'s valueForKeyPath:"FontRange.location")), Occurrences:(thisAttributesArray_filtered's |count|())})
end repeat
set theArray_sortedByFirstLocation to (theArray's sortedArrayUsingDescriptors:{(current application's NSSortDescriptor's sortDescriptorWithKey:"FirstLocation" ascending:true selector:"compare:")})
set theRemoveArray to current application's NSMutableArray's new()
repeat with i from 0 to ((theArray_sortedByFirstLocation's |count|()) - 1)
set thisItem to (theArray_sortedByFirstLocation's objectAtIndex:i)
set thisFontSize to (thisItem's valueForKey:"FontSize") as real
set thisFontSize_Occurrences to (thisItem's valueForKey:"Occurrences") as integer
if thisFontSize_Occurrences = 1 then
repeat with j from (i + 1) to ((theArray_sortedByFirstLocation's |count|()) - 1)
set thatFontSize to ((theArray_sortedByFirstLocation's objectAtIndex:j)'s valueForKey:"FontSize") as real
if thisFontSize < thatFontSize then
(theRemoveArray's addObject:thisItem)
exit repeat
end if
end repeat
end if
end repeat
set theArray_sortedByFontSize to (theArray's sortedArrayUsingDescriptors:{(current application's NSSortDescriptor's sortDescriptorWithKey:"FontSize" ascending:false selector:"compare:")})'s mutableCopy()
theArray_sortedByFontSize's removeObjectsInArray:theRemoveArray
set theFontSizes_Headings_withoutSingles to theArray_sortedByFontSize's valueForKey:"FontSize"
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"getFontSizesHeadingsWithoutSingles\"" message error_message as warning
error number -128
end try
end getFontSizesHeadingsWithoutSingles
on createTempDirectory()
try
set theTempDirectoryURL to current application's |NSURL|'s fileURLWithPath:((current application's NSTemporaryDirectory())'s stringByAppendingPathComponent:("Script Split RTFD at Font Sizes" & space & (current application's NSProcessInfo's processInfo()'s globallyUniqueString())))
set {successCreateDir, theError} to current application's NSFileManager's defaultManager's createDirectoryAtURL:theTempDirectoryURL withIntermediateDirectories:false attributes:(missing value) |error|:(reference)
if theError ≠ missing value then error (theError's localizedDescription() as string)
return theTempDirectoryURL
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"createTempDirectory\"" message error_message as warning
error number -128
end try
end createTempDirectory
on writeAttributedStringToTempFile(theAttributedString, theRange, theTempDirectoryURL)
try
set thisAttributedString to (theAttributedString's attributedSubstringFromRange:theRange)
set thisAttributedString_Range to {location:0, |length|:thisAttributedString's |length|()}
if (thisAttributedString's containsAttachmentsInRange:thisAttributedString_Range) then
set thisFileWrapper to (thisAttributedString's RTFDFileWrapperFromRange:thisAttributedString_Range documentAttributes:{NSDocumentTypeDocumentAttribute:(current application's NSRTFDTextDocumentType)})
set thisTempURL to ((theTempDirectoryURL's URLByAppendingPathComponent:(current application's NSProcessInfo's processInfo()'s globallyUniqueString()))'s URLByAppendingPathExtension:"rtfd")
set {successWrite, theError} to (thisFileWrapper's writeToURL:thisTempURL options:(current application's NSFileWrapperWritingAtomic) originalContentsURL:(missing value) |error|:(reference))
else
set thisData to (thisAttributedString's RTFFromRange:(thisAttributedString_Range) documentAttributes:{NSDocumentTypeDocumentAttribute:(current application's NSRTFTextDocumentType)})
set thisTempURL to ((theTempDirectoryURL's URLByAppendingPathComponent:(current application's NSProcessInfo's processInfo()'s globallyUniqueString()))'s URLByAppendingPathExtension:"rtf")
set {successWrite, theError} to (thisData's writeToURL:thisTempURL options:(current application's NSDataWritingAtomic) |error|:(reference))
end if
if theError ≠ missing value then error (theError's localizedDescription() as string)
return {thisAttributedString, thisTempURL}
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"writeAttributedStringToTempFile\"" message error_message as warning
error number -128
end try
end writeAttributedStringToTempFile
on createGroupInGroupWithUUID(theParentGroup_UUID, theNewGroup_Name)
try
tell application id "DNtp"
set theParentGroup to get record with uuid theParentGroup_UUID
set theNewGroup to create record with {name:theNewGroup_Name, type:group} in theParentGroup
set theNewGroup_UUID to uuid of theNewGroup
return {theNewGroup, theNewGroup_UUID}
end tell
on error error_message number error_number
activate
if the error_number is not -128 then display alert "Error: Handler \"createGroupInGroupWithUUID\"" message error_message as warning
error number -128
end try
end createGroupInGroupWithUUID