# Can I specify that I only want the .sty file from a .dtx?

I've been trying to be good and make my proto-packages .dtx files (in particular, the files in the TeX-SX Package but that's not particularly relevant). My workflow goes a bit like this:

1. Hack a few macros with tests in a .tex file
2. Fork the macro bit into a .sty file and the tests stay in a .tex file
3. Munge the macros into something reasonable
4. Convert the tests into something approximating documentation
5. Convert the .sty file to a .dtx
7. Announce it somewhere and ask for testers

At this point, I enter the "add feature and fix bugs" stage. Editing the .dtx is a little less intuitive than the .sty (having to remember the macrocode stuff, but I'm getting used to it), but I don't usually want to rebuild the documentation every time - I usually have a separate test file that tests only those bits that I'm editing. So whilst I'm okay at adding pdflatex file.dtx to generate the new .sty file, it's a bit much that it generates the documentation as well. Not only is it a waste of time but also can hide any errors in the .sty bit under a wreath of information about the documentation bit.

So: how do I tell pdflatex to only generate the .sty file when I run pdflatex file.dtx?

(Incidentally, if anyone happens to suggest any improvements on my workflow, I'll be very grateful.)

-
Hack, Fork, Munge... I think step 4 should be "splice the tests..." and 5. should be "whizz the .sty..." – Seamus May 28 '11 at 18:04
@Seamus: Vær så godt! (aka: feel free to edit accordingly!) – Loop Space May 28 '11 at 18:16

The approach I use is to have a .dtx file structured such that pdflatex <filename>.dtx will extract the code and typeset the documentation, while tex <filename>.dtx will only do the extraction. The one I use is basically

% \iffalse meta-comment
%<*internal>
\iffalse
%</internal>
%<*internal>
\fi
\def\nameofplainTeX{plain}
\ifx\fmtname\nameofplainTeX\else
\expandafter\begingroup
\fi
%</internal>
%<*install>
\input docstrip.tex
\keepsilent
\preamble
---------------------------------------------------------------
<PACKAGE> --- <DESCRIPTION>
Maintained by <NAME>
E-mail: <EMAIL>
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
---------------------------------------------------------------

\endpreamble
\postamble
<NAME> <<EMAIL>>

It may be distributed and/or modified under the conditions of
the LaTeX Project Public License (LPPL), either version 1.3c of
version of this license is in the file:
http://www.latex-project.org/lppl.txt
This work is "maintained" (as per LPPL maintenance status) by
<NAME>.

This work consists of the file  <PACKAGE>.dtx
and the derived files <PACKAGE>.pdf,
<PACKAGE>.sty and
<PACKAGE>.ins.

\endpostamble
\usedir{tex/latex/<PACKAGE>}
\generate{
\file{\jobname.sty}{\from{\jobname.dtx}{package}}
}
%</install>
%<install>\endbatchfile
%<*internal>
\usedir{source/latex/<PACKAGE>}
\generate{
\file{\jobname.ins}{\from{\jobname.dtx}{install}}
}
\nopreamble\nopostamble
\usedir{doc/latex/<PACKAGE>}
\generate{
}
\ifx\fmtname\nameofplainTeX
\expandafter\endbatchfile
\else
\expandafter\endgroup
\fi
%</internal>
%<*driver>
\documentclass{ltxdoc} % or whatever
%\DisableImplementation
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% CODE AND DOCUMENTATION HERE


What happens is that the tests (inside the internal guards) mean that the extraction is done inside a group for LaTeX but is not for plain TeX, which instead exits before getting to the documentation part.

The way I then use this for testing is to have a very simple test file, with \write18 enabled. Something like

\immediate\write18{tex <FILENAME>.dtx}
\documentclass{article}
\usepackage{<FILENAME>}
\begin{document}
Tests here.
\end{document}


which lets me do a lot of simple (or less simple) testing without needing to typeset everything.

-
On the basis that I copied my .dtx template from your blog, I tested this fully expecting it to work with no modification ... and it did! Fantastic! Thanks. – Loop Space May 29 '11 at 17:47
@Andrew: I suspected that from your other comments, but as answers are intended to be self-contained decided to post more-or-less the same stuff here. Also, in this particular case I've tried to focus on the one point in hand. – Joseph Wright May 29 '11 at 20:30

You probably put the installer code into the .dtx file as well. This style seems to be some form of fashion nowadays. The classic way to do this as shown in the clsguide is to put the docstrip command into a separate .ins file which then extracts the .sty file:

So, unpack using:

pdflatex somepackage.ins   % extract .sty file


While:

pdflatex somepackage.dtx   % compile manual


I'm using Makefile's for all my packages and have a unpack target for the first line, so I only need to say make unpack or make package which is an alias.

A minimal example of a .ins file would be:

\input docstrip.tex
\keepsilent
\generate{\file{somepackage.sty}{\from{somepackage.dtx}{package}}}
\endbatchfile


See the clsguide for a larger example.

-
I did put the installer in to the .dtx. It was a bit of "Cargo Cult Programming" based on examples at Joseph's blog (which you directed me to!). I like having absolutely everything in one file. But while I'm writing the stuff then having a separate .ins is perfectly reasonable. Thanks. – Loop Space May 28 '11 at 18:37
@Andrew: You can have both, i.e. the install code twice internal and external. Then only use the .ins file if you want the .sty file only. There is some trickery with conditionals passed by the Makefile but I would try to avoid this. – Martin Scharrer May 28 '11 at 18:46
That's what I tried and it worked fine (except that I had to name the external one something other than package.ins so that it didn't get overwritten if I inadvertently called pdflatex on the .dtx). – Loop Space May 28 '11 at 20:21
Sorry, Martin - Joseph's answer just happens to be the right answer for my specific situation since I copied my .dtx template from his blog, so he gets the 'accepted'. I hope you won't feel too disappointed. – Loop Space May 29 '11 at 17:49