3

pre-notice: I tried very hard to find an answer to this question and searched with various different terms. But I still have the tiny feeling that someone asked this before, because it is a very general and valid question. So if it is asked before and please direct me to the relevant topic and accept my apologies :)

The problem is easy to state but proved extremely hard to solve (at least for a TeX newbie such as myself): I want to know certain things about my tex document such as chapter and section font types and sizes.

Is there a way to extract this information, for instance, with a package that displays style information in a structured format? If memory serves there was a package for displaying page margins but I failed to find one for displaying styles.

I am aware that some styles are user-defined and it can be parsed from document preamble. I have two problems with that. If I own (created) the tex document, I might want to check whether everything is in place and as planned, easily. If I don't own the tex document and want to use some style in that document I might end up with doing a lot of guessing. And obviously there are some styles default to some packages or document styles that I need to dig into their source. I rather not do that if I can get away with something more subtle :)

Finally, let me rephrase my question in a 'sacrilegious' way. In MS Word when I click on some text I can see whether it is Calibri or Arial, font size, bold and italic or not, exact color, even paragraph parameters and other stuff. I require something similar for TeX documents.

edit: I have one more analogy: I want for TeX what Inspect Element is for HTML and CSS elements.

  • The used fonts can be retrieved from the pdf (viewer) under Properties – user31729 Mar 21 '15 at 19:24
  • Yes I can get a list of fonts using Adobe Reader (could not find it on Mac's Preview). It is more than nothing, but still not in the level of detail I'd like. But thank you for bringing that suggestion. – berkorbay Mar 21 '15 at 19:31
  • 1
    It isn't clear what answer you want here, other than the source code of the class file you are using. \chapter for example will typically be defined to involve spacing before and after the head, alignment of the heading, setting up information for the table of contents, it may include an image or quotation or any other details required by the class. Other than the source code of the class it isn't clear how any of this information could be returned. – David Carlisle Mar 21 '15 at 21:41
  • 2
    If it was originally specified using titlesec, getting those settings back is reasonable, if you are asking for some automatic tool to parse arbitrary tex code implementing a heading and work out what it is doing, then I doubt that is possible. – David Carlisle Mar 22 '15 at 9:18
  • 1
    I'm not clear what you are trying to get information from: the .tex source or the .dvi/.ps/.html/.pdf output? At one point you say you might not have the source, which suggests the latter. But then you say that parsing the source shouldn't be too onerous, which suggests the former. – cfr Mar 25 '15 at 1:34
10

Short answer, no this is not possible.

It is not possible to automatically even locate the definition of a section heading, without worrying about how to parse that definition to work out what fonts are being used.

Take the standard article class for example. in there you will find

\newcommand\section{\@startsection {section}{1}{\z@}%
                                   {-3.5ex \@plus -1ex \@minus -.2ex}%
                                   {2.3ex \@plus.2ex}%
                                   {\normalfont\Large\bfseries}}

So if you know what the arguments of \@startsection mean then you know the spacing and some details about the font choice. Exactly what font is \normalfont depends on what font packages and declarations are being used.

But to take the first class I tried that is not in the core latex distribution, the koma scrartcl class.

It took me a while to find the definition of \section (I don't really know the details of this class) there is no obvious definition of \section instead you find

\DeclareSectionCommand[%
  style=section,%
  level=1,%
  indent=\z@,%
  beforeskip=-3.5ex \@plus -1ex \@minus -.2ex,%
  afterskip=2.3ex \@plus.2ex,%
  tocindent=0pt,%
  tocnumwidth=1.5em%
]{section}

Note the lack of \ in {section}. unlike \@startsection which is defined in the latex format, \DeclareSectionCommand is defined in this file so the only way the proposed parser would recognise that this declaration is in fact defining \section would be for it to parse its definition which is

\newcommand*{\DeclareSectionCommand}[2][]{%
  \edef\reserved@a{%
    \noexpand\FamilyStringKey[.dsc]{KOMAarg}{style}{%
      \expandafter\noexpand\csname scr@#2@style\endcsname
    }%
  }\reserved@a
  \scr@ifundefinedorrelax{scr@local@levelincrease}{%
    \RelaxFamilyKey[.dsc]{KOMAarg}{increaselevel}%
  }{%
    \FamilyCounterMacroKey[.dsc]{KOMAarg}{increaselevel}[1]%
                          {\scr@local@levelincrease}%
  }%
  \scr@ifundefinedorrelax{scr@local@leveloffset}{%
    \edef\reserved@a{%
      \noexpand\FamilyCounterMacroKey[.dsc]{KOMAarg}{level}{%
        \expandafter\noexpand\csname #2numdepth\endcsname}%
    }\reserved@a
  }{%
    \edef\reserved@a{%
      \noexpand\DefineFamilyKey[.dsc]{KOMAarg}{level}{%
        \noexpand\FamilySetCounterMacro{KOMAarg}{level}{%
          \expandafter\noexpand\csname #2numdepth\endcsname
        }%
        \unexpanded{%
          {\numexpr ##1+\scr@local@leveloffset\relax}%
          \edef\scr@local@leveloffset{%
            \the\numexpr\scr@local@leveloffset+\scr@local@levelincrease\relax
          }%
        }%
      }%
    }\reserved@a
  }%
  \edef\reserved@a{%
    \noexpand\FamilyLengthMacroKey[.dsc]{KOMAarg}{indent}{%
      \expandafter\noexpand\csname scr@#2@sectionindent\endcsname}%
  }\reserved@a
  \edef\reserved@a{%
    \noexpand\FamilyLengthMacroKey[.dsc]{KOMAarg}{beforeskip}{%
      \expandafter\noexpand\csname scr@#2@sectionbeforeskip\endcsname}%
  }\reserved@a
  \edef\reserved@a{%
    \noexpand\FamilyLengthMacroKey[.dsc]{KOMAarg}{afterskip}{%
      \expandafter\noexpand\csname scr@#2@sectionafterskip\endcsname}%
  }\reserved@a
  \edef\reserved@a{%
    \noexpand\DefineFamilyKey[.dsc]{KOMAarg}{font}{%
      \noexpand\IfExistskomafont{#2}{%
        \noexpand\setkomafont
      }{%
        \noexpand\newkomafont
      }{#2}{####1}%
      \noexpand\FamilyKeyStateProcessed
    }%
  }\reserved@a
  \FamilyStringKey[.dsc]{KOMAarg}{counterwithin}{\scr@local@counterwithin}%
  \let\scr@local@counterwithin\relax
  \scr@ifundefinedorrelax{scr@local@tocleveloffset}{%
    \edef\reserved@a{%
      \noexpand\FamilyCounterMacroKey[.dsc]{KOMAarg}{toclevel}{%
        \expandafter\noexpand\csname #2tocdepth\endcsname}%
    }\reserved@a
  }{%
    \edef\reserved@a{%
      \noexpand\DefineFamilyKey[.dsc]{KOMAarg}{toclevel}{%
        \noexpand\FamilySetCounterMacro{KOMAarg}{toclevel}{%
          \expandafter\noexpand\csname #2tocdepth\endcsname
        }%
        \unexpanded{%
          {\numexpr ##1+\scr@local@tocleveloffset\relax}%
          \edef\scr@local@tocleveloffset{%
            \the\numexpr\scr@local@tocleveloffset+\scr@local@levelincrease\relax
          }%
        }%
      }%
    }\reserved@a
  }%
  \edef\reserved@a{%
    \noexpand\FamilyLengthMacroKey[.dsc]{KOMAarg}{tocindent}{%
      \expandafter\noexpand\csname scr@#2@tocindent\endcsname}%
  }\reserved@a
  \edef\reserved@a{%
    \noexpand\FamilyLengthMacroKey[.dsc]{KOMAarg}{tocnumwidth}{%
      \expandafter\noexpand\csname scr@#2@tocnumwidth\endcsname}%
  }\reserved@a
  \FamilyExecuteOptions[.dsc]{KOMAarg}{#1}%
  \begingroup
    \scr@ifundefinedorrelax{#2numdepth}{%
      \scr@declaresectioncommanderror{#2}{section level}{level}%
    }{}%
    \scr@ifundefinedorrelax{scr@#2@sectionindent}{%
      \scr@declaresectioncommanderror{#2}{section indent}{indent}%
    }{}%
    \scr@ifundefinedorrelax{scr@#2@sectionbeforeskip}{%
      \scr@declaresectioncommanderror{#2}{before section skip}{beforeskip}%
    }{}%
    \scr@ifundefinedorrelax{scr@#2@sectionafterskip}{%
      \scr@declaresectioncommanderror{#2}{after section skip}{afterskip}%
    }{}%
    \IfExistskomafont{#2}{}{%
      \scr@declaresectioncommanderror{#2}{font}{font}%
    }{}%
    \scr@ifundefinedorrelax{scr@#2@tocindent}{%
      \scr@declaresectioncommanderror{#2}{toc entry indent}{tocindent}%
    }{}%
    \scr@ifundefinedorrelax{scr@#2@tocnumwidth}{%
      \scr@declaresectioncommanderror{#2}{toc entry number
        width}{tocnumwidth}%
    }{}%
  \endgroup
  \@firstofone{%
    \@ifundefined{c@#2}{\newcounter{#2}}{}%
    \ifx\scr@local@counterwithin\relax
    \else\ifx\scr@local@counterwithin\@empty
        \@namedef{the#2}{\arabic{#2}}%
      \else
        \@removefromreset{#2}{\scr@local@counterwithin}%
        \@addtoreset{#2}{\scr@local@counterwithin}%
        \expandafter\def\csname the#2\expandafter\endcsname{%
          \csname the\scr@local@counterwithin\endcsname.\arabic{#2}}%
      \fi
    \fi
    \@ifundefined{#2format}{%
      \@namedef{#2format}{\csname the#2\endcsname\autodot\enskip}%
    }{}%
    \ifstr{\csname scr@#2@style\endcsname}{}{%
      \ClassInfo{\KOMAClassName}{%
        not defining `\expandafter\string\csname #2\endcsname' due
        to\MessageBreak
        empty section style%
      }%
    }{%
      \scr@ifundefinedorrelax{scr@#2@style}{%
        \ClassWarning{\KOMAClassName}{using default section style}%
        \@namedef{scr@#2@style}{section}%
      }{}%
      \expandafter\edef\csname #2\endcsname{%
        \noexpand\scr@ifundefinedorrelax{%
          scr@start\csname scr@#2@style\endcsname}{%
          \noexpand\ClassError{\noexpand\KOMAClassName}{%
            section style `\csname scr@#2@style\endcsname' not defined}{%
            A not yet defined section style `\csname scr@#2@style\endcsname'
            has been setup for\MessageBreak
            `\expandafter\string\csname #2\endcsname'. You should either setup
            another style\MessageBreak
            or define the style.\MessageBreak
            If you'll continue, style `section' will be used as an emergency
            fallback.%
          }%
          \noexpand\def\expandafter\noexpand\csname scr@#2@style\endcsname
          {section}%
        }{}%
        \expandafter\noexpand
        \csname scr@start\csname scr@#2@style\endcsname\endcsname
        {#2}%
        \expandafter\noexpand\csname #2numdepth\endcsname
        \expandafter\noexpand\csname scr@#2@sectionindent\endcsname
        \expandafter\noexpand\csname scr@#2@sectionbeforeskip\endcsname
        \expandafter\noexpand\csname scr@#2@sectionafterskip\endcsname{%
          \noexpand\ifdim\noexpand\glueexpr
          \expandafter\noexpand\csname scr@#2@sectionbeforeskip\endcsname
          <\noexpand\z@
            \unexpanded{%
              \ifnum \scr@compatibility>\@nameuse{scr@v@2.96}\relax
                \setlength{\parfillskip}{\z@ plus 1fil}%
              \fi
            }%
          \noexpand\fi
          \unexpanded{%
            \raggedsection\normalfont\sectfont\nobreak\usekomafont{#2}%
          }%
        }%
      }%
    }%
    \@ifundefined{DeclareSectionNumberDepth}{%
      \@ifundefined{#2markformat}{%
        \@namedef{#2markformat}{\csname the#2\endcsname\autodot\enskip}%
      }{}%
      \@ifundefined{#2mark}{%
        \expandafter\let\csname #2mark\endcsname\@gobble
      }{}%
    }{%
      \DeclareSectionNumberDepth{#2}{\csname #2numdepth\endcsname}%
    }%
    \scr@ifundefinedorrelax{#2tocdepth}{%
      \expandafter\let\csname #2tocdepth\expandafter\endcsname
      \csname #2numdepth\endcsname
    }{}%
    \expandafter\providecommand\expandafter*%
    \csname add#2tocentry\endcsname[2]{%
      \addtocentrydefault{#2}{##1}{##2}%
    }%
    \scr@ifundefinedorrelax{l@#2}{%
      \expandafter\edef\csname l@#2\endcsname{%
        \noexpand\bprot@dottedtocline
        \expandafter\noexpand\csname #2tocdepth\endcsname
        \expandafter\noexpand\csname scr@#2@tocindent\endcsname
        \expandafter\noexpand\csname scr@#2@tocnumwidth\endcsname
      }%
    }{}%
  }%
}

and note that in there the line \expandafter\edef\csname #2\endcsname{ means that the second argument being {section} results in \section being defined.

Getting from there to working out anything about which fonts are being used seems tricky. a human reader may guess something from key names such as afterskip=2.3ex \@plus.2ex, but the key names are just arbitrary names, so any guesses are just guesses unless you have traced the code to see what they do.

And the above is just to consider one command, \section in two classes, article and scratcl.

  • Although I hope that you are wrong with all my heart, I must admit I have no alternative proposition. Perhaps in the future, someone with the proper obsession and sufficient technical expertise could come up with a solution. I am signing it as the proper answer, concluding the question. – berkorbay Mar 24 '15 at 21:58
  • @berkorbay It's like hoping God's wrong... – cfr Mar 25 '15 at 1:37
  • @cfr Not at all. By the way, I meant no offense to anyone in my previous comment (now that I see it can be perceived that way thanks to online communication). I merely wanted to say maybe someone in the future will look into it seriously. – berkorbay Mar 25 '15 at 16:14
  • 2
    @berkorbay It's unlikely anyone will look into it too seriously as I suspect it's provably impossible. What is more likely is that latex3 (or some other suitable successor) will have a more powerful declarative styling mechanism (see the xtemplate package for initial drafts) which will mean that most, and hopefully all, classes will not need to be executing arbitrary imperative code in order to specify a section style. If all headings are made by calling a known number of parametrised templates, then answering your question just means looking up the parameters used. – David Carlisle Mar 25 '15 at 16:51
1

This just concerns the 'sacrilegious' bit.

One reason that you can recover precise formatting information for particular document elements easily in Word is precisely that Word does not use semantic mark-up.

Indeed, Word does not even have styles in the sense that LaTeX does. From the document author's point of view, Word's styles are derivative - it is the formatting which is basic. From the document author's point of view, LaTeX's styles are basic - it is the formatting which is derivative.

So when you look at the 'source' of a Word document, insofar as there is such a thing, it does not necessarily tell you the functional role of each document element. A heading may use a style, if the author is well-organised and disciplined. Or it may not. But it is hard work to keep the format of document elements aligned with styles. You have to stop yourself doing the natural thing which is to directly change the format of the element in front of you.

In contrast, it is easy to use use styles in a LaTeX document because the styles are right there. The specific formatting is not right in front of you. And just as it is not right there in front of you with the document element, it is not right there with the document element for a parser, either. When you look at a document element in the source, what you see is its functional role, and it is this semantic layer which you manipulate when writing document content.

And this is a good thing!

If you don't care about the advantages, of course, you can just mark-up the document elements directly. In that case, the basic formatting will be right there, and a parser will be able to determine it fairly easily. Of course, it won't be able to easily tell that the element is a heading or whatever, but it will be able to tell that it is large, bold etc. If you go further, you could directly select particular fonts and sizes, and then the parser could give you more information. The more you avoid semantic mark-up, the more the parser will be able to tell you. That is not a coincidence and it is not a (good) reason to eschew such mark-up!

  • Thanks for the explanation. I love to take the full advantage of LaTeX styles and love that people can use without the worry of altering the way of things. The problem begins when I try to make a default style of my own. When I like a color, I can see its code with a color picker. When I like an HTML element, I can see the basics from Firebug. But it is hard with LaTeX documents. I encountered many "How can I do my layout/fonts like this?" questions in SE. And, to me, it is like "What is the color code of this?" for an image to me. Unfortunately, the answer was negative. – berkorbay Mar 25 '15 at 16:20
  • @berkorbay I understand that. What I meant was: you can't have the one without the other any more than you can have hills without valleys. Note that you can't pull the style information from the .html source either if it is using .css, say. The situation really isn't different. (A PDF viewer can tell you the font information etc., the colour and so on. That is, the rendered result can be inspected here, as well.) – cfr Mar 25 '15 at 22:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.