achemso and rsc: empty first entry in bibliography

I’ve had a few e-mails recently from users of my achemso and rsc packages, complaining that they get an empty first entry in the bibliography. Some of the users have noticed that it seems to be linked to the special control citation that both packages use. However, this is not a bug in either bundle, but is because the users have done a self-install of the packages.

In both cases, the LaTeX packages are designed to work with matching BibTeX styles. What tends to happen is people install the LaTeX stuff manually, but forget the BibTeX part. So the wrong .bst files get used by BibTeX, and odd results are seen. So my advice is, if you update anything by hand, make sure you install all of the update and not just some of it!

PCTeX: Helpful people

I had a bug report for siunitx recently, concerning handling of the ohm symbol when the MathTime Pro package has made \Omega slanted. As many of you will know, MathTime Pro is commercial, and so I was not totally sure I’d be able to sort the issue out. I dropped the suppliers, PCTeX, a quick e-mail to see if they’d let me see the code for bug-fixing purposes, more in hope than expectation. I was pleasantly surprised to get an e-mail back the next morning, saying that this was no problem and even letting me download the fonts themselves for testing. A ‘pat on the back’ to PCTeX: very good service indeed.

TeXworks: Automatic LaTeX message detection

TeXworks: Experimental LaTeX-errors interface
TeXworks: Experimental LaTeX-errors interface

The latest builds of TeXworks include support for scripting. There are not a lot of scripts just yet, but one that already looks good is LaTeX error message highlighting.

This already seems to work pretty well, and it’s one of the few things I miss from my previous editor of choice (WinEdt). It can already jump to the line in question, when you choose the appropriate line in the listing.

Of course, this is only the first step in getting full scripting support for TeXworks. But things look good to me: the extra complexity to the interface is minimal, and it really opens up the possibilities for more advanced users.

Automating releases to CTAN

I’ve talked in recent posts about various aspects of creating LaTeX packages, focussing on the dtx format. One thing I’ve been promising to cover is automating the release of material to CTAN. Even for a basic package, there are a few files to sort out (the source, a readme file, the documentation and an ins file). For the documentation, you need to typeset the correct version, include the changes and code index. So even in a simple case, a bit of help from the computer is a good thing: I manage to miss stuff quite happily even with some stuff set up.

What do I mean by automation? Well, there is typesetting to do, files to copy and zip files to create. For Windows users, there are also line endings to worry about: CTAN prefer Unix ones for plain text files. All of that can be rolled up into some kind of script (a shell script on Unix or a batch file on Windows). Unix users also have easy access to the ‘make’ utility. The basic tasks are the same whatever method you go for, but I’m going to assume batch files for Windows and make files for Unix (including Mac OS X).

The aim here is not to have to most sophisticated system possible, but to make life easier. So I’ve not necessarily made every refinement I’ve thought of as some of them make what is going on much less clear. I’d also point out that a lot of the ideas here are ones I’ve adapted from elsewhere, or that have been suggested to me. Not much originality, but again that is not the main point. One thing to point out is that I’ve provided settings for copying dtx, ins, sty and pdf files. Other file types would need to be added, but hopefully there is enough here for the pattern to be clear without over-complicating things. You can always add things to a script so that the do nothing if they are not needed. So the same ideas can be used for packages with different requirements, with only a few basic settings to change.

The two files I’m going to provide both aim to give the same functionality: I work with both Windows and Unix, so I need that. As well as being able to clean out the working directory and make documentation, there are also methods to make a CTAN archive and a TDS one (to send to users for direct installation). Finally, I’ve included a local installation option: useful if you don’t update your TeX system regularly and need your own code to be up to date!

Windows batch files

A batch file on Windows (or indeed a shell script on Unix) is simply a list of commands you could type yourself at the command line, but with some flow control added. Recent versions of Windows include a number of extensions beyond the old DOS capabilities: I’m going to use some of these, but that only rules out very old systems so it should be reasonably safe. If you want to grab the entire file in one go, it’s available here.

One problem is that there is no command line tool for creating zip files installed by default in Windows. I’ve tried a few out, and the best seems to be Info-ZIP. It does a good job of marking up binary and text files, and also includes some abilities to sort out line endings. If it doesn’t work for you, other tools such as the Swiss File Knife do the same thing on a file-by-file basis. Whatever you decide, it’s best to put the support tools on the Windows path somewhere.

@echo off

  if not "%1" == "" goto :init

:help

  echo.
  echo  make clean        - delete all generated files
  echo  make ctan         - create an archive ready for CTAN
  echo  make doc          - typesets documentation
  echo  make localinstall - extract packages
  echo  make tds          - create a TDS-ready archive
  echo  make unpack       - extract packages

  goto :EOF

:init

  setlocal

  rem The name of the package to create should be set here: here, the
  rem example package "demopkg" is in use

  set PACKAGE=demopkg

  rem It is possible to unpack dtx files without needing any extra files, but
  rem some people prefer a separate ins file (or there may be no unpacking
  rem to do). This should be set up here: for a self-extracting dtx the
  rem standard setting is fine.

  set UNPACK=%PACKAGE%.dtx

  rem A list of pdf files to be typeset and included in the archive files
  rem created. The files named here will be typeset (looking for source files
  rem in the order .dtx, .tex, .ltx).

  set INCLUDEPDF=%PACKAGE%

  rem Plain text files to be included in the archives: the .txt extension is
  rem automatically stripped when creating the archive.

  set INLCUDETXT=README

  rem Files to typeset

  rem The settings for cleaning up after compilation are divided into two
  rem parts. AUXFILES are deleted after each (La)TeX run, CLEAN only
  rem when the user calls "make clean"

  set AUXFILES=aux dvi glo gls hd idx ilg ind ist log out toc
  set CLEAN=gz ins pdf sty tex txt zip

  rem Sets the order for searching for source files for pdfs

  set PDFSOURCES=dtx tex

  rem The file types for inclusion in the archive files: note that a CTAN
  rem archive should not contain "unpacked" files. Typeset files and their
  rem sources are not inlcuded here: they are dealt with separately

  set CTANFILES=dtx ins pdf
  set TDSFILES=%CTANFILES% sty 

  rem Locations for building archives

  set CTANROOT=ctan
  set CTANDIR=%CTANROOT%\%PACKAGE%
  set TDSROOT=tds

  cd /d "%~dp0"

:main

  if /i "%1" == "clean"        goto :clean
  if /i "%1" == "ctan"         goto :ctan
  if /i "%1" == "doc"          goto :doc
  if /i "%1" == "help"         goto :help
  if /i "%1" == "localinstall" goto :localinstall
  if /i "%1" == "tds"          goto :tds
  if /i "%1" == "unpack"       goto :unpack

  goto :help

:clean

  echo.
  echo Deleting files

  for %%I in (%CLEAN%) do (
    if exist *.%%I del /q *.%%I
  )

  for %%I in (%TXT%) do (
    if exist %%I del /q %%I
  )

:clean-aux

  for %%I in (%AUXFILES%) do (
    if exist *.%%I del /q *.%%I
  )

  goto :end

:ctan

  call :zip
  if errorlevel 1 goto :EOF

  call :doc
  if errorlevel 1 goto :EOF

  echo.
  echo Creating archive

  for %%I in (%SOURCES%) do (
    xcopy /q /y %%I "%CTANDIR%\" > nul
  )
  for %%I in (%CTANFILES%) do (
    xcopy /q /y *.%%I "%CTANDIR%\" > nul
  )
  for %%I in (%INLCUDETXT%) do (
    xcopy /q /y %%I.txt "%CTANDIR%\" > nul
    ren "%CTANDIR%\%%I.txt" %%I
  )

  pushd "%CTANROOT%"
  %ZIPEXE% %ZIPFLAG% %PACKAGE%.zip .
  popd
  copy /y "%CTANROOT%\%PACKAGE%.zip" > nul

  rmdir /s /q %CTANROOT%

  goto :end

:doc 

  call :unpack

  set SOURCES=

  for %%I in (%INCLUDEPDF%) do (
    for %%J in (%PDFSOURCES%) do (
      echo.
      if exist %%I.%%J call :typeset-%%J %%I.%%J
    )
  )

  goto :clean-aux

:file2tdsdir

  set TDSDIR=

  if /i "%~x1" == ".dtx" set TDSDIR=source\latex\%PACKAGE%
  if /i "%~x1" == ".ins" set TDSDIR=source\latex\%PACKAGE%
  if /i "%~x1" == ".pdf" set TDSDIR=doc\latex\%PACKAGE%
  if /i "%~x1" == ".sty" set TDSDIR=tex\latex\%PACKAGE%
  if /i "%~x1" == ".txt" set TDSDIR=doc\latex\%PACKAGE%

  goto :EOF

:localinstall

  call :unpack

  echo.
  echo Installing

  if not defined TEXMFHOME set TEXMFHOME=%USERPROFILE%\texmf

  for %%I in (%TDSFILES%) do (
    call :localinstall-int *.%%I
  )

  goto :end

:localinstall-int

  call :file2tdsdir %1

  if defined TDSDIR (
    xcopy /q /y %1 "%TEXMFHOME%\%TDSDIR%\" > nul
  ) else (
    echo Unknown file type "%~x1"
  )

  goto :EOF

:tds

  call :zip
  if errorlevel 1 goto :EOF

  call :doc
  if errorlevel 1 goto :EOF

  echo.
  echo Creating archive

  for %%I in (%SOURCES%) do (
    call :tds-int %%I
  )
  for %%I in (%TDSFILES%) do (
    call :tds-int *.%%I
  )
  for %%I in (%INLCUDETXT%) do (
    call :tds-txt %%I
  )

  pushd "%TDSROOT%"
  %ZIPEXE% %ZIPFLAG% %PACKAGE%.tds.zip .
  popd
  copy /y "%TDSROOT%\%PACKAGE%.tds.zip" > nul

  rmdir /s /q "%TDSROOT%"

  goto :end

:tds-int

  call :file2tdsdir %1

  if defined TDSDIR (
    xcopy /q /y %1 "%TDSROOT%\%TDSDIR%\" > nul
  ) else (
    echo Unknown file type "%~x1"
  )

  goto :EOF

:tds-txt

  call :file2tdsdir %1.txt

  if defined TDSDIR (
    xcopy /q /y %1.txt "%TDSROOT%\%TDSDIR%\" > nul
    ren "%TDSROOT%\%TDSDIR%\%1.txt" %1
  ) else (
    echo Unknown file type "%~x1"
  )

  goto :EOF

:typeset-dtx

  echo Typesetting %1

  pdflatex -interaction=nonstopmode -draftmode "\AtBeginDocument{\OnlyDescription}\input %1" > nul
  if ERRORLEVEL 1 (
    echo ! Compilation failed
  )

  makeindex -q -s gglo.ist -o %~n1.gls %~n1.glo > nul
  makeindex -q -s gind.ist -o %~n1.ind %~n1.idx > nul
  pdflatex -interaction=nonstopmode "\AtBeginDocument{\OnlyDescription} \input %1" > nul
  pdflatex -interaction=nonstopmode "\AtBeginDocument{\OnlyDescription} \input %1" > nul

  goto :EOF

:typeset-tex

  echo Typesetting %1

  set SOURCES=%SOURCES% %1

  pdflatex -interaction=nonstopmode -draftmode %1 > nul
  if ERRORLEVEL 1 (
    echo ! Compilation failed
  )
  pdflatex -interaction=nonstopmode %1 > nul
  pdflatex -interaction=nonstopmode %1 > nul

  goto :EOF

:unpack

  echo.
  echo Unpacking files

  for %%I in (%UNPACK%) do (
    tex %%I > nul
  )

  goto :end

:zip 

  if not defined ZIPFLAG set ZIPFLAG=-r -q -X -ll

  if defined ZIPEXE goto :EOF

  for %%I in (zip.exe "%~dp0zip.exe") do (
    if not defined ZIPEXE if exist %%I set ZIPEXE=%%I
  )

  for %%I in (zip.exe) do (
    if not defined ZIPEXE set ZIPEXE="%%~$PATH:I"
  )

  if not defined ZIPEXE (
    echo.
    echo This procedure requires a zip program,
    echo but one could not be found.
    echo
    echo If you do have a command-line zip program installed,
    echo set ZIPEXE to the full executable path and ZIPFLAG to the
    echo appropriate flag to create an archive.
    echo.
  )

  goto :EOF

:end

  shift
  if not "%1" == "" goto :main

Most of the ideas here should be pretty straight-forward. The clever part is :file2tdsdir, which I have to say was not my idea at all! It allows the batch file to ‘know’ which type of files go where, so that you only need the information once for use in several places.

To use the file, just alter the settings at the beginning. The pattern should be pretty clear, and most of the rest of the code (for example, :file2tdsdir for correctly placing files) is also quite obvious.

Unix make files

Unix make files work somewhat differently to shell scripts. Each entry is a ‘target’, which is a file to create. I’m not going to explain in detail how they work, but in essense there are a series of fake ‘files’ which are the names of the settings you send to make (for example, make ctan needs a target called ctan). As with the batch file, there are a series of blanks to fill in here to customise things. I’m also sticking with the idea that things are pretty basic: a dtx file, a sty file and some documentation, plus perhaps one or more example tex files. Hopefully the idea is pretty clear. By keeping as much as possible in variables, the idea is to avoid needing to change the bulk of the file to move from one package to another. As with the batch file, the entire thing is available here. to download.

################################################################
################################################################
# Makefile for demopkg                                         #
################################################################
################################################################

################################################################
# Default with no target is to give help                       #
################################################################

help:
	@echo ""
	@echo " make clean               - clean out test directory"
	@echo " make ctan                - create a CTAN-ready archive"
	@echo " make doc                 - typeset documentation"
	@echo " make localinstall        - install files in local texmf tree"
	@echo " make tds                 - create a TDS-ready archive"
	@echo " make unpack              - extract packages"
	@echo ""

##############################################################
# Master package name                                        #
##############################################################

PACKAGE = demopkg

##############################################################
# Directory structure for making zip files                   #
##############################################################

CTANROOT := ctan
CTANDIR  := $(CTANROOT)/$(PACKAGE)
TDSDIR   := tds

##############################################################
# Data for local installation and TDS construction           #
##############################################################

INCLUDEPDF  := $(PACKAGE)
INCLUDETEX  :=
INCLUDETXT  := README
PACKAGEROOT := latex/$(PACKAGE)

##############################################################
# Details of source files                                    #
##############################################################

DTX      = $(PACKAGE).dtx
DTXFILES = $(PACKAGE)
UNPACK   = $(PACKAGE).dtx

##############################################################
# Clean-up information                                       #
##############################################################

AUXFILES = \
	aux  \
	glo  \
	gls  \
	hd   \
	idx  \
	ilg  \
	ind  \
	log  \
	out  \
	tmp  \
	toc  

CLEAN = \
	gz  \
	ins \
	pdf \
	sty \
	tex \
	txt \
	zip 

################################################################
# File buiding: default actions                                #
################################################################

%.pdf: %.dtx
	NAME=`basename $< .dtx` ; \
	echo "Typesetting $$NAME" ; \
	pdflatex -draftmode -interaction=nonstopmode "\AtBeginDocument{\OnlyDescription} \input $<" &> /dev/null ; \
	if [ $$? = 0 ] ; then  \
	  makeindex -s gglo.ist -o $$NAME.gls $$NAME.glo &> /dev/null ; \
	  makeindex -s gind.ist -o $$NAME.ind $$NAME.idx &> /dev/null ; \
	  pdflatex -interaction=nonstopmode "\AtBeginDocument{\OnlyDescription} \input $<" &> /dev/null ; \
	  pdflatex -interaction=nonstopmode "\AtBeginDocument{\OnlyDescription} \input $<" &> /dev/null ; \
	else \
	  echo "  Complilation failed" ; \
	fi ; \
	for I in $(AUXFILES) ; do \
	  rm -f $$NAME.$$I ; \
	done

################################################################
# User make options                                            #
################################################################

.PHONY = \
	clean        \
	ctan         \
	doc          \
	localinstall \
	tds          \
	unpack

clean:
	echo "Cleaning up"
	for I in $(AUXFILES) $(CLEAN) ; do \
	  rm -f *.$$I ; \
	done
	rm -rf $(CTANROOT)/
	rm -rf $(TDSDIR)/

ctan: doc
	echo "Creating CTAN archive"
	mkdir -p $(CTANDIR)/
	rm -rf $(CTANDIR)/*
	cp -f *.dtx $(CTANDIR)/ ; \
	cp -f *.ins $(CTANDIR)/ ; \
	for I in $(INCLUDEPDF) ; do \
	  cp -f $$I.pdf $(CTANDIR)/ ; \
	done ; \
	for I in $(INCLUDETEX); do \
	  cp -f $$I.tex $(CTANDIR)/ ; \
	done ; \
	for I in $(INCLUDETXT); do \
	  cp -f $$I.txt $(CTANDIR)/; \
	  mv $(CTANDIR)/$$I.txt $(CTANDIR)/$$I ; \
	done ; \
	cd $(CTANDIR) ; \
	zip -ll -q -r -X $(PACKAGE).zip .
	cp $(CTANDIR)/$(PACKAGE).zip ./
	rm -rf $(CTANROOT)/

doc: $(foreach FILE,$(INCLUDEPDF),$(FILE).pdf)

localinstall: unpack
	echo "Installing files"
	TEXMFHOME=`kpsewhich --var-value=TEXMFHOME` ; \
	rm -rf $$TEXMFHOME/tex/$(PACKAGEROOT)/*.* ; \
	cp *.sty $$TEXMFHOME/tex/$(PACKAGEROOT)/ ; \
	texhash &> /dev/null

tds: doc
	echo "Creating TDS archive"
	mkdir -p $(TDSDIR)/
	rm -rf $(TDSDIR)/*
	mkdir -p $(TDSDIR)/doc/$(PACKAGEROOT)/
	mkdir -p $(TDSDIR)/tex/$(PACKAGEROOT)/
	mkdir -p $(TDSDIR)/source/$(PACKAGEROOT)/
	cp -f *.dtx $(TDSDIR)/source/$(PACKAGEROOT)/ ; \
	cp -f *.ins $(TDSDIR)/source/$(PACKAGEROOT)/ ; \
	for I in $(INCLUDEPDF) ; do \
	  cp -f $$I.pdf $(TDSDIR)/doc/$(PACKAGEROOT)/ ; \
	done ; \
	cp -f *.sty $(TDSDIR)/tex/$(PACKAGEROOT)/ ; \
	for I in $(INCLUDETEX); do \
	  cp -f $$I.tex $(TDSDIR)/doc/$(PACKAGEROOT)/ ; \
	done ; \
	for I in $(INCLUDETXT); do \
	  cp -f $$I.txt $(TDSDIR)/doc/$(PACKAGEROOT)/ ; \
	  mv $(TDSDIR)/doc/$(PACKAGEROOT)/$$I.txt $(TDSDIR)/doc/$(PACKAGEROOT)/$$I ; \
	done
	cd $(TDSDIR) ; \
	zip -ll -q -r -X $(PACKAGE).tds.zip .
	cp $(TDSDIR)/$(PACKAGE).tds.zip ./
	rm -rf $(TDSDIR)

unpack:
	echo "Unpacking files"
	for I in $(UNPACK) ; do \
	  tex $$I &> /dev/null ; \
	done

You’ll see that on Unix (where we have more tools definitely available) some things are easier. That also applies to finding the local tex root: TeX Live will almost certainly be the TeX system installed, so its tools can be called on to collect the data needed. Both of the above should work with the demonstration package code I talked about last week.

No restricted \write18 just yet!

Having posted about restricted \write18 support in TeX Live 2009 (and MiKTeX 2.8), a message to the TeX Live mailing list now tells me that for the moment there’s been a change:

… we pulled the plug and try to fix it. The problem is that
allowing epstopdf we in fact obliterate openout_any becasue
epstopdf can write everywhere.
As long as we are not able to provide a restricted epstopdf that
only allows writing to subdirectories or similar we will
unfortunately not have this feature …

So for the moment you still need to turn on \write18 explicitly if you need it (at least with TeX Live: I’d imagine that MiKTeX will be updated with the same change). I hope that a solution can be found to provide easy to use \write18 for a subset of ‘safe’ programs, but for the moment we have to wait.

The TDS and TDS zip files

In my post about working with dtx files, I made the somewhat throw-away statement

The idea of a TDS-ready zip is also popular …

I’ve been pulled up on that by e-mail, so I thought I’d consider this a bit more before looking at automating working with dtx sources.

First, what does ‘TDS’ mean? The short answer is TeX Directory Structure, but that does not really help. The idea of the TDS is to have a standard layout for the location of TeX files, so for example LaTeX .sty files go inside tex/latex/ (or more likely tex/latex/<package>/), while BibTeX style files (.bst) go inside bibtex/bst.

That’s important as both TeX Live and MiKTeX use a database to locate files, and only scan the ‘correct’ parts of the TeX installation when building the database. So if you do a local file installation and put the file in the wrong place TeX won’t find it. The result is that you need to lay things out properly if you’re installing TeX files, which can be confusing if you’re not familiar with the idea.

The TDS zip idea is very simple: rather than having just the source files in a zip, set up the documentation, extracted package, source and so on in the correct layout. The end user can then just unzip the TDS zip inside their local TeX directory to install a package (of course, they’ll still need to run texhash). As a package author, sending a user a file they can just unzip and use is much faster in the long run than sending them a bunch of files with a list of installation instructions on where everything needs to go.

The downside of the system is that the TDS zip has to be built in the first place, by the package author. With a batch script or Makefile for doing releases, that’s not an issue, but it is if everything is being done by hand. Mistakes can be a problem (even with a script, if you get it wrong!).

One argument against needing TDS zips is that both TeX Live and MiKTeX update very regularly, and so it’s easy to install a package from CTAN using the package manager of your TeX system. However, not everyone is using a burning edge system. Many Linux systems are still on TeX Live 2007, and on multi-user systems the TeX system is probably fixed by the administrator. So doing local installations is still a reality for a lot of people.

Over all, I think the idea has merit, but as a package author you do need to put in some effort to get things ‘right’. I’ll be talking about some scripting in my next post, and hopefully the ideas there will show how things can be done reliably. The overall aim is to make life easier for non-experts, and if that means a bit more effort for the more experienced TeX users then I think the trade-off is not too bad. I don’t expect everyone to agree with me!

Working with dtx files

I’ve talked a bit about the dtx file format and given an example of a skeleton dtx file. I thought I’d talk next about working with sources, which will be a bit of a scattered post but will hopefully be interesting!

Editing dtx files

As with any TeX source, you don’t have to have a special editor to work with dtx files, but it can be helpful. Many people say that Emacs (using AUC-TeX) has the best dtx editing mode of all: I’ve only tried it briefly, but the AUC-TeX homepage has the details. On Windows, WinEdt has a pretty strong DTX Submode which does similar things. As I mainly use TeXworks, I’ve made a few modifications to get something similar to those two ‘leaders’: at the moment I use the following settings for syntax highlighting:

[LaTeX DTX]

# comments
red        Y    \^\^A.*

# Guards
orange        N    %<(?:[A-Za-z0-9!\|]+|.)>
limegreen    N    %<\*(?:[A-Za-z0-9!\|]+|.)>
crimson        N    %</(?:[A-Za-z0-9!\|]+|.)>

# special characters
darkred        N    \^\^\^\^\^[0-9a-z]{5}
darkred        N    \^\^\^\^[0-9a-z]{4}
darkred        N    \^\^\^[0-9a-z]{3}
darkred        N    \^\^[0-9a-z]{2}
darkred        N    [$#^_{}&]
gray        N    ^%%.*
gray        N    ^%

# Macrocode
green        N    \\(?:begin|end)\{macrocode\}

# LaTeX environments
darkgreen    N    \\(?:begin|end)\s*\{[^}]*\}

# control sequences
blue        N    \\(?:[A-Za-z@:_]+|.)

plus a few special auto-complete entries. Not quite up with the best just yet, but it’s still early days for TeXworks.

What to document

Getting documentation right is not easy. My general approach is to try to include lots of examples, so I always load the package being talked about for the documentation. That means I can use the package ‘in place’. Unfortunately, ltxdoc does not have a built-in example environment. I use the listings package, and although it’s a bit complex looking, the following code works well:

%\lst@RequireAspects{writefile}
%\newsavebox{\LaTeXdemo@box}
%\lstnewenvironment{LaTeXdemo}[1][code and example]{^^A
%  \global\let\lst@intname\@empty
%  \expandafter\let\expandafter\LaTeXdemo@end
%    \csname LaTeXdemo@#1@end\endcsname
%  \@nameuse{LaTeXdemo@#1}^^A
%}{^^A
%  \LaTeXdemo@end
%}
%\newcommand*\LaTeXdemo@new[3]{^^A
%  \expandafter\newcommand\expandafter*\expandafter
%    {\csname LaTeXdemo@#1\endcsname}{#2}^^A
%  \expandafter\newcommand\expandafter*\expandafter
%    {\csname LaTeXdemo@#1@end\endcsname}{#3}^^A
%}
%\newcommand*\LaTeXdemo@common{^^A
%  \setkeys{lst}{
%    basicstyle   = \small\ttfamily,
%    basewidth    = 0.51em,
%    gobble       = 3,
%    keywordstyle = \color{blue},
%    language     = [LaTeX]{TeX},
%    moretexcs    = {
%      examplemacro,
%      ^^A Add you command names here!
%    }
%  }^^A
%}
%\newcommand*\LaTeXdemo@input{^^A
%  \MakePercentComment
%  \catcode`\^^M=10\relax
%  \small
%  \begingroup
%    \setkeys{lst}{
%      SelectCharTable=\lst@ReplaceInput{\^\^I}{\lst@ProcessTabulator}
%    }^^A
%    \leavevmode
%      \input{\jobname.tmp}^^A
%  \endgroup
%  \MakePercentIgnore
%}
%\LaTeXdemo@new{code and example}{^^A
%  \setbox\LaTeXdemo@box=\hbox\bgroup
%    \lst@BeginAlsoWriteFile{\jobname.tmp}^^A
%    \LaTeXdemo@common
%}{^^A
%    \lst@EndWriteFile
%  \egroup
%  \begin{center}
%    \ifdim\wd\LaTeXdemo@box>0.48\linewidth\relax
%      \hbox to\linewidth{\box\LaTeXdemo@box\hss}^^A
%        \begin{minipage}{\linewidth}
%          \LaTeXdemo@input
%        \end{minipage}
%    \else
%      \begin{minipage}{0.48\linewidth}
%        \LaTeXdemo@input
%      \end{minipage}
%      \hfill
%      \begin{minipage}{0.48\linewidth}
%        \hbox to\linewidth{\box\LaTeXdemo@box\hss}^^A
%      \end{minipage}
%    \fi
%  \end{center}
%}
%\LaTeXdemo@new{code only}{^^A
%  \LaTeXdemo@common
%}{^^A
%}

This gets pasted in at the start of the document (after the driver): not great coding style, but not too bad for this job. The idea is that I can then write something like:

%\begin{LaTeXdemo}
%  Some clever demo here
%\end{LaTeXdemo}

and the demonstration will be both typeset as code and actually used. So the user can see the input and the result of whatever I’ve designed.
Of course, if you are writing LaTeX classes or the like, then this won’t work. For my achemso class, I include a demo document in the dtx. This then gets extracted as a separate file (achemso-demo.tex), which includes lots of hints in the text and demonstrates as much as possible about the class. Again, the idea is to show how things are done by example: much better than trying to explain in the abstract.

Releasing stuff to CTAN

In my next post, I’m hoping to talk about automating the process of getting stuff ready for CTAN. So here I’ll just mention a few general ideas. One is that users shouldn’t need to read the code to use a LaTeX package (unless of course you are aiming at supporting other package authors). So I tend to typeset only the user part of the documentation. Normally, it’s a good idea to also include an index and list of changes in the pdf documentation, so a typical ‘recipe’ would be

pdflatex -draftmode "\AtBeginDocument{\OnlyDescription} \input demopkg.dtx"
makeindex -s gglo.ist -o demopkg.gls demopkg.glo
makeindex --s gind.ist -o demopkg.ind demopkg.idx
pdflatex "\AtBeginDocument{\OnlyDescription} \input demopkg.dtx"
pdflatex "\AtBeginDocument{\OnlyDescription} \input demopkg.dtx"

The idea of all this is to only typeset what is needed (hence the -draftmode in the first line), to miss out the code (\OnlyDescription), and to index both the changes and the user functions (the two makeindex lines). This recipe will turn up in the next post as the basis for doing things without needing to remember everything yourself!

CTAN like to have a zip file containing the source, documentation and ins file. They also prefer Unix line endings, so those of us working on Windows have to use something like Info-ZIP or the Swiss File Knife to alter the line endings. The idea of a TDS-ready zip is also popular, so there are normally two files to get ready. All of that is a bit awkward, especially if like me you keep having to do bug fix releases. So I always do this using an automated tool. I’ll talk about this in the next post.

TeXworks bugfixes in v0.2 “stable” branch

Jonathan Kew has released a couple of bug-fix versions on the ‘stable’ 0.2 branch of TeXworks, taking the current stable version to v0.2.2. The latest fix only affects Windows users, and is related to the ‘drag and drop’ inclusion of JPEG images. As usual, pre-compiled versions are available for Windows and Mac OS X: Linux users have to grab the source and compile their own.

TeX Live freeze on Monday (12th)

Karl Berry has posted to the TeX Live mailing list

I hope to take care of the endless last-minute updates over the next
couple days, and then freeze everything, including package updates, as
of this coming Monday (Oct 12). After that, we’ll have another few days
of testing, but only critical changes will be made. Then we’ll make the
final images for the DVD, etc.

I’ve been using TeX Live 2009 for a while on Windows and Mac OS X, and all seems pretty good. Any last changes will be bug fixes, so I’d say all looks good. Time to get those last-minute items to CTAN to make the DVD!