summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/tcldoc/dtxload.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/tcldoc/dtxload.dtx')
-rw-r--r--Master/texmf-dist/source/latex/tcldoc/dtxload.dtx1256
1 files changed, 1256 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/tcldoc/dtxload.dtx b/Master/texmf-dist/source/latex/tcldoc/dtxload.dtx
new file mode 100644
index 00000000000..f68a0ca3a8b
--- /dev/null
+++ b/Master/texmf-dist/source/latex/tcldoc/dtxload.dtx
@@ -0,0 +1,1256 @@
+%
+%
+% \iffalse Meta-comment
+%
+%<*driver>
+\documentclass{tcldoc}
+
+\DeclareRobustCommand{\package}[1]{\textsf{#1}}
+\newcommand{\Alpha}{\textit{Alpha}}
+\newcommand{\AlphaTk}{\textit{Alphatk}}
+
+\PageIndex
+\setcounter{IndexColumns}{2}
+\CodelineNumbered
+\RecordChanges
+\IndexPrologue{\section*{Index}\markboth{Index}{Index}%
+ Numbers written in italic refer to the page where
+ the corresponding entry is described; numbers underlined refer
+ to the definition; numbers in roman refer to the pages where
+ the entry is used.}
+\expandafter\def \expandafter\GlossaryParms \expandafter{\GlossaryParms
+ \hbadness=10000\emergencystretch=2cm}
+
+\begin{document}
+\DocInput{dtxload.dtx}
+\PrintChanges
+\PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \title{\package{dtxload} --- loading \Tcllogo\ code directly from
+% \texttt{.dtx} source files}
+% \author{Lars Hellstr\"om^^A
+% \thanks{E-mail: \texttt{Lars.Hellstrom@math.umu.se}}}
+% \date{December 20, 2000}
+% \maketitle
+%
+% \begin{abstract}
+% \package{dtxload} is a feature for the text editor \Alpha. It
+% implements a command for loading a piece of \Tcllogo\ code directly
+% from a \texttt{.dtx} file.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Usage}
+%
+% \subsection{About \Alpha}
+%
+% About \Alpha\ itself, the \Alpha~v\,7.3 manual says the following:
+% \begin{quotation}
+% \Alpha\ is a very powerful, multi-purpose text editor.
+% \Alpha\ is multi-modal, which means it switches between different
+% modes depending on which type of document you are editing. Everybody
+% who has used Emacs knows about this concept. The idea with different
+% modes is to change \Alpha's behaviour depending on which kind of text
+% you're editing. For example if you're programming in C$^{++}$ or
+% editing a \LaTeX\ document you want different features.
+%
+% \Alpha\ is very customizable. Much of \Alpha's functionality is
+% implemented in `packages' or `extensions'. [\dots]
+% \Alpha\ uses Dr.~Ousterhout's \emph{Tool Command Language} (\Tcllogo) as
+% an extension language. Many of the functions bound to keystrokes,
+% as well as many of the functions in the menus, are written in \Tcllogo.
+% All the `packages' or `extensions' just mentioned are all written
+% in \Tcllogo. Anybody who wants can write new packages for \Alpha!
+%
+% Of course, you don't have to learn \Tcllogo\ to use \Alpha. You can
+% have lots of use of \Alpha\ without knowing anything about \Tcllogo.
+% But if you want to become a real power user, you should consider
+% trying it out. Then the possibilities of customizing \Alpha\ are
+% unlimited.
+% \end{quotation}
+% Originally \Alpha\ only existed on the \mbox{MacOS} platform, but
+% recently the program was rewritten in Tk.\footnote{Tk is an extension of
+% \Tcllogo\ which includes GUI support.} In that form (which is called
+% \AlphaTk), \Alpha\ can be run on any platform for which there exists
+% a port of Tk!
+%
+% \medskip
+%
+% There are also some \Alpha-related URLs which should be mentioned.
+% \Alpha's official home page is~\cite{AlphaHome}, but it is currently
+% rather out-of-date. More recent information can be found on
+% e.g.~\cite{DocScriptingAlpha}, which also has links to many other
+% \Alpha-related sites. The home page for \AlphaTk\ is~\cite{Alphatk}.
+%
+%
+%
+% \subsection{Installation}
+%
+% To install \package{dtxload} as an \Alpha\ feature, you first \LaTeX\
+% the file \texttt{dtxload.ins}---this will generate a file
+% \texttt{dtxload.tcl}, which contains the \Tcllogo\ code for the
+% package in a form that \Alpha\ understands. Then follow the normal
+% procedure for installing an \Alpha\ package, i.e., open
+% \texttt{dtxload.tcl}\footnote{Which should be somewhere outside
+% \Alpha's directory subtree.} in \Alpha---this will trigger the
+% automatic installation dialog for the package and you proceed as
+% usual.
+%
+%
+% \subsection{Loading \Tcllogo\ code}
+% \label{Ssec:Loading}
+%
+% To load (evaluate) a piece of \Tcllogo\ code in a \texttt{.dtx}
+% document, simply select that code and press \marginpar{Loading code:
+% \textsf{Cmd--L}}Command--L. The commands are evaluated one by one and
+% the result of each command will be shown at the current log destination
+% (by default the status line, but that can be changed). In case one of
+% the commands return with an error, that error will be shown as well,
+% evaluation of further commands is cancelled, and the insertion point is
+% moved to the beginning of the erroneous command. Furthermore the mark
+% will be left at the end of the selection, so that the part of the
+% original selection which has not yet been successfully evaluated can
+% easily be reselected using the \textsf{Mark Hilite} command.
+%
+% Loading \Tcllogo\ code does not necessary mean all text in the
+% selection will be evaluated; only extractable code will be passed on
+% to the \Tcllogo\ interpreter. There are several factors which affect
+% whether a piece of text is extractable code or not, but the foremost
+% is that text on \package{docstrip} comment lines (i.e., lines which
+% begin by a `|%|' that is not immediately followed by a `|<|') is
+% \emph{not} extractable code. Secondly, if the selection contains a
+% \package{docstrip} guard line which marks the start of a module then
+% \package{dtxload} will ask you whether you want the code in that
+% module to be loaded. If you answer no, it naturally won't be.
+%
+% Thus far the factors which may restrict which text is extractable
+% code correspond exactly to what the \package{docstrip}
+% program~\cite{docstrip} might do when generating a file of extracted
+% code, but \package{dtxload} has two additional mechanisms which may
+% categorize text as ``not extractable code''. Both are however
+% controlled by preferences in the \Alpha\ \TeX\ mode, so they can be
+% switched off if you don't like them.
+% The first is the \describestring[var.][]{onlyLoadDtxFiles}
+% \textsf{Only Load Dtx Files} preference, which when on restricts
+% loading to files with suffix \texttt{.dtx}. For \TeX\ files with other
+% suffixes I suspect that Command--L is pressed more often by accident
+% than because there actually is some \Tcllogo\ code that should be
+% loaded \textellipsis\space The second mechanism is controlled by the
+% \describestring[var.][]{onlyLoadTclEnvs} \textsf{Only Load Tcl Envs}
+% preference, which when on adds the restriction that extractable code
+% must appear inside a \texttt{tcl} or \texttt{tcl*} environment
+% (defined by the \package{tcldoc} \LaTeX\ package~\cite{tcldoc}). This
+% is primarily useful when a \texttt{.dtx} file contains both \Tcllogo\
+% code in \texttt{tcl} environments and code in some other language in
+% e.g.\ \texttt{macrocode} environments, since if the preference had been
+% off then \package{dtxload} would stop at the \package{docstrip} guard
+% that must appear at the beginning of each non-\Tcllogo\ code section
+% and ask whether the code should be included, whereas if it is on then
+% \package{dtxload} doesn't even have to ask whether the code in the
+% \texttt{macrocode} environments should be loaded.
+%
+% \medskip
+%
+% As an example of how the load \Tcllogo\ code command works, consider
+% the following code:
+% \DontCheckModules\iffalse
+%<*example>
+%<<EXAMPLE
+% \fi\begin{macrocode}
+% Text text text text text
+% \begin{tcl}
+set a A
+%<*andB>
+append a B
+%</andB>
+append a C
+%<*andD>
+append a D
+%</andB>
+expr $a
+string length $a
+% \end{tcl}
+% text text text.
+% \end{macrocode}\iffalse
+%EXAMPLE
+%</example>
+% \fi \CheckModules
+% If lines 1--7 above are selected and Command--L is pressed,
+% \package{dtxload} will display the message ``\texttt{Tcl eval OK}'' on
+% the status line and the following information will have been added to
+% the log.\footnote{This shows the window log format, but there are
+% other formats. Furthermore the `\texttt{<}' and `\texttt{>}' will
+% actually be guillemets in \Alpha\ (but not in \AlphaTk).}
+% \begin{trivlist}\item\small
+% |<dtxload> set a A|\\
+% |A|\\[\medskipamount]
+% |<dtxload> append a B|\\
+% |AB|\\[\medskipamount]
+% |<dtxload> append a C|\\
+% |ABC|
+% \end{trivlist}
+% The |<dtxload>| lines show the commands that were evaluated and the
+% lines after these contain the respective results of these commands.
+% Before the |append a B| command is evaluated, \package{dtxload} will
+% stop and ask
+% \begin{quote}
+% \textsf{Should \textless andB\textgreater\ modules be included?}
+% \end{quote}
+% In the case above the answer given was `Yes'; if it had been `No' then
+% the |append a B| command would neither be logged nor evaluated, and
+% the result of the |append a C| command would have been |AC|.
+%
+% If one continues by selecting lines 9--12 and pressing Command--L
+% then \package{dtxload} will display the message ``\texttt{Tcl eval
+% error}'' on the status line, the insertion point will be moved to the
+% beginning of line 11, and the following information will be found in
+% the log:
+% \begin{trivlist}\item\small
+% |<dtxload> append a D|\\
+% |ABCD|\\[\medskipamount]
+% |<dtxload> expr $a|\\
+% |Error: syntax error in expression "ABCD"|
+% \end{trivlist}
+% If then line 11 is changed to |expr {$a}| and lines 11--12 are again
+% selected (e.g. using \textsf{Mark Hilite}) and loaded then
+% \package{dtxload} will log:
+% \begin{trivlist}\item\small
+% |<dtxload> expr {$a}|\\
+% |ABCD|\\[\medskipamount]
+% |<dtxload> string length $a|\\
+% |4|
+% \end{trivlist}
+%
+% Finally, if lines 3--12 are selected and loaded then these are the
+% questions \package{dtxload} will ask:
+% \begin{itemize}
+% \item \textsf{Should \textless andB\textgreater\ modules be included?}
+% (Possible answers are `Yes' and `No'.)
+% \item \textsf{Should \textless andD\textgreater\ modules be included?}
+% (Possible answers are `Yes' and `No'.)
+% \item \textsf{Module nesting error: \textless*andD\textgreater\
+% module ended by \textless/andB\textgreater. For which
+% guards should the positions be pushed?}
+% (Possible answers are `None', `Start', `End', and `Both'.)
+% \end{itemize}
+% In the last case, \package{dtxload} has noticed that the guard
+% expressions that began (\textsf{andD}) and ended (\textsf{andB}) a
+% module are not equal (which is an error). Answering `Both' here will
+% push the positions of (the beginning of) both guard lines (8 and 10) onto
+% the bookmark stack so that they can easily be jumped to and corrected
+% later, but \package{dtxload} will continue evaluating the rest of the
+% selection after you answer.
+%
+%
+% \subsection{Selecting log destination}
+%
+% At startup, \package{dtxload} is logging results on the status line,
+% i.e., after a command has been evaluated it either displays the message
+% \begin{quote}
+% \texttt{Tcl eval OK:\ }\meta{result}
+% \end{quote}
+% or
+% \begin{quote}
+% \texttt{Tcl eval error:\ }\meta{error message}
+% \end{quote}
+% depending on whether the command returned an error or not. The
+% evaluation log can however be sent to a window instead.
+%
+% To set the destination for the log, one uses the procedure
+% \describestring[proc][dtxload]{logdest}|dtxload::logdest|. To set the
+% log destination to the window \word{win}, one gives the command
+% \begin{quote}
+% |dtxload::logdest window| \word{win}
+% \end{quote}
+% When the log destination is a window, the log shows the commands
+% that were evaluated as well as their result. If there is no window
+% named \word{win} then it is created. A slight
+% variation on this is the command
+% \begin{quote}
+% |dtxload::logdest shell| \word{win}
+% \end{quote}
+% which makes the \word{win} window a \Alpha\ \Tcllogo\ shell window if
+% it has to create it. When the log destination is a shell window, the
+% commands that are executed will be saved on the history list as well
+% as inserted in the window.
+%
+% A short form which may be convenient is
+% \begin{quote}
+% |dtxload::logdest here|
+% \end{quote}
+% which simply makes the current window the log destination. Finally,
+% the log destination is reset to the status line after the command
+% \begin{quote}
+% |dtxload::logdest status|
+% \end{quote}
+% Evaluation will also be logged on the status line if the log
+% destination window is closed.
+%
+%
+% \subsection{Other features and surprises}
+%
+% If nothing is selected when Command--L is pressed, \package{dtxload}
+% will continue as if all text was selected.
+%
+% Like \Alpha's \Tcllogo\ shell, \package{dtxload} can send the commands
+% to evaluate to a remote \Tcllogo\ interpreter rather than \Alpha's
+% built-in interpreter. In both cases the choice of target interpreter is
+% controlled by the global \Alpha\ variable
+% \describestring[var.][]{evaluateRemotely}|evaluateRemotely|. The
+% easiest way of changing this variable is via the \Tcllogo-tk submenu
+% of \Alpha's \Tcllogo\ menu.
+%
+% If the \textsf{Only Load Tcl Envs} preference is on and lines 4--6 in
+% the code example of Subsection~\ref{Ssec:Loading} are loaded then
+% \package{dtxload} will simply display the message
+% \begin{quote}
+% \texttt{No extractable code found.}
+% \end{quote}
+% The reason for this is that the first character of the selection is
+% a |%|; when the first character in the interval to load is a percent
+% character then \package{dtxload} will guess that this position is not
+% in a \texttt{tcl} or \texttt{tcl*} environment, and therefore it won't
+% try to extract any code until it has seen a comment line that contains
+% |\begin{tcl}| or |\begin{tcl*}|. You can always avoid making a
+% \package{docstrip} guard the first thing in the selection to load.
+%
+%
+%
+% \StopEventually{
+% \begin{thebibliography}{9}
+% \bibitem{Alphatk}
+% Vince Darley: \textit{Alphatk} ({\small WWW} page),
+% \texttt{http}://\texttt{www.santafe.edu}\slash
+% \texttt{\~{}vince}\slash \texttt{alphatk}\slash
+% \texttt{about.html}
+% \bibitem{DocScriptingAlpha}
+% Donavan Hall: \textit{Alpha} ({\small WWW} page),
+% \texttt{http}://\texttt{magnet.fsu.edu}\slash
+% \texttt{\~{}hall}\slash\texttt{docscripting}\slash
+% \texttt{alpha}/.
+% \bibitem{tcldoc}
+% Lars Hellstr\"om:
+% \textit{The \package{tcldoc} package and class},
+% \texttt{ftp}:/\slash\texttt{ftp.tex.ac.uk}\slash
+% \texttt{tex-archive}\slash \texttt{macros}\slash
+% \texttt{latex}\slash \texttt{contrib}\slash
+% \texttt{supported}\slash \texttt{tcldoc.dtx}.
+% \bibitem{AlphaHome}
+% Pete Keleher: \textit{Alpha Home Page} ({\small WWW} page),
+% \texttt{http}://\texttt{alpha.olm.net}/.
+% \bibitem{docstrip}
+% Frank Mittelbach, Denys Duchier, Johannes Braams, Marcin
+% Woli\'nski, and Mark Wooding: \textit{The \textsf{DocStrip}
+% program}, The \LaTeX3 Project;
+% \texttt{ftp}:/\slash\texttt{ftp.tex.ac.uk}\slash
+% \texttt{tex-archive}\slash \texttt{macros}\slash
+% \texttt{latex}\slash \texttt{base}\slash \texttt{docstrip.dtx}.
+% \end{thebibliography}
+% }
+%
+% \section{Implementation}
+%
+%
+% \subsection{Interface to \Alpha}
+%
+% The package begins with an |alpha::feature| command to declare itself
+% to \Alpha. As it is hardly useful outside the \texttt{TeX} mode, it
+% declares itself as being specific to that mode.
+% \begin{tcl}
+%<*tcl>
+alpha::feature dtxload 1.1 {TeX} {
+% \end{tcl}
+%
+% \begin{variable}{onlyLoadDtxFiles}
+% \begin{variable}{onlyLoadTclEnvs}
+% Next comes the initialization script for the feature, which
+% declares the two preference variables used by \package{dtxload}.
+% Both variables are flags. |onlyLoadDtxFiles| is |1| if loading of
+% code is restricted to files with suffix \texttt{.dtx} and |0| if
+% there is no restriction. |onlyLoadTclEnvs| is |1| if only code
+% surrounded by a \texttt{tcl} or \texttt{tcl*} environment is loaded
+% and |0| if there is no such restriction. Both preferences are by
+% default |1|.
+% \begin{tcl}
+ # When set, the Load Tcl Code command will be disabled in
+ # TeX files whose suffix is not dtx.
+ newPref flag onlyLoadDtxFiles 1 TeX
+ # When set, the Load Tcl Code command will only extract code
+ # from code lines in tcl and tcl* environments.
+ newPref flag onlyLoadTclEnvs 1 TeX
+% \end{tcl}
+% \end{variable}\end{variable}
+% \begin{variable}{loadTclCode}
+% The initialization script also declares a keybinding preference (to
+% the |dtxload::load| procedure), which is used for
+% \package{dtxload}'s only command. The default value is Command--L
+% and the binding is specific to the \texttt{TeX} mode.
+% \begin{tcl}
+ # This is the key binding for dtxload's Load Tcl Code command.
+ newPref binding loadTclCode <O/L TeX "" dtxload::load TeX
+% \end{tcl}
+% \end{variable}
+%
+% After the initialization script comes the activation and deactivation
+% scripts (which, if I understood things correctly, are called when
+% switching between modes), but these need not contain anything for
+% \package{dtxload}. Instead the arguments of |alpha::feature| continue
+% with the uninstallation procedure
+% \begin{tcl}
+} "" "" uninstall {this-file} \
+% \end{tcl}
+% the maintainer specification (|\x9a| is \texttt{\"{o}})
+% \begin{tcl}
+ maintainer {"Lars Hellstr\x9am" Lars.Hellstrom@math.umu.se} \
+% \end{tcl}
+% and a short help text
+% \begin{tcl}
+ help {The dtxload package implements a command for loading
+ Tcl code that is embedded in a .dtx file without docstripping
+ the file first. For more help, LaTeX the file dtxload.dtx.}
+% \end{tcl}
+% It is possible that the help should rather be |file dtxload.dtx|, but
+% then this file would have to be installed somewhere that \Alpha\
+% would find it. I haven't studied the matter.
+%
+% Next the |dtxload| namespace is declared to \Tcllogo.
+% \begin{tcl}
+namespace eval dtxload {}
+% \end{tcl}
+% \setnamespace{dtxload}
+%
+%
+% \subsection{Code extraction}
+%
+%
+% The code extraction algorithm of \package{dtxload} lack a few of the
+% features of proper \package{docstrip}, but I don't think any of them
+% are essential for the kind of work \package{dtxload} is designed for.
+% The differences to \package{docstrip} are:
+% \begin{itemize}
+% \item The values of guard expressions are not determined from a
+% base set of options, instead the user is inquired for the value of
+% each guard expression.
+% \item Extraction of \package{docstrip} verbatim mode lines is not
+% supported, but it isn't needed for \Tcllogo\ code either.
+% \item Metacomments aren't extracted, but they hardly contain any
+% code of interest to the \Tcllogo\ interpreter anyway.
+% \item \package{dtxload} may scan the comment lines for certain
+% known markup elements (beginning and end of \texttt{tcl} and
+% \texttt{tcl*} environments) and choose to enable or disable
+% extraction based on that.
+% \end{itemize}
+% \package{dtxload} does however act on the guard modifiers and it also
+% looks for errors in the syntax of guards.
+%
+% \begin{variable}{module_stack}
+% \begin{variable}{next_module_idx}
+% The |dtxload::module_stack| variable is keeps track of how modules
+% are nested around the currently considered line. The variable is a
+% stack implemented as a list in which the last element corresponds to
+% the innermost module. Each element in this list is itself a list
+% with the structure
+% \begin{quote}
+% \word{expression} \word{start pos.} \word{previous}\regopt
+% \end{quote}
+% The \word{expression} is the guard expression, as a string. The
+% \word{start pos.} is the position in the file where the module
+% started. Finally, the \word{previous} is a boolean value which
+% records the inclusion status (value of |dtxload::module_included|)
+% that was in force before the module was entered.
+%
+% The |dtxload::next_module_idx| variable holds the index in the
+% |dtxload:|\penalty\hyphenpenalty|:module_stack| list of the next
+% module whose expression has not yet been evaluated; it is equal to
+% |llength ${dtxload::module_stack}| if all module expressions have
+% been evaluated. Those elements in the |dtxload::module_stack| list
+% which have index $\geq$ |dtxload::next_module_idx| do not have a
+% \word{previous} element.
+% \end{variable}\end{variable}
+%
+% \begin{arrayvar}{known_expressions}[expression]
+% The |dtxload::known_expressions| array records the values of all
+% known expressions, i.e., those expressions about whose values the
+% user has been inquired. The entries are either |0| (for ``don't
+% include'') or |1| (for ``include'').
+% \end{arrayvar}
+%
+% \begin{proc}{eval_guard}
+% The |dtxload::eval_guard| procedure takes the string that is a guard
+% expression as argument. It returns |1| if the expression evaluates
+% to true and |0| if it evaluates to false.
+%
+% If the expression has an entry in the |dtxload::known_expressions|
+% array then the |dtxload::eval_guard| procedure returns that value,
+% and if it does not the user is inquired for the value.
+% \begin{tcl}
+proc dtxload::eval_guard {e} {
+ global dtxload::known_expressions
+ if {![info exists dtxload::known_expressions($e)]} then {
+ set dtxload::known_expressions($e)\
+ [expr {"yes" ==\
+ "[askyesno "Should <$e> modules be included?"]"}]
+ }
+ set dtxload::known_expressions($e)
+}
+% \end{tcl}
+% \end{proc}
+%
+% \begin{proc}{push_module}
+% The |dtxload::push_module| procedure pushes a block module onto the
+% module stack, but it does not modify the value of
+% |dtxload::module_included|. The syntax of |dtxload::push_module| is
+% \begin{quote}
+% |dtxload::push_module| \word{expression} \word{position}
+% \end{quote}
+% where \word{expression} is the expression string and
+% \word{position} is the position where the guard begins.
+% \begin{tcl}
+proc dtxload::push_module {e p} {
+ global dtxload::module_stack
+ lappend dtxload::module_stack [list $e $p]
+}
+% \end{tcl}
+% \end{proc}
+%
+% \begin{proc}{pop_module}
+% The |dtxload::pop_module| procedure pops a block module off the
+% module stack and checks that the modules are properly nested. Its
+% syntax is
+% \begin{quote}
+% |dtxload::pop_module| \word{expression} \word{position}
+% \end{quote}
+% where \word{expression} is the expression string of the module to
+% pop and \word{position} is the position where the (end of module)
+% guard begins.
+%
+% If the module nesting is incorrect then the user is presented with
+% a dialog with buttons for pushing the positions of the incorrect
+% modules. It is not an error if the module stack is empty, since it
+% is perfectly reasonable that the beginning of the code to evaluate
+% is in the middle of a module.
+% \begin{tcl}
+proc dtxload::pop_module {e p} {
+ global dtxload::module_stack dtxload::module_included\
+ dtxload::next_module_idx
+ set len [llength ${dtxload::module_stack}]
+ if {$len==0} then {return}
+ set L [lindex ${dtxload::module_stack} [expr {$len-1}]]
+ if {[lindex $L 0] != $e} then {
+ switch [buttonAlert "Module nesting error: <*[lindex $L 0]>\
+ module ended by </$e>. For which guards should the positions\
+ be pushed?" None Start End Both]\
+ {
+ Start {dtxload::push_bookmarks [lindex $L 1]}
+ End {dtxload::push_bookmarks $p}
+ Both {dtxload::push_bookmarks [lindex $L 1] $p}
+ }
+ }
+ set dtxload::module_stack\
+ [lreplace ${dtxload::module_stack} end end]
+ if {$len>=${dtxload::next_module_idx}} then {
+ incr dtxload::next_module_idx -1
+ }
+ if {[llength $L]>2} then {
+ set dtxload::module_included [lindex $L 2]
+ }
+}
+% \end{tcl}
+% \end{proc}
+%
+% \begin{proc}{push_bookmarks}
+% The |dtxload::push_bookmarks| procedure pushes one or several
+% positions in the current window onto the bookmarks stack. The
+% arguments are the positions to push.
+% \begin{tcl}
+proc dtxload::push_bookmarks {args} {
+ global markStack markName
+ foreach pos $args {
+ set name mark$markName
+ incr markName
+ createTMark $name $pos
+ set fileName [win::Current]
+ set markStack [linsert $markStack 0 [list $fileName $name]]
+ }
+}
+% \end{tcl}
+% \end{proc}
+%
+% \begin{variable}{module_included}
+% \begin{variable}{in_tcl_env}
+% The |dtxload::module_included| variable keeps track of whether the
+% current position is in an included module. It is |1| if the current
+% position should be included and |0| if it shouldn't.
+% The |dtxload::in_tcl_env| variable is used for keeping track of
+% what markup context surrounds the currently considered line in the
+% file. It is set to |1| when a |\begin{tcl}| or |\begin{tcl*}| is
+% scanned, and set to |0| when a |\end{tcl}| or |\end{tcl*}| is scanned.
+% \end{variable}\end{variable}
+%
+% \begin{proc}{update_included}
+% Simply pushing a module onto the module stack does not update the
+% |dtxload:|\penalty\hyphenpenalty|:module_included| variable; that is
+% instead done by the |dtxload::update_included| procedure, which
+% should be called right before the value of |dtxload::module_included|
+% is used. The reason for this arrangement is that it avoids evaluating
+% guard expressions whose values do not matter.
+%
+% |dtxload::update_included| has no arguments.
+% \begin{tcl}
+proc dtxload::update_included {} {
+ global dtxload::module_included dtxload::module_stack\
+ dtxload::next_module_idx
+ while {${dtxload::module_included} &&\
+ ${dtxload::next_module_idx}<[llength ${dtxload::module_stack}]}\
+ {
+ set L [lindex ${dtxload::module_stack} ${dtxload::next_module_idx}]
+ lappend L ${dtxload::module_included}
+ set dtxload::module_stack [lreplace ${dtxload::module_stack}\
+ ${dtxload::next_module_idx} ${dtxload::next_module_idx} $L]
+ incr dtxload::next_module_idx
+ set dtxload::module_included [dtxload::eval_guard [lindex $L 0]]
+ }
+}
+% \end{tcl}
+% \end{proc}
+%
+%
+% \begin{proc}{extract_line}
+% The |dtxload::extract_line| procedure steps forward in the file one
+% line at a time until it has found a codeline that can be extracted or
+% it reaches the end of the part of the file from which code is to be
+% extracted. Its syntax is
+% \begin{quote}
+% |dtxload::extract_line| \word{startpos} \word{endpos}
+% \end{quote}
+% Here \word{startpos} is the position at which it should start to
+% look for an extractable code line, and \word{endpos} is the
+% position at which the search should stop if no such line is found.
+% \word{startpos} is assumed to be at the beginning of a line (for
+% identification of code, comment, and guard line purposes) but no
+% test for this is made.
+%
+% The return value of |dtxload::extract_line| is a list with the
+% structure
+% \begin{quote}
+% \word{nextpos} \word{line}\regopt\ \word{foundpos}\regopt
+% \end{quote}
+% \word{nextpos} is the first position in the file after the part that
+% was searched. \word{line} is the extracted codeline and
+% \word{foundpos} is the position at which it began, but these two items
+% are missing if there was no more codeline.
+%
+% The overall structure of |dtxload::extract_line| is a loop
+% which steps through the lines until it reaches the |endpos|. When a
+% line to extract is actually found the procedure returns from within
+% the loop using the |return| command. The local variable |pos|
+% stores the current position, and |pos2| stores the position of the
+% beginning of the next line.
+% \begin{tcl}
+proc dtxload::extract_line {startpos endpos} {
+ global dtxload::in_tcl_env onlyLoadTclEnvs dtxload::module_included
+ for {set pos $startpos} {[pos::compare {$pos<$endpos}]}\
+ {set pos $pos2} {
+% \end{tcl}
+% Inside the loop, the next line is extracted and stored in the local
+% variable |line|. Then |switch| is used for classifying the line and
+% taking appropriate actions.
+% \begin{tcl}
+ set pos2 [nextLineStart $pos]
+ if {$pos2>$endpos} then {set pos2 $endpos}
+ set line [getText $pos $pos2]
+ switch -regexp -- $line {
+% \end{tcl}
+% \changes{v\,1.0}{2000/10/15}{Corrected regular expressions; only
+% percents on the beginning of a line are significant. (LH)}
+% \changes{v\,1.1}{2000/12/03}{Guard lines will affect code extraction.
+% (LH)}
+% \changes{v\,1.1}{2000/12/18}{The code extraction procedures can
+% now handle \package{docstrip} verbatim mode guards, provided
+% they do not appear in a block of extractable code. (LH)}
+% Lines that begin with |%<<| are \package{docstrip} guard lines that
+% start verbatim mode. Extracting code from such lines is currently
+% not supported by \package{dtxload}, so if such a guard is ever
+% encountered the extraction is stopped, but \package{dtxload} can
+% skip verbatim sections from which it shouldn't extract code.
+% \begin{tcl}
+ {^%<<} {
+ if {!$onlyLoadTclEnvs || ${dtxload::in_tcl_env}} then {
+ dtxload::update_included
+ if {${dtxload::module_included}} then {
+ alertnote "docstrip verbatim mode guard line\
+ encountered. Verbatim mode extraction is\
+ currently not supported, so I stop here."
+ goto $pos
+ return [list $endpos]
+ }
+ }
+% \end{tcl}
+% The part of the guard line which comes after the |%<<| is called an
+% end-tag. Verbatim mode ends with the next line which consists of a
+% percent character followed by this end-tag, and therefore all lines
+% up to and including that one are skipped. A technical matter here
+% is that spaces at the end of the line does not count (\TeX\ cannot
+% see them), but spaces inside the end-tag do count!
+% \begin{tcl}
+ set endtag %[string trimright [string trimright\
+ [string range $line 3 end] \n\r] \ ]
+ while {[string trimright [string trimright $line \n\r] \ ]\
+ != $endtag} {
+ set pos $pos2
+ if {[pos::compare {$pos>=$endpos}]}\
+ then {return [list $pos]}
+ set pos2 [nextLineStart $pos]
+ if {$pos2>$endpos} then {set pos2 $endpos}
+ set line [getText $pos $pos2]
+ }
+ }
+% \end{tcl}
+% Lines that begin with |%<*| or |%</| are \package{docstrip} guard
+% lines that delimit block modules, but they do not contain any code
+% themselves. The module is pushed onto or popped off the module stack
+% when the guard line is encountered, but evaluating it is deferred
+% until the first extractable code line.
+% \begin{tcl}
+ {^%<[*/]} {
+ if {![regexp {^%<(\*|/)([^>]+)>} $line foo modifier\
+ expression]}\
+ then {
+ if {"[askyesno "Malformed guard line \"$line\"\
+ encountered. Push position?"]"=="yes"}\
+%
+ then {dtxload::push_bookmarks $pos}
+ } elseif {$modifier=="*"} then {
+ dtxload::push_module $expression $pos
+ } else {
+ dtxload::pop_module $expression $pos
+ }
+ }
+% \end{tcl}
+%
+% Other lines that begin with |%<| are also \package{docstrip}
+% guard lines, but in these cases the lines (i) contain some code
+% and (ii) the guard only affect the code on that line. There must be
+% a |>| somewhere on the line, and the part of the line after the |>|
+% is code that \package{docstrip} can extract.
+% \begin{tcl}
+ {^%<} {
+ if {![regexp {^%<(-|\+|)([^>]+)>(.*)$} $line\
+ foo modifier expression code]}\
+ then {
+ if {"[askyesno "Malformed guard line \"$line\"\
+ encountered. Push position?"]"=="yes"}\
+%
+ then {dtxload::push_bookmarks $pos}
+ } elseif {!$onlyLoadTclEnvs || ${dtxload::in_tcl_env}} then {
+ dtxload::update_included
+ if {${dtxload::module_included}} then {
+ if {[dtxload::eval_guard $expression] !=\
+ ($modifier=="-")}\
+ then {return [list $pos2 $code $pos]}
+ }
+ }
+ }
+% \end{tcl}
+% Remaining lines that begin with |%| are considered comment lines,
+% but they could technically be metacomment lines (begin with |%%|) or
+% a line that \package{docstrip} would process in verbatim mode. In
+% both these cases \package{docstrip} would copy the line, but as there
+% is little point in using these \package{docstrip} features for lines
+% that the \Tcllogo\ interpreter would miss, \package{dtxload} ignores
+% those subtleties.
+% \begin{tcl}
+ {^%} {
+ while {[regexp -indices {\\(begin|end) *{tcl\*?}} $line\
+ match type]} {
+ set dtxload::in_tcl_env\
+ [expr {"[eval string range \$line $type]"=="begin"}]
+ set line [string range $line\
+ [expr {[lindex $match 1]+1}] end]
+ }
+ }
+% \end{tcl}
+% Finally, all lines that do not begin with a |%| are code lines.
+% \begin{tcl}
+ default {
+ if {!$onlyLoadTclEnvs || ${dtxload::in_tcl_env}} then {
+ dtxload::update_included
+ if {${dtxload::module_included}}\
+%
+ then {return [list $pos2 $line $pos]}
+ }
+ }
+ }
+ }
+ list $endpos
+}
+% \end{tcl}
+% \end{proc}
+%
+%
+%
+% \subsection{Evaluating the code}
+%
+% The code in this subsection is based on the \Alpha\ procedures
+% |Alpha::evaluate| and |tcltk::evaluate|, but |dtxload::evaluate|
+% tries to return a bit more information.
+%
+% \begin{proc}{evaluate}
+% The |dtxload::evaluate| procedure takes a script as argument and
+% evaluates it in the global variable context. Any errors that occur
+% are caught. The returned value is a list with the structure
+% \begin{quote}
+% \word{code} \word{message}
+% \begin{regexp}[\regopt]\word{errorInfo}
+% \word{errorCode}\end{regexp}
+% \end{quote}
+% \word{code} is the \Tcllogo\ return code, as returned by |catch|
+% when evaluating the script. \word{message} is the value returned by
+% the script; it is an error message if an error occurred.
+% \word{errorInfo} is the value that the global variable |errorInfo|
+% got after the script was evaluated and \word{errorCode} is the
+% corresponding value of |errorCode|.
+%
+% When the \Alpha\ global variable |evaluateRemotely| is |0| the
+% evaluation is carried out by \Alpha\ itself, but when
+% |evaluateRemotely| is |1| the script is instead sent to a separate
+% \Tcllogo\ shell for evaluation. The current implementation does not
+% return the values of the |errorInfo| and |errorCode| variables in
+% that case, which is why they may be absent from the return value of
+% |dtxload::evaluate|.
+% \changes{v\,1.0}{2000/10/17}{Moved \texttt{history} interaction to
+% \texttt{dtxload::shell\_log}. (LH)}
+% \changes{v\,1.1}{2000/12/05}{Added code for remote evaluation. (LH)}
+% \begin{tcl}
+proc dtxload::evaluate {t} {
+ global errorInfo errorCode evaluateRemotely tcl_platform
+ if {!$evaluateRemotely} then {
+ if {[set code [catch {uplevel \#0 $t} msg]] == 1} then {
+% \end{tcl}
+% If there was an error, the last part of the value of |errorInfo|
+% will be due to the |uplevel| command. As that command was not
+% requested by the user, it would be confusing and it is therefore
+% best to remove it.
+% \begin{tcl}
+ set L [split $errorInfo \n]
+ set errorInfo [join [lrange $L 0 [expr {[llength $L] - 4}]] \n]
+ }
+ list $code $msg $errorInfo $errorCode
+ } elseif {$tcl_platform(platform) == "macintosh"} then {
+% \end{tcl}
+% On the \mbox{MacOS} platform, the script is sent to a remote
+% \Tcllogo\ shell via AppleEvents.
+% \begin{tcl}
+ global tclshSig
+ app::ensureRunning $tclshSig
+ list [catch {
+ aebuild::result -t 30000 '${tclshSig}' misc dosc ----\
+ [aebuild::TEXT $t]
+ } res]\
+ $res
+ } else {
+% \end{tcl}
+% On the other platforms I don't really know what should be done. The
+% following code is based on that in |tcltk::evaluate|, but I haven't
+% been able to test it (help, please?).
+% \begin{tcl}
+ global tclshInterp
+ if {![info exists tclshInterp]} {
+ if {[catch {tcltk::findTclshInterp}]} {
+ return [list 1 "No shell selected"]
+ }
+ }
+ if {$tcl_platform(platform) == "windows"} {
+ if {[dde services Tk $tclshInterp] == ""} {
+ alertnote "The remote shell has died, please select a new one."
+ unset tclshInterp
+ return [dtxload::evaluate $t]
+ }
+ list [catch {dde execute Tk $tclshInterp $t} res] $res
+ } else {
+ list [catch {send $tclshInterp $t} res] $res
+ }
+ }
+}
+% \end{tcl}
+% \end{proc}
+%
+%
+% \subsection{Logging}
+%
+% The code in this subsection is based on the \Alpha\ procedures
+% |Shel::carriageReturn| and |Alpha::evaluate|, but many details had to
+% be changed because, amongst other things, the window to which text is
+% written is not the frontmost one.
+%
+% \begin{proc}{message_log}
+% The |dtxload::message_log| procedure handles logging a script
+% evaluation on the status line. It takes one argument, which is the
+% script to evaluate, and returns a boolean value that specifies whether
+% an error occurred (|0| is no error, |1| is that there was an error).
+%
+% Since the status line is rather limited in size there isn't very
+% much that can be logged on it. |dtxload::message_log| simply displays
+% the result or error that occurred.
+% \begin{tcl}
+proc dtxload::message_log {script} {
+ set res [dtxload::evaluate $script]
+ if {[lindex $res 0]==1} then {
+ message "Tcl eval error: [lindex $res 1]"
+ expr 1
+ } else {
+ if {[string length [lindex $res 1]] == 0} then {
+ message "Tcl eval OK."
+ } else {
+ message "Tcl eval OK: [lindex $res 1]"
+ }
+ expr 0
+ }
+}
+% \end{tcl}
+% \end{proc}
+%
+%
+% \begin{proc}{window_log}
+% \changes{v\,1.1}{2000/12/05}{Renamed procedure (old name was
+% \texttt{dtxload:\discretionary{}{}{}:shell\_log}). (LH)}
+% \begin{variable}{log_window_name}
+% \changes{v\,1.1}{2000/12/05}{Renamed variable (old name was
+% \texttt{dtxload:\discretionary{}{}{}:shell\_window\_name}). (LH)}
+% The |dtxload::window_log| procedure handles logging a script
+% evaluation in a window, which must be open when this procedure is
+% called. It takes one argument, which is the script to evaluate, and
+% returns a boolean value that specifies whether an error occurred
+% (|0| is no error, |1| is that there was an error).
+%
+% When it is set the |dtxload::log_window_name| variable holds the
+% name of the window which is used in logging, and when it isn't set
+% this means that logging should be in the status line. Initially it
+% is unset.
+% \begin{tcl}
+if {[info exists dtxload::log_window_name]} then {
+ unset dtxload::log_window_name
+}
+% \end{tcl}
+% \end{variable}
+%
+% If the log window has mode |Shel| then the |script| is recorded in
+% the history list, but since the shells have trouble handling history
+% items that contain more than one line, all newlines in the recorded
+% script will be replaced by semicolons. This \emph{can} change the
+% meaning of the script, but hopefully that happens so rarely that one
+% can live with it.
+% \changes{v\,1.0}{2000/11/01}{Scripts added to the history list are
+% converted to one-liners. (LH)}
+% \begin{tcl}
+proc dtxload::window_log {script} {
+ upvar #0 dtxload::log_window_name win
+ global win::Modes Shel::startPrompt Shel::endPrompt
+ if {[set win::Modes($win)] == "Shel"} then {
+ global Shel::histnum
+ regsub -all \n [string trimright $script] " ; " text
+ history add $text
+ set Shel::histnum [history nextid]
+ }
+% \end{tcl}
+%
+% Next the script is inserted into (at the end of) the log window.
+% The lines on which logged scripts are written are marked out using
+% a special \package{dtxload} prompt, which is constructed as
+% \begin{quote}
+% |"${Shel::startPrompt}dtxload${Shel::endPrompt} "|
+% \end{quote}
+% If the log window mode is |Shel| and the last thing in the window
+% is the current prompt for the window, then that prompt is replaced
+% by the \package{dtxload} prompt, otherwise a newline followed by a
+% \package{dtxload} prompt will be appended to the window. The result
+% of a logged script is put on the line after the last line of the
+% script.
+% \begin{tcl}
+ set pos [maxPos -w $win]
+ select -w $win $pos $pos
+ set dtxprompt "${Shel::startPrompt}dtxload${Shel::endPrompt} "
+ if {[set win::Modes($win)] != "Shel"} then {
+ insertText -w $win \r$dtxprompt
+ } else {
+ set stdprompt [Alpha::Prompt]
+ set pos2 [pos::math $pos - [string length $stdprompt]]
+ if {[getText -w $win $pos2 $pos] != $stdprompt} then {
+ insertText -w $win \r$dtxprompt
+ } else {
+ replaceText -w $win $pos2 $pos $dtxprompt
+ refresh
+ }
+ }
+% \end{tcl}
+% There currently is a bug (it is fixed in \Alpha~8) in
+% |replaceText| which causes it to always draw in the current window.
+% The |refresh| restores the proper window contents.
+% \changes{v\,1.0}{2000/10/16}{\texttt{refresh} inserted to overcome
+% \texttt{replaceText} bug. (LH)}
+%
+% Inserting the actual script text is basically an |insertText|, but
+% before the script is inserted all newlines in it (except the last)
+% are replaced by newlines followed by a \package{dtxload} prompt.
+% Since |dtxload::load| converts all newlines to linefeeds, it is
+% sufficient to replace linefeeds. It seems that newlines in \Alpha\
+% are always carriage returns (regardless of the window's ``platform''
+% attribute), and I assume that the \package{dtxload} prompt doesn't
+% contain any regexp metacharacter.
+% \changes{v\,1.0}{2000/10/16}{Assuming newlines in the script to log
+% are linefeeds. (LH)}
+% \begin{tcl}
+ regsub -all \n [string trimright $script] \r$dtxprompt text
+ insertText -w $win "$text\r"
+% \end{tcl}
+% After the script has been logged, it is time to evaluate it and log
+% the result.
+% \begin{tcl}
+ set res [dtxload::evaluate $script]
+ if {[lindex $res 0]==1} then {
+ insertText -w $win "Error: [lindex $res 1]\r"
+ if {[llength $res]>2} then {
+ global errorInfo
+ set errorInfo [lindex $res 2]
+ }
+ message "Tcl eval error"
+ } else {
+ if {[string length [lindex $res 1]]>0}\
+ then {insertText -w $win "[lindex $res 1]\r"}
+ message "Tcl eval OK"
+ }
+% \end{tcl}
+% If the window has mode |Shel| then the window's current prompt is
+% inserted. It is necessary to call |Alpha::Prompt| again because
+% evaluating the script might have changed the prompt. Then the return
+% value is finally computed.
+% \begin{tcl}
+ if {[set win::Modes($win)] == "Shel"}\
+ then {insertText -w $win [Alpha::Prompt]}
+ expr {[lindex $res 0]==1}
+}
+% \end{tcl}
+% \end{proc}
+%
+%
+%
+%
+% \subsection{Putting it all together}
+%
+% \begin{proc}{load}
+% The |dtxload::load| procedure implements the \package{dtxload} user
+% command---it extracts and evaluates the code in the current
+% selection (if something is selected) or the entire front window (if
+% nothing is selected). The evaluation is logged a window or on the
+% status line depending on the current value of
+% |dtxload::log_window_name|.
+%
+% Code is extracted and evaluated one command (or as close as one gets)
+% at a time. In case an error occurs the loading is stopped and the
+% insertion point is moved to the beginning of the problematic script,
+% whereas the mark is put at the end of the code to load. This way a
+% simple \textsf{Mark Hilite} will select the part of the code that
+% remains to be loaded.
+%
+% The very first thing |dtxload::load| does is to check whether it is
+% allowed to load any code in this window.
+% \begin{tcl}
+proc dtxload::load {} {
+ global onlyLoadDtxFiles
+ if {$onlyLoadDtxFiles && ![string match *.dtx [win::CurrentTail]]}\
+ then {
+ message "Not a .dtx file."
+ return
+ }
+% \end{tcl}
+% Then the interval from which code should be extracted is
+% determined.
+% \begin{tcl}
+ set startpos [getPos]
+ set endpos [selEnd]
+ if {[pos::compare {$startpos == $endpos}]} then {
+ set startpos [minPos]
+ set endpos [maxPos]
+ }
+% \end{tcl}
+% Next it is determined what logging method should be used. The name
+% of the procedure gets stored in the local variable |log|.
+% \begin{tcl}
+ global dtxload::log_window_name
+ if {
+ [info exists dtxload::log_window_name] &&
+ [lsearch -exact [winNames] ${dtxload::log_window_name}]!=-1
+ } then {set log dtxload::window_log}\
+ else {set log dtxload::message_log}
+% \end{tcl}
+% After that a couple of extraction-related variables are initialized.
+% The idea behind how the |dtxload::in_tcl_env| variable is set is that
+% if one is loading a short piece of code inside a \texttt{tcl}
+% environment then the first line probably doesn't start with a |%|,
+% whereas if one is loading an entire file (and thus starts in
+% non-\texttt{tcl}-environment) the first character quite likely is a
+% |%|.
+% \begin{tcl}
+ global dtxload::in_tcl_env dtxload::module_stack\
+ dtxload::next_module_idx dtxload::module_included
+ set dtxload::in_tcl_env\
+ [expr {[getText $startpos [pos::math {$startpos+1}]] != "%"}]
+ set dtxload::module_stack {}
+ set dtxload::next_module_idx 0
+ set dtxload::module_included 1
+% \end{tcl}
+% The last piece of initialization concerns the |script| local
+% variable, in which the extracted lines are collected until they
+% make up an entire command. The |escaped| variable is a boolean
+% which is true when the newline at the end of the last line of
+% |script| was escaped. The |spos| variable stores the position at
+% which the command currently being collected began, but it is
+% initialized to |none| here to help distinguishing the case that no
+% extractable code was found.
+% \begin{tcl}
+ set script ""
+ set escaped 0
+ set spos none
+ while {[pos::compare $startpos < $endpos]} {
+ set extract [dtxload::extract_line $startpos $endpos]
+ if {[llength $extract]>1} then {
+% \end{tcl}
+% When a line of code has been extracted, it must be appended to
+% |script|. This isn't as easy as one might imagine, because \Tcllogo\
+% code being |source|d (which is what loading must function as) is fed
+% through a few more conversion steps than code being |eval|ed. In
+% particular all escaped newlines are converted to spaces and all
+% other newlines are converted to linefeeds, so that must be done
+% explicitly. A newline is considered to be escaped if is is preceded
+% by an odd number of backslashes, and if it is then the last backslash
+% and the newline are replaced by a single space. If the last line of
+% |script| ended by an escaped newline then the script is considered
+% incomplete and more code will be collected before evaluation is
+% attempted. Evaluation of |script| is also conditioned by that |info\
+% complete $script| returns |1|.
+% \changes{v\,1.0}{2000/10/16}{Converting nonescaped newlines to
+% linefeeds, since \Tcllogo\ doesn't consider carriage returns to
+% be command separators. (LH)}
+% \begin{tcl}
+ if {[string length $script]==0} then {
+ set spos [lindex $extract 2]
+ }
+ set line [lindex $extract 1]
+ if {$escaped} then {set line [string trimleft $line]}
+ set escaped [regsub -all\
+ "((^|\[^\\\\\])(\\\\\\\\)*)\\\\(\r|\n|\r\n)$" $line {\1 } line]
+ if {!$escaped} then {regsub "\r\n?\$" $line \n line}
+ append script $line
+ if {!$escaped && [info complete $script]} then {
+ if {[$log $script]} then {
+ select $spos $endpos
+ markHilite
+ return
+ } else {
+ set script ""
+ }
+ }
+ } elseif {$spos=="none"} then {
+ message "No extractable code found."
+ }
+ set startpos [lindex $extract 0]
+ }
+% \end{tcl}
+% If the |script| variable isn't empty, then try to evaluate whatever
+% is in it before returning. If not even that causes an error the
+% |dtxload:|\penalty\hyphenpenalty|:known_expressions| array is unset
+% so that one can use other options for the next piece of code loaded.
+% \begin{tcl}
+ if {[string length $script]>0 && [$log $script]} then {
+ select $spos $endpos
+ markHilite
+ } else {
+ global dtxload::known_expressions
+ if {[info exists dtxload::known_expressions]}\
+ then {unset dtxload::known_expressions}
+ }
+}
+% \end{tcl}
+% \end{proc}
+%
+%
+% \subsection{Setting the log destination}
+%
+% \begin{proc}{logdest}
+% \changes{v\,1.0}{2000/10/16}{Procedure added. (LH)}
+% \changes{v\,1.1}{2000/12/07}{Procedure renamed from
+% \texttt{dtxload::redirect} and the syntax was changed. (LH)}
+% The log destination is set using the |dtxload::logdest| procedure.
+% The general syntax for this procedure is
+% \begin{quote}
+% |dtxload::logdest| \word{keyword} \word{window name}\regopt
+% \end{quote}
+% where the \word{keyword} (mainly) specifies the type of log
+% destination and \word{window name} is the name of the target
+% window (ignored for some \word{keyword}s).
+% \begin{tcl}
+proc dtxload::logdest {type {win "dtxload log"}} {
+ global dtxload::log_window_name
+ switch -exact -- $type {
+% \end{tcl}
+% The first form of |dtxload::logdest| has the syntax
+% \begin{quote}
+% |dtxload::logdest status|
+% \end{quote}
+% It makes the status line the log destination.
+% \begin{tcl}
+ status {
+ if {[info exists dtxload::log_window_name]}\
+ then {unset dtxload::log_window_name}
+ }
+% \end{tcl}
+% The second form has the syntax
+% \begin{quote}
+% |dtxload::logdest here|
+% \end{quote}
+% It makes the current window the log destination, regardless of what
+% may already be in it or which mode it has.
+% \begin{tcl}
+ here {set dtxload::log_window_name [win::CurrentTail]}
+% \end{tcl}
+% The third form has the syntax
+% \begin{quote}
+% |dtxload::logdest window| \word{window name}
+% \end{quote}
+% It sets the log destination to the window named \word{window name},
+% regardless of what may already be in it or which mode it has. If
+% the window does not already exist it is created.
+% \begin{tcl}
+ window {
+ if {[lsearch -exact [winNames] $win] == -1} then {
+ new -n $win -shell 1 -text "This is a dtxload log window.\r"
+ }
+ set dtxload::log_window_name $win
+ }
+% \end{tcl}
+% The fourth and final form has the syntax
+% \begin{quote}
+% |dtxload::logdest shell| \word{window name}
+% \end{quote}
+% It calls |Shel::start| to open a \Tcllogo\ shell window and sets the
+% log destination to that window.
+% \begin{tcl}
+ shell {
+ Shel::start "Alpha" $win\
+ "This is a dtxload log window (and Alpha Tcl shell).\r"
+ set dtxload::log_window_name $win
+ }
+ }
+}
+%</tcl>
+% \end{tcl}
+% \end{proc}
+%
+%
+% \Finale
+%
+\endinput