5

Background:

As per my earlier question, Can't get real currfile if used in precompiled .fmt file, I am trying to speed up compilation by generating a .fmt file. The example below tests that the value of the token \MyToken is set to the portion of the file name between the two dashes.

I am not getting the desired behavior when I use TeXShop and the precompiled .fmt file. But, things work as expected if I use TeXworks, or command line compilation. I suspect something is not quite right with the MyLaTeX.engine script invoked by TeXShop, but don't know for sure.

After saving MyPreamble.tex defined below, I first compile the preamble via the command line:

    pdflatex -ini -jobname=MyPreamble "&pdflatex MyPreamble.tex\dump"

Then I try to use this preamble in four different ways to process foo-x-bar.tex:


  1. Command Line compilation (works):

    pdflatex  --file-line-error --shell-escape -fmt=MyPreamble -recorder --synctex=1                   foo-x-bar.tex
    

    yields the correct result (no red error message):

    enter image description here

    Furthermore, the following (change how the file name is specified, see the "Update" section below) also works:

    pdflatex  --file-line-error --shell-escape -fmt=MyPreamble -recorder --synctex=1                    ./foo-x-bar.tex
    
  2. Using TeXworks (works):

    With MyLaTeX configured as

    enter image description here

    I get identical results as command line compilation (again, no red error message).

  3. Using TeXShop (does not work):

    With TeXShop things are not quite the same. I have the following file saved as MyLaTeX.engine:

    #!/bin/sh
    bfname=$(dirname "$1")/"`basename "$1" .tex`"
    pdflatex --file-line-error --shell-escape -fmt=MyPreamble -recorder --synctex=1 "$bfname"
    

    and invoking MyLaTeX from TeXShop, I get the dreaded red error message:

    enter image description here

  4. Compiling the foo-x-barComplete.tex, which is simply:

    \input{MyPreamble.tex}
    \input{foo-x-bar.tex}
    

    directly via LaTeX on TeXShop, and pfdlatex on TeXworks, things also work fine (no red error message).


So, the problem only occurs on TeXShop with the precompiled .fmt file.


Update:

  • After posting the question, I do see one difference in the TeXShop run in that the file name is prefixed with ./. And I am extracting the text between the first and second dash with:

    \StrBefore{\themainfile}{.}[\CurrentFileName]%
    \StrBetween[1,2]{\CurrentFileName}{-}{-}[\ExtractedValue]
    

    This seemed to be the problem (since there are now two dots in the file name). So, I attempted the obvious fix which is to extract the file name before .tex:

    \StrBefore{\themainfile}{.tex}[\CurrentFileName]%
    

    Now I get identical results with both TeXShop and TeXworks, but now both show the dreaded error messages!!!

    Ok, so the fix lies in this code, or the .engine file.

    However it should be noted that the command line invocation with a leading ./ before the file name does not have a problem.

Temporary Solution:

Found a temporary solution:

    \StrBetween[1,2]{\themainfile}{-}{-}[\ExtractedValue]%

but I would prefer to find a method that extracts this from the file name with the extension removed, which is what the above code attempts to do.


Code: MyPreamble.tex:

% Based on egreg's answer at https://tex.stackexchange.com/questions/80453/cant-get-real-currfile-if-used-in-precompiled-fmt-file
\documentclass{article}
\usepackage{xcolor}
\usepackage{xstring}
\usepackage{lipsum}
\usepackage[realmainfile]{currfile}% 

\newcommand*{\Debug}[1]{\par\noindent\textcolor{blue}{#1}\par}%
\newcommand*{\Error}[1]{\par\noindent\textcolor{red}{#1}\par}%

\newtoks{\MyToken}
\MyToken={oo}% set default value
\AtBeginDocument{%
    \getmainfile
    \Debug{Debug: themainfile = "\themainfile"}%
    \StrBefore{\themainfile}{.}[\CurrentFileName]% 
    \Debug{Debug: CurrentFileName = "\CurrentFileName"}%
    \StrBetween[1,2]{\CurrentFileName}{-}{-}[\ExtractedValue]%
    \Debug{Debug: ExtractedValue = "\ExtractedValue"}%
    %
    %\StrBetween[1,2]{\jobname}{-}{-}[\ExtractedValue]% this works
    \IfStrEq*{\ExtractedValue}{\the\MyToken}{}{%
        \Error{Error: MyToken (middle) was "\the\MyToken",
                but was expected to be "\ExtractedValue".}%
    }%
}
%% ----- preamble ends here

Code: foo-x-bar.tex:

% This file need to be named in three parts separated by two dashes.
% This need to be set to be the value in between the two dashes. So,
% if this file is named "foo-x-bar.tex", then this needs to be "x"
\MyToken={x}%

\begin{document}
    \lipsum[1]
\end{document}

Code:

6
  • File name manipulation is always tricky! Remember that ./../Folder/./././../././Folder/file.tex is a valid name of a file in the current folder, as long as it's name is Folder ;)
    – yo'
    Nov 12, 2012 at 8:08
  • @tohecz: Well, yeah, but that is why I thought getting the string before .tex instead of before the . should have worked. I am not looking for a general solution that will cover all wacky cases of file names. So, I am thinking that if perhaps the bash script would pass the file name to pfdlatex without the leading ./ then it might just work... Nov 12, 2012 at 8:14
  • You are adding the ./ with bfname=$(dirname "$1")/"`basename "$1" .tex`" Try with bfname=$(basename "$1".tex) or, better yet, bfname="$1" (I don't see why extracting what's before the extension and adding the extension again).
    – egreg
    Nov 12, 2012 at 21:37
  • @egreg: That certainly does the job with TeXShop, but only if I use \StrBefore{\themainfile}{.}[\CurrentFileName], which is what I was originally doing since there was only one . to deal with, and your suggestion here does. So, this seems like an answer. As an aside, why does it fail with if I instead use \StrBefore{\themainfile}{.tex}[\CurrentFileName]. Nov 12, 2012 at 21:45
  • @egreg: You should add that as answer so we can mark this as being answered. Jan 21, 2013 at 23:30

2 Answers 2

2

When the file is in the same directory, which is the case here,

$(dirname "$1")

returns .; so

bfname=$(dirname "$1")/"`basename "$1" .tex`"

when the file is foo-x-bar.tex stores

./foo-x-bar.tex

as the value of bfname. Just use

bfname="$1"

(or use directly $1, of course). Indeed with

bfname="`basename "$1" .tex`"

you'd be removing the extension just to reinsert it afterwards.

0

It is a quite old post but a more general and most simple answer is worth providing it here.

I never used TeXShop (no Mac at hand) but what follows works well in TeXworks and TeXmaker on both Windows and Linux, and also from older versions of Winedt.

The solution is twofold :

  1. Fist of all, keep in mind that the TeX "old fashion" to provide a non-standard format is based on the & (ampersand) key. This can be used on the command line, or as the very first line of the latex file e.g as : %&"myCustonFormat" Notice the % which followed by & acts as a magic comment which is passed to (la)tex, exactly as it would be done from the command line.
  2. Secondly, the creation of the custom format is mostly simplified by the mylatexformat.ltx TeX program This program does the whole job needed to create the format with the command line:

    pdflateX -initialize -jobname="myCustonFormat" "&pdflatex" mylatexformat.ltx "mySourceFile.tex"
    

I am used to work with a per-project-custom-format named as the main file and use:

pdflateX -initialize -jobname="myFile" "&pdflatex" mylatexformat.ltx "myFile.tex"

This command can be configured as typesetting tool in TeXworks as shown on this picture:

TeXworks config MakeCustom ormat

Finally a MWE is :

%&"mwe"
% !TEX encoding = UTF-8
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{tikz}
\csname endofdump\endcsname
\setcounter{secnumdepth}{1}
\begin{document}
\section{First}
\subsection{subsection}
Lorem ipsum dolor sit amet, consectetur adipiscing elit...
\end{document}

In this code I included the heavy pgf/tikz package in the preamble, to be incorporated in the custom format, while the \setcounter{secnumdepth}{1}, being placed after the \csname endofdump\endcsname, is not included in the format, and can therefore be modified without to need to rebuild the custom format. The second line is a TeWworks-style magic command interpreted by the editor only, in contrast to the first one which is interpreted by the (pdf)(la)tex compiler.

Of course the format created here by using the above shown typesetting tools will be called mwe.fmt, but can be renamed. If oen intend to create a sytem- or user-wide custom format, it is worth using one time the command line, thus providing a more meaningful jobnameto be used to name the format.

1
  • As diplayed in OP, le initex option in TeXLive is -ini while it is -initialize in MiKTeX. I also observed that when the custom format is declared on the very first line or the source file, it should be quoted in MiKteX and not quoted in TeXLive (tested on TL 2015 and 2013 on Linux).
    – Jhor
    Feb 21, 2018 at 11:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .