--Applescript direct

-- Script that a format specification to the document, e.g. %&pdflatex
-- by letting the user choose which format she/he wants to use,
-- deleting the first old (if any) format command,
-- inserting the command at the beginning of the document, and
-- restoring the original selection.
-- Ramon Figueroa-Centeno (March 29, 2009)
-- http://www2.hawaii.edu/~ramonf

-- The script will try to find kpsewhich if it can't find it it will look here
-- TIP: type 
--  which kpsewhich
-- in the Terminal to find what this path should be for you
property kpsewhich_path : "/usr/texbin/kpsewhich"

-- If you wish you can change this so that your favorite format is the default choice
property default_fmt : "pdflatex"

-- The list of available formats is quite long, so you have the option
-- of only including a few.
property few : false

-- If above "few" is true or the script fails to build its own list
-- (because, for example, the script can't find kpsewhich),
-- then this is the list from which the format names will be chosen.
-- TIP: type 
--  fmtutil --listcfg | awk '/^[^#].*/ {print $1}'
-- in the Terminal to get a full list of available formats.
property short_list : {"pdflatex", "cont-en", "pdftex", "xelatex", "xetex"}

tell application "TeXShop"
	
	if few then
		tell me to set formats to {"<none>"} & sort(short_list)
	else
		try
			set FILEPATH to path of the front document
			tell me to set dirname to do shell script "dirname " & quoted form of FILEPATH
		on error -- Is this document saved?
			set dirname to ""
		end try
		
		-- Get a sorted list of the installed formats
		tell me
			
			set formats to short_list
			
			-- Look for formats in the directory of the front document.
			if dirname is not "" then
				try
					set command to "ls " & quoted form of dirname
					set command to command & " | grep .fmt$ | sed 's/\\.fmt$//'"
					set formats to formats & paragraphs of (do shell script command)
				end try
			end if
			
			-- Try to find kpsewhich
			try
				set kpsewhich to do shell script "which kpsewhich"
			on error
				-- Probably PATH in the ~/.MacOSX/environment.plist does not contain
				-- the path to kpsewhich, so we assume it is in kpsewhich_path
				set kpsewhich to kpsewhich_path
			end try
			
			-- Get the paths where kpsewhich looks for formats
			try
				set oldDelims to AppleScript's text item delimiters -- save their current state
				set AppleScript's text item delimiters to {":"} -- declare new delimiters
				set raw_paths to every text item of ((do shell script kpsewhich & " -show-path=.fmt") as text)
				set AppleScript's text item delimiters to oldDelims -- restore them
			on error -- restore them in case something went wrong
				set AppleScript's text item delimiters to oldDelims
				set raw_paths to {}
				--say "no paths found"
			end try
			
			-- Get the paths where to look for formats
			set search_paths to {}
			repeat with p in raw_paths
				if p as string is not "." then
					if p starts with "!!" then
						try
							set search_paths to search_paths & {text 3 through -1 of p}
						end try
					else
						set search_paths to search_paths & {p}
					end if
				end if
			end repeat
			
			repeat with p in search_paths
				try
					set command to "find \"" & p & "\" -name *.fmt -exec basename {} .fmt \\;"
					set formats to formats & paragraphs of (do shell script command)
				end try
			end repeat
			
			set formats to {"<none>"} & sort(formats)
			
		end tell
	end if
	
	-- Figure out which is the index of "default_fmt" in the "formats" list
	if default_fmt is in formats then
		repeat with i from 1 to count of formats
			if item i of formats is default_fmt then
				exit repeat
			end if
		end repeat
	else
		-- If  "default_fmt" is not among the formats then choose first format in the list
		set i to 1
	end if
	
	set the fmt to choose from list formats with prompt "Pick a format:" default items item i of formats 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
	
	if fmt contains "<none>" then
		set fmt to ""
	else
		set fmt to "%&" & (fmt) & linefeed
		
	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 fmt specification
	
	set searchString to "%&"
	set first_occurrence to (search for searchString starting from 0) of the front document
	
	-- First line of the document
	set first_line to paragraph 1 of the text of the front document as string
	
	set i to count of first_line
	-- If the length of the first line is greater than the offset of the first ocurrence,
	-- i.e., the first ocurrence is in the first line, then
	if i > first_occurrence and first_occurrence > 0 then
		set offset of selection of front document to 0
		set length of selection of front document to count of the first_line
		-- Delete the first line
		set the content of the selection of the front document to ""
		
		-- We will try to 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
		set selection_offset to selection_offset - 1
	end if
	
	--set program to fmt 
	set selection_offset to selection_offset + (count of (fmt))
	
	-- Insert Format
	set offset of the selection of the front document to 0
	set length of the selection of the front document to 0
	set content of the selection of the front document to fmt
	
	-- 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

(* 
http://www.macosxhints.com/article.php?story=20040513173003941
Sort lists in AppleScript using the Unix sort command
Mon, May 17 '04 at 09:13AM • from: erickaterman *)
on sort(the_list)
	set old_delims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {ASCII character 10} -- always a linefeed
	set list_string to (the_list as string)
	set new_string to do shell script "echo " & quoted form of list_string & " | sort -f -u"
	set new_list to (paragraphs of new_string)
	set AppleScript's text item delimiters to old_delims
	return new_list
end sort