You can have the errors reported by piping the output from the call to
pdflatex
into some command line tool. Exactly what tool to use is less clear. The natural choice for SubEthaEdit would be the see
command line too, but it's not very convenient, and has some real problems. Beyond that, calling out to see
repeatedly will produce a new window each time, which is just annoying.The Python mode has a nicer behavior. It has a Check Syntax command that always writes to a window named Python Check Syntax, opening it if need be or overwriting the contents otherwise. The Lua mode has an analogous Check Syntax command with similar behavior.
Let's make a shell script that does something similar. First, I encapsulate the relevant bits of AppleScript from the Python and Lua modes into some simple handlers. Second, I embed those into a shell script using the approach recently discussed here. The resulting script I call
seeless
, as it is usable as something like the less
pager. I'll defer the text of the script until the end, first describing the usage.Basic usage is just to pipe in some text:
echo Hello World! | seeless
This writes the text Hello World into a SubEthaEdit window titled seeless message, opening a new window if necessary or replacing the text in an existing window. Multiple windows with the same title are a bit problematic, with no guarantee that the window you want will be the one written to. Don't do that.
The title of the window can be specified:
echo Hello World! | seeless -t"A message for you, direct from the shell"
Appropriate choice of title allows a SubEthaEdit mode to establish its own reporting window.
The window is normally brought to the front when it is written to. Call
seeless
asecho Hello World! | seeless -b
to leave the window in the background. This allows, e.g., a reporting window to be kept out of the way as a tab and only checked when something seems to be wrong.
There are two different modes, insert and append, for writing to the window. For insert mode, the window is cleared before writing the text from
stdin
, while append mode just appends to any existing text. To set append more, use:echo Hello World! | seeless -a
Insert mode is the default, but a flag exists for it, too:
echo Hello World! | seeless -i
Multiple flags for the insert and append mode can be given, with the final one determining the behavior.
In append mode, the text from a second call to
seeless
follows immediately after the text from the first. To give some visual space, specify a separator:echo Hello World! | seeless -s"----------"
When a separator is given with the
-s
flag, append mode is automatically set. It is also possible to use a separator in insert mode, giving a form of header. For example,echo Hello World! | seeless -s"$(date)" -i
shows the time when
seeless
was called. Another possibility would be to have a cluster of related programs writing to the same window, and using the separator to specify the program that wrote the latest text.Let's take a look at how I put those options into use with the LaTeX mode. I set
SEE_BIBTEX
to: 'bibtex "${FILE%.tex}" | "$HOME/Library/bin/seeless" -t"LaTeX Messages" -s"bibtex ran at $(date)\n" -b -i &> /dev/null &'
SEE_LATEX_CLEANUP
to: 'latexmk -C "$FILE" | "$HOME/Library/bin/seeless" -t"LaTeX Messages" -s"latexmk -C ran at $(date)\n" -b -i &> /dev/null &'
and SEE_LATEX_COMPILER
to: 'latexmk -pdf -quiet "$FILE" | "$HOME/Library/bin/seeless" -t"LaTeX Messages" -s"latexmk ran at $(date)\n" -b -i &> /dev/null &'
Note that I have redirected the output of each call to seeless
to /dev/null
and made the calls asynchronous with &
—SubEthaEdit hangs without doing this, requiring a force quit.With the above settings, the LaTeX mode will cause SubEthaEdit to open up a report window titled LaTeX Messages whenever a document is typeset,
bibtex
is run, or the auxiliary files are cleaned up. I can put it out of the way, either as a tab or background document; because I've used the -b
flag for each call, the report window will stay out of the way until I want it brought to the front. I've used a separator to show which feature was most recently used and at what time it was called. I've set insert mode with an -i
flag, so I only see the latest call; by eliminating this flag, I'd have a chronological record of all the calls made (in the current editing session, anyway).I haven't been using this very long, so there may be some bugs. However, it seems quite solid, and is definitely useful already. Download it here.
As promised above, I'll give the text of the script here, too. I've formatted the script as a shell script, to better show how the shell variables are used to adapt the behavior of the embedded AppleScript.
#!/bin/sh
# Writes stdin to a SubEthaEdit document, modifying the contents if the
# document already exists. Document is selected by title, with a default
# title of 'seeless'. Title can be specified with a '-t' flag. If there
# are multiple documents with the given title, one is chosen arbitrarily.
#
# Writing to the document occurs in two modes, insert and append. With
# insert mode, the document is cleared before any text is written to
# it. In append mode, any existing text is maintained, with the new
# text appended at the end. By giving an '-a' flag, append mode is set.
# Giving an '-i' flag sets insert mode; insert mode is the default.
#
# A separator can be specified. The separator is written to the
# document before the text from stdin. Specifying a separator also sets
# append mode (but this can be turned off again if desired with an '-i'
# flag). The separator is specified with an '-s' flag; the argument
# following the flag is used as the separator.
#
# Giving an '-h' flag shows a usage summary. Any other flags are ignored.
#
#$Id: seeless.sh,v 1.9 2008/04/12 20:33:56 mjb Exp $
# Copyright (c) 2008, Michael J. Barber
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject
# to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
PROGRAM=$(basename $0)
usage()
{
echo "Usage: $PROGRAM [-ahi] [-t title] [-s separator]"
}
title="$PROGRAM message"
shouldClear=true
shouldSeparate=false
shouldBringToFront=true
separator="----------"
while getopts :t:ias:bh opt
do
case $opt in
t) title="$OPTARG"
;;
i) shouldClear=true
;;
a) shouldClear=false
;;
s) separator="$OPTARG"
shouldSeparate=true
shouldClear=false
;;
b) shouldBringToFront=false
;;
h) usage
exit 0
;;
'?') echo "$PROGRAM: invalid option -$OPTARG" >&2
usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
/usr/bin/osascript > /dev/null <<ASCPT
set newContents to "$(cat | sed -e 's/\\/\\\\/g' -e 's/\"/\\\"/g')"
set seeDoc to (ensureSEEDocumentExists for "$title")
if $shouldClear then
replaceContents for the seeDoc by ""
end if
if $shouldSeparate then
extendContents for the seeDoc by the "$separator"
end if
extendContents for the seeDoc by the newContents
if $shouldBringToFront then
tell application "SubEthaEdit" to show the seeDoc
end if
to ensureSEEDocumentExists for doctitle
tell application "SubEthaEdit"
if exists document named doctitle then
document named doctitle
else
make new document with properties {name:doctitle}
end if
end tell
end ensureSEEDocumentExists
to replaceContents for seeDoc by newContents
tell application "SubEthaEdit"
set the contents of seeDoc to newContents
clear change marks of seeDoc
try
set modified of seeDoc to false
end try
end tell
end replaceContents
to extendContents for seeDoc by moreContents
tell application "SubEthaEdit"
if "" is not equal to the contents of the last paragraph of seeDoc then
set the contents of the last insertion point of the last paragraph of seeDoc to return
end if
set the contents of the last insertion point of the last paragraph of seeDoc to moreContents
clear change marks of seeDoc
try
set modified of seeDoc to false
end try
end tell
end extendContents
ASCPT
# Writes stdin to a SubEthaEdit document, modifying the contents if the
# document already exists. Document is selected by title, with a default
# title of 'seeless'. Title can be specified with a '-t' flag. If there
# are multiple documents with the given title, one is chosen arbitrarily.
#
# Writing to the document occurs in two modes, insert and append. With
# insert mode, the document is cleared before any text is written to
# it. In append mode, any existing text is maintained, with the new
# text appended at the end. By giving an '-a' flag, append mode is set.
# Giving an '-i' flag sets insert mode; insert mode is the default.
#
# A separator can be specified. The separator is written to the
# document before the text from stdin. Specifying a separator also sets
# append mode (but this can be turned off again if desired with an '-i'
# flag). The separator is specified with an '-s' flag; the argument
# following the flag is used as the separator.
#
# Giving an '-h' flag shows a usage summary. Any other flags are ignored.
#
#$Id: seeless.sh,v 1.9 2008/04/12 20:33:56 mjb Exp $
# Copyright (c) 2008, Michael J. Barber
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject
# to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
PROGRAM=$(basename $0)
usage()
{
echo "Usage: $PROGRAM [-ahi] [-t title] [-s separator]"
}
title="$PROGRAM message"
shouldClear=true
shouldSeparate=false
shouldBringToFront=true
separator="----------"
while getopts :t:ias:bh opt
do
case $opt in
t) title="$OPTARG"
;;
i) shouldClear=true
;;
a) shouldClear=false
;;
s) separator="$OPTARG"
shouldSeparate=true
shouldClear=false
;;
b) shouldBringToFront=false
;;
h) usage
exit 0
;;
'?') echo "$PROGRAM: invalid option -$OPTARG" >&2
usage >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
/usr/bin/osascript > /dev/null <<ASCPT
set newContents to "$(cat | sed -e 's/\\/\\\\/g' -e 's/\"/\\\"/g')"
set seeDoc to (ensureSEEDocumentExists for "$title")
if $shouldClear then
replaceContents for the seeDoc by ""
end if
if $shouldSeparate then
extendContents for the seeDoc by the "$separator"
end if
extendContents for the seeDoc by the newContents
if $shouldBringToFront then
tell application "SubEthaEdit" to show the seeDoc
end if
to ensureSEEDocumentExists for doctitle
tell application "SubEthaEdit"
if exists document named doctitle then
document named doctitle
else
make new document with properties {name:doctitle}
end if
end tell
end ensureSEEDocumentExists
to replaceContents for seeDoc by newContents
tell application "SubEthaEdit"
set the contents of seeDoc to newContents
clear change marks of seeDoc
try
set modified of seeDoc to false
end try
end tell
end replaceContents
to extendContents for seeDoc by moreContents
tell application "SubEthaEdit"
if "" is not equal to the contents of the last paragraph of seeDoc then
set the contents of the last insertion point of the last paragraph of seeDoc to return
end if
set the contents of the last insertion point of the last paragraph of seeDoc to moreContents
clear change marks of seeDoc
try
set modified of seeDoc to false
end try
end tell
end extendContents
ASCPT
No comments:
Post a Comment