Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a document that is structured like this:

\part{Birds}
    \chapter{North America}
        \section{West Coast}
            \mymacro{Bald Eagle}
            \mymacro{Spotted Owl}
        \section{East Coast}
        \section{Alaska}
    \chapter{South America}
        \section{Peru}
        \section{Brazil}
\part{Bears}
    \chapter{Canada}
  • The preamble appears in a separate file.
  • All of the content is added using a custom macro, \mymacro, so each item gets a single line.

How can I alphabetically sort all of the parts, chapters, sections, and macros in the document, at each level? E.g., the above would be sorted like this:

\part{Bears}
    \chapter{Canada}
\part{Birds}
    \chapter{North America}
        \section{Alaska}
        \section{East Coast}
        \section{West Coast}
            \mymacro{Bald Eagle}
            \mymacro{Spotted Owl}
    \chapter{South America}
        \section{Brazil}
        \section{Peru}
share|improve this question

3 Answers 3

up vote 3 down vote accepted

AFAIK, ConTeXt cannot sort your input file.

You might be able to get a working version by using \startchapter ... \stopchapter version of section heads, storing each section body in a buffer, and using registers to soft each level.

But, I think that if you want to sort your input, then TeX is the wrong input language. Most XML processing tools (including the XML parser in ConTeXt) have access to the complete XML tree, which makes it easier to sort and move blocks. So, for such data, it is better to use XML as an input language.

If your input file follows a restricted TeX grammar, then you may also parse it using a higher-level programming language and sort things there.

Another option will be to simply input your text as a Lua table:

\startluacode
thirddata = thirddata or {}
thirddata.contents = {
   "bears" = { -- Part level
        "Canada" = {}, -- Chapter level  
   },
   "birds" = { -- Part level
        "North America" = { -- Chapter level
           "West Coast" = {
                "Bald Eagle",
                "Spotted Owl",
           },
           "East Coast" = {},
           "Alaska" = {},
         },
        "South America" = { ---
         --- ....
         },
    }
 }
\stopluacode

You can then write a ConTeXt Lua Document to convert this data to a TeX document on the fly and process it.

share|improve this answer

I'm rather certain that it should be possible in context. You could write the entries to a csv-file or build a database in the memory and then sort it with TeX or lua. In LaTeX one could e.g. use datatool: (I'm assuming that there is always at least one \section entry to keep the code simple, and I didn't try to protect possible fragile commands in the values. The code should only show the princip):

\documentclass{article} 
\usepackage{datatool,ifthen}
\DTLnewdb{animals}
\renewcommand\part[1]{%
 \def\currenttype{#1}}%


 \newcommand\chapter[1]{%
  \def\currentlocation{#1}}

\renewcommand\section[1]{%
  \DTLnewrow{animals}
  \DTLnewdbentry{animals}{type}{\currenttype}
  \DTLnewdbentry{animals}{location}{\currentlocation}
  \DTLnewdbentry{animals}{sublocation}{#1}
  }


\begin{document}     
\dtlexpandnewvalue
\part{Birds} 
     \chapter{North America}
        \section{West Coast}
        \section{East Coast}
        \section{Alaska}    
   \chapter{South America}
        \section{Peru}
        \section{Brazil}
    \chapter{Germany}
      \section{North}
\part{Bears}
    \chapter{Canada}
         \section{Lake}

Unsorted database:

\DTLdisplaydb{animals}

\bigskip

Sorted entries:

\DTLsort{type,location,sublocation}{animals}%
\begin{tabular}{lll}
\bfseries type &
\bfseries location & \bfseries sublocation 
\DTLforeach{animals}{%
\type=type,\location=location,\sublocation=sublocation}{%
\\
\type&\location &\sublocation}
\end{tabular}

\end{document}
share|improve this answer
    
IIUC, the content of each section should also move. Does the above code work if each section has arbitrary content. –  Aditya Apr 15 '12 at 13:54
    
@Adity: Village wrote "All of the content is added using a custom macro, \mymacro," so all is needed is another level. Longer text parts should better be put in external files so that the main text keeps its clear "database like" structure. –  Ulrike Fischer Apr 15 '12 at 14:09
    
OK. But I still think that TeX is the wrong language to create a database tree. I added a hint about using Lua tables in my answer. –  Aditya Apr 15 '12 at 17:48
1  
@Aditya: There are certainly better tools for large databases. But being able to keep everything "inside" TeX can have some advantage. I have quite often used (small) LaTeX-databases e.g. for serial letters. –  Ulrike Fischer Apr 15 '12 at 18:42

Easiest and least harmful way I can think of is to intercept the ordinary structure macros and do the sorting part in Lua. If you do the grouping right you won’t notice the difference. I’ve outlined an annotated proof of concept that works for your example. Basically, all you have to do is to specify a list of structure elements that should be sorted as well as your command for typesetting the entries (\mymacro as you called it, here I stuck with plain \entry). The latter takes one compulsory argument but the code could be easily rewritten to allow optional args as well.

The configuration macro \setupsortstructure expects the two parameters sections (type comma list) and entry (macro):

\setupsortstructure[
   sections={part,chapter,section,subsection},
   entrycommand=\entry,
]

Of course, the entry command needs to be properly defined. From the example:

%%% The macro for entries.
\definehighlight [entryhighlight] [style=italic]
\define[1]\entry{%
  \leavevmode
  \noindentation
  \hbox to2em{\hfill·}\hskip.5em
  \entryhighlight{#1}%
  \blank[line]%
}

And you’re done! Insert your content between \starttext and \stoptext, and you will get something like this: sorted document structure

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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