0

I'm writing my own .sty file. It contains its own table of contents and commands like \section{}, but nothing works because the output to the file for the table of contents does not work correctly

Here's what the output should look like:

\hyperref[mysection1]{\bfseries  3\hskip 1em\relax Section\dotfill  \pageref  {mysection1}}
\hyperref[mysection2]{\bfseries  3\hskip 1em\relax Section\dotfill  \pageref  {mysection2}}

аnd here's what it looks like:

\hyperref  [mysection3]{\bfseries  3\hskip 1em\relax Section\dotfill  \pageref  {mysection3}}
\hyperref  [mysection3]{\bfseries  3\hskip 1em\relax Section\dotfill  \pageref  {mysection3}}

Here is the code from .tex file:

\documentclass[10pt]{article}
\usepackage{cmap}
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[english,russian]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{setspace}
\usepackage{hyperref}
\usepackage{mysty}

\begin{document} \mytableofcontents

\section{Section}

\section{Section}

\end{document}

Here is the code from mysty.sty file:

\RequirePackage{amsmath}
\RequirePackage{amssymb}
\RequirePackage{setspace}
\RequirePackage{hyperref}

\newwrite\myoutput \immediate\openout\myoutput=toc.tex

\newcounter{sections} \setcounter{sections}{1}

\renewcommand{\section}[1]{%

\vspace{2ex}
\label{mysection\the\value{sections}}%
\noindent\textbf{\arabic{sections}.\quad #1}%
\write\myoutput{\hyperref[mysection\the\value{sections}]{\bfseries\the\value{sections}\quad #1\dotfill\pageref{mysection\arabic{sections}}}}%
\stepcounter{sections}

\vspace{2ex}

}

\newcommand{\mytableofcontents}{% \newpage\thispagestyle{empty} \noindent\textbf{Table of Contents}

\input{toc}

\newpage

}

\endinput

  • You are not using \immediate\write as you claim in the title of your question. – Ulrike Fischer Dec 03 '23 at 13:32
  • @UlrikeFischer If you add \immediate before \write, a lot of errors will come out – Andrew D. Dec 03 '23 at 13:38
  • write expands its arguments so you need to protect expansion but still expand the things you need but you will not get correct page numbers with \immediate\write. But why are you not using any of the facilities latex offers for section commands and writing the table of contents data? – David Carlisle Dec 03 '23 at 13:47
  • https://tex.stackexchange.com/a/115933/1090 – David Carlisle Dec 03 '23 at 13:49
  • @DavidCarlisle I need to customize all of the section commands and the view of the table of contents – Andrew D. Dec 03 '23 at 14:08
  • 1
    latex sectioning is highly customisable but this just removes all features. Apart from breaking the table of contents, you are losing all the control latex has over avoiding page breaks close to section headings or to the indentation of following paragraphs, and removing the ability to \label and \ref sections. – David Carlisle Dec 03 '23 at 14:12

2 Answers2

2

You missed \immediate before \write. The you can't be surprised that you have delayed \write.

Adding \immediate before \write without another changes yields to error, because the parameter of \write is immediately expanded. You want to expand only \the\value{sections}, nothing more.

Your line with \write in your mysty.sty should be:

    \immediate\write\myoutput
       {\string\hyperref[mysection\the\value{sections}]{\noexpand\bfseries\the\value{sections}\quad #1\string\dotfill\string\pageref{mysection\the\value{sections}}}}%
wipet
  • 74,238
  • now there is another problem, the \input command inside the \tableofcontents command does not seem to work, and at the same time \label inside the \section command works somehow strangely: \pageref to mysection2 returns 2, and \hyperref to mysection2 when clicking on the text refers to the table of contents – Andrew D. Dec 03 '23 at 15:19
  • You solved the least problem. Of course, the toc file will be cleared before it's read in, so nothing will appear in the table of contents. – egreg Dec 03 '23 at 15:35
1

It's hard to understand why you want to do manually what the LaTeX kernel does better by itself.

Anyway, doing \immediate\openout\myoutput in the .sty file has the consequence that the toc file is cleared as soon as the file is loaded, so you will get nothing in the table of contents.

You must start writing it after the table of contents (as built in the previous run) has been typeset.

You also get no anchor if you do \stepcounter{sections}. You need \refstepcounter{sections} before \label (and to not initialize the counter to 1, of course).

Another obvious weakness of the code is that you're forced to have the table of contents at the beginning. With the standard \tableofcontents you can put it anywhere.

You also need to protect commands from expansion inside \write.

Here's a working version of your code. But you should not do it yourself: use the standard tools and customize them. For instance, as noted by David Carlisle, you may well get a section title at the bottom of a page, with the text in the following page.

Check for the differences.

\documentclass[10pt]{article}
\usepackage{cmap}
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[english,russian]{babel}
%\usepackage{mysty}

\makeatletter \RequirePackage{amsmath} \RequirePackage{amssymb} \RequirePackage{setspace} \RequirePackage{hyperref}

\newwrite\myoutput \AtEndDocument{\immediate\closeout\myoutput}

\newcounter{sections}

\renewcommand{\section}[1]{% \par\vspace{2ex} \refstepcounter{sections}\label{mysection\the\value{sections}}% \noindent\textbf{\arabic{sections}.\quad #1}% \immediate\write\myoutput{% \noindent \noexpand\hyperref[mysection\the\value{sections}]{% \noexpand\bfseries\the\value{sections}\noexpand\quad #1% \noexpand\dotfill\noexpand\pageref{mysection\arabic{sections}}% }% \noexpand\par }% \par\vspace{2ex} }

\newcommand{\mytableofcontents}{% \newpage\thispagestyle{empty} \noindent\textbf{Table of Contents}\par \InputIfFileExists{\jobname.toc}{}% \newpage \immediate\openout\myoutput=\jobname.toc } \makeatother

\begin{document}

\mytableofcontents

\section{Section}

\section{Section}

\end{document}

enter image description here

egreg
  • 1,121,712
  • Thank you very much. I don't understand how to customize standard tools at a low level, I learned how to do this for headers and footers and page markup, but I haven't found a solution for other tools yet – Andrew D. Dec 03 '23 at 15:50
  • @AndrewD. For customizing section titles you can look at titlesec; for the table of contents, look at titletoc or etoc. Don't try these low level customization by hand. – egreg Dec 03 '23 at 15:56