--Applescript direct -- Script that improves on the TeXShop default macro called "Root", -- i.e., %!TEX root = #INS# -- by letting the user choose which root document she/he wants to use -- (as a relative or absolute path), -- deleting the first old (if any) root command, -- inserting the command at the beginning of the document, and -- restoring the original selection. -- Ramon Figueroa-Centeno (March 10, 2009) -- http://www2.hawaii.edu/~ramonf -- History: -- 1.1: March 18, 2009 -- Added code to respect first lines that start with "%&" -- What is the default choice: relative or not relative (i.e. absolute) property relative : true tell application "TeXShop" try path of the front document set TeX_path to the result on error -- there is no front document or it has not ever been saved beep display dialog "there is no front document" & return & "or it has not been saved ever!" buttons {"Ok"} default button "Ok" with icon caution giving up after 5 return end try set TeX_path to do shell script "dirname " & quoted form of TeX_path -- Get the absolute path to the Root document try set Root_abs_path to POSIX path of (choose file with prompt "Pick the Root document:") on error return end try -- Use perl to convert the absolute path to the Root document -- to a relative path to it. set command to "perl -e 'use File::Spec; " set command to command & "$rel_path = File::Spec->abs2rel" set command to command & "( \"" & Root_abs_path & "\"," set command to command & "\"" & TeX_path & "\" ) ; " set command to command & "print $rel_path'" tell me to set Root_rel_path to do shell script command if relative then set i to 1 else set i to 2 end if set roots to {Root_rel_path, Root_abs_path} set the root to choose from list roots with prompt "Choose between a relative and absolute path:" default items item i of roots OK button name "OK" cancel button name "Cancel" without multiple selections allowed and empty selection allowed if the result is false then return end if -- The linefeed character set linefeed to ASCII character 10 -- The whole text of the document set whole_document to (the text of the front document) as string -- The offset of the selection set selection_offset to offset of the selection of the front document -- The length of the selection set selection_length to length of the selection of the front document -- Find and delete a previous encoding specification -- (it will not handle more than one specification) set searchString1 to "%!TEX root =" set search1 to (search for searchString1 starting from 0) of front document set searchString2 to "% !TEX root =" set search2 to (search for searchString2 starting from 0) of front document if search1 * search2 > 0 then if search1 < search2 then set first_occurrence to search1 else set first_occurrence to search2 end if else if search1 > 0 then set first_occurrence to search1 else set first_occurrence to search2 end if if first_occurrence > 0 then set offset of selection of front document to (first_occurrence - 1) -- Get the offset of the line feed (or eof) ending the line containing "%!TEX root =" -- (here we use a "try" statement to avoid needing to have a saved file -- from which we could get the "eof") set i to first_occurrence set end_of_file to false set char to character i of whole_document repeat while char is not in {linefeed, return} set i to i + 1 try set char to character i of whole_document on error set end_of_file to true exit repeat end try end repeat -- Detect if the line starts with "% !TEX root =" and it is not the last line, -- if so we will delete not only "% !TEX root =..." but the whole line if ((first_occurrence = 1) or (character (first_occurrence - 1) of whole_document is in {linefeed, return})) and not end_of_file then set i to i + 1 end if set length of selection of front document to (i - first_occurrence) -- Delete the line set the content of the selection of the front document to "" -- We restore the selection the user had before invoking this script -- so we compute what the new selection_offset should be. if (selection_offset ≥ first_occurrence - 1) and (selection_offset < i - 1) then set selection_offset to first_occurrence - 1 set selection_length to 0 else if selection_offset ≥ i - 1 then set selection_offset to selection_offset - (i - first_occurrence) end if end if set program to "% !TEX root = " & root & linefeed set selection_offset to selection_offset + (count of program) -- If the first line starts with "%&" set the insertion offset -- to the beginning of the second line. try set first_line to paragraph 1 of the text of the front document as string if the first_line starts with "%&" then set insertion_offset to count the characters of the first_line try get paragraph 2 of the text of the front document on error -- There is only one line? set selection_offset to selection_offset + 1 set program to linefeed & program end try else set insertion_offset to 0 end if on error -- The document was empty? set insertion_offset to 0 end try -- Insert Root set offset of the selection of the front document to insertion_offset set length of the selection of the front document to 0 set content of the selection of the front document to program -- Restore the offset of the selection set offset of the selection of the front document to selection_offset -- Restore the length of the selection set length of the selection of the front document to selection_length end tell