--Applescript direct
-- Script to insert a begin/end block
-- Ramon Figueroa-Centeno March 10, 2009

tell application "TeXShop"
	
	-- The linefeed character.
	set linefeed to ASCII character 10
	
	set TeX_delimiters to {linefeed, return, tab} & characters of ¬
		" {}[](),:;.\\|/?!<>`'\"@#$%^~&-+=" as list
	
	set the front_document to the front document
	-- set the front_document to document #DOCUMENTNAME#
	
	-- 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
	
	repeat until (selection_offset = 0) or (character selection_offset of ¬
		the whole_document is in TeX_delimiters)
		set selection_offset to selection_offset - 1
	end repeat
	set the offset of the selection of the front_document to selection_offset
	
	set selection_length to 0
	
	try
		set next_character to character (selection_offset + selection_length + 1) of ¬
			the whole_document
		repeat until (next_character is in TeX_delimiters)
			set selection_length to selection_length + 1
			try
				set next_character to character (selection_offset + selection_length + 1) of ¬
					the whole_document
			on error
				-- reached the end of the document
				exit repeat
			end try
		end repeat
	end try
	set the length of the selection of the front_document to selection_length
	
	-- The selection is empty, so stop
	if selection_length = 0 then
		beep
		return
	end if
	
	set environment_name to the content of the selection of the front_document
	set begin_environment to "\\begin{" & environment_name & "}"
	set end_environment to "\\end{" & environment_name & "}"
	set environment to begin_environment & linefeed & " " & linefeed & end_environment
	set insertion_point to (count of begin_environment) + selection_offset + 3
	
	-- determine if we are the beginning of a line
	set at_the_beginning to ((selection_offset = 0) or (character selection_offset of ¬
		the whole_document is in {linefeed, return}))
	
	-- determine if we are at the end of a line
	-- (since we do not know if we are at the end of the document
	-- we use a "try" to avoid having to count the characters of the document)
	set at_the_end to false
	try
		if character (selection_offset + selection_length + 1) of ¬
			the whole_document is in {linefeed, return} then
			set at_the_end to true
		end if
	on error
		set at_the_end to true
	end try
	
	if at_the_beginning and at_the_end then
		-- say "at the beginning and the end"
		set the content of the selection of the front_document to ¬
			environment
		set the offset of the selection of the front_document to ¬
			insertion_point - 1
	else if at_the_beginning then
		-- say "at the beginning"
		set the content of the selection of the front_document to ¬
			environment & linefeed
		set the offset of the selection of the front_document to ¬
			insertion_point
	else if at_the_end then
		-- say "at the end"
		set the content of the selection of the front_document to ¬
			linefeed & environment
		set the offset of the selection of the front_document to ¬
			insertion_point
	else
		-- say "at the middle"
		set the content of the selection of the front_document to ¬
			linefeed & environment & linefeed
		set the offset of the selection of the front_document to ¬
			insertion_point
	end if
end tell