# Macro to format text

Good morning, I have the following problem, I have a file with 8000 questions in the following format:

COD: 7
¿A qué número de revoluciones se alcanza la potencia máxima de un motor?
A Al número de revoluciones a las que gira el motor en el momento de arrancarlo.
B A bajas revoluciones.
C A un número intermedio de revoluciones.
D A un número de revoluciones próximo al máximo.
RESPUESTA: D
NORMA: Sin referencia


and wanted to leave it in this format:

\begin{description}
\item[COD: 7] ¿A qué número de revoluciones se alcanza la potencia máxima de un motor?
\begin{enumerate}
\item  Al número de revoluciones a las que gira el motor en el momento de arrancarlo.
\item  A bajas revoluciones.
\item \textbf{A un número intermedio de revoluciones.}
\item A un número de revoluciones próximo al máximo.
RESPUESTA: D
NORMA: Sin referencia
\end{enumerate}
\end{description}


Can advise me any macro or other way to do it faster?

-
Welcome on tex.sx! You should try to narrow your problem as much as possible : for example, what syntax for the macro do you expect? What is supposed to be recognised as delimiters between the different "blocks"? How do you want to tell the macro/tool that you need the third item bold? Etc, etc. It will help you getting a solution here (since nobody can do that work for you), and it may also help you figure out a path to a solution by yourself. –  T. Verron Jan 4 '13 at 11:46
This seems to be a job for your text editor, rather than for TeX. Or write an awk or sed script that adds the missing markup. –  Marco Jan 4 '13 at 11:49
Do you require the parsing of the plain text file to be done in TeX, with the result being typeset as if it were marked up in your second example, or do you want to simply use an external tool such as sed or perl to convert the plain text file to TeX (this is likely to be easier) Also what in the input determines that C is made bold? –  David Carlisle Jan 4 '13 at 11:50

A simple semi-manual solution could be search and replace the fixed string as "COD:" at the beginning of the line, to adapt these strings to something that can be understood by a LaTeX converter/generator.

There are several tools for the second step and probably hundreds for the first, so I will just expose one way that I know in Linux, but with little imagination can be adapted in many ways to other tools and operative systems.

First step: Seearch & replace "COD:","\nA ", \nB ", etc. with gedit or any other tool, but preferably with one that can find end of lines (\n) and tabulations (\n), to left the text with this format:

* COD: 7
¿A qué número de revoluciones se alcanza la potencia máxima de un motor?
^^ Al número de revoluciones a las que gira el motor en el momento de arrancarlo.
++ A bajas revoluciones.
++ A un número intermedio de revoluciones.
++ A un número de revoluciones próximo al máximo.
N:RESPUESTA: D
N:NORMA: Sin referencia


Second step: Convert to LaTeX with SDF (available in official packages at least in Debian and Ubuntu distributions).

$sdf +sdf2latex_ yourfile.txt  The ouput is a yourlife.tex but without preamble and document class, so you must include at least: \documentclass[spanish]{article} \usepackage{babel} \usepackage[utf8]{inputenc} % problems? try latin9  The raw ouput is: %%% This file was generated using SDF$version by
%%% Ian Clatworthy (ianc@mincom.com) and the 2latex_ driver
%%% $Id: tolatex.pl,v 1.1.1.2 1998/03/22 09:39:20 valerio Exp valerio$
%%% written by Valerio Aimale <valerio@svpop.com.dist.unige.it>.
%%% SDF is freely available from http://www.mincom.com/mtr/sdf

\begin{document}

\begin{itemize} % Level 1
\item COD: 7 ¿A qué número de
revoluciones se alcanza la potencia máxima de un motor?

\begin{enumerate} % Level 2
\item Al número de revoluciones a las que
gira el motor en el momento de arrancarlo.

\item A bajas revoluciones.

\item A un número intermedio de revoluciones.

\item A un número de revoluciones próximo al máximo.

\end{enumerate}
\end{itemize}

RESPUESTA: D

NORMA: Sin referencia

\end{document}


After adding the preamble, you can compile to obtain this result:

This is not exactly as your example, because there are not a description environments but itemize. As far I know SDF manage only unordered or numbered list, but change this is a simple search and replace in all the document.

The manual part could be enclose with [ ] "COD:7" and mark in bold font the correct answer, but with a editor with macro language as Nedit it could be easily automatized in five setps. If you do not have a good editor, see this comparative.

-

Yes, it's a job for a skript or a small program and not for TeX. You can do this with several tools: a small shell script, a parser generator or a small program like I did it her.

I have chosen Java as programming language. I assume that each of your questions has 8 lines. I simply read them in from a file call questions.txt, parse them and write some TeX code (questions.tex and questionsBody.tex).

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class test {

/**
*  Name of the main output file
*/
private final static String FILE_NAME = "questions.tex";

/**
*  Name of the body file which is included into the main output file
*/
private final static String FILE_NAME_BODY = "questionsBody.tex";

/**
*  Name of the input file
*/
private final static String INPUT_FILE_NAME = "questions.txt";

/**
* The main output file where the generated latex code will be written into.
*/
private static File outputFileBody;

/**
*
*/
private static BufferedWriter outputStreamBody;

/**
* reads the input file line by line and converts them to tex code
*/
private static void convertDoc(File inFile) throws IOException {
String buf;
String[] buf2 = new String[8];
while ((buf = inputStreamR.readLine()) != null) {
buf2[0] = buf;
convertLine(buf2);
System.out.print(".");
}
}

/**
* convert a single question to TeX code and write them to the output stream
*/
private static void convertLine(String[] buf2) throws IOException {
outputStreamBody.write("\\begin{description}\n");
outputStreamBody.write("\\item["+buf2[0]+"] "+buf2[1]+"\n");
outputStreamBody.write("\\begin{enumerate}\n");
outputStreamBody.write("\\item "+buf2[2].substring(2)+"\n");
outputStreamBody.write("\\item "+buf2[3].substring(2)+"\n");
outputStreamBody.write("\\item \\textbf{"+buf2[4].substring(2)+"}\n");
outputStreamBody.write("\\item "+buf2[5].substring(2)+".\n");
outputStreamBody.write(buf2[6]+"\n");
outputStreamBody.write(buf2[7]+"\n");
outputStreamBody.write("\\end{enumerate}\n");
outputStreamBody.write("\\end{description}\n\n");
}

/**
* the main function
* @param args
*/
public static void main (String[] args)
{
System.out.println ("Start converting\n");
String userDir = System.getProperty("user.dir") + File.separator;
initOutputFiles(userDir);

File inFile = new File (userDir+INPUT_FILE_NAME);
if(inFile!=null) {
try {
convertDoc(inFile);
outputStreamBody.flush ();
outputStreamBody.close ();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println ("\nFinished");
System.exit (0);
}

private static void initOutputFiles (String path) {
try
{
outputFileBody = new File(path + FILE_NAME_BODY);
outputStreamBody = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFileBody), "UTF8"));
System.out.println ("write output to: "+outputFileBody);
writeMainFile(path);
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}

private static void writeMainFile (String path) throws UnsupportedEncodingException, FileNotFoundException, IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(path + FILE_NAME)), "UTF8"));

// write tex file
writer.write("\\documentclass[a4paper,12pt]{article}"); writer.newLine();
writer.write("\\usepackage[utf8x]{inputenc}");  writer.newLine();
writer.write("\\usepackage[T1]{fontenc}"); writer.newLine();
writer.write("\\usepackage[left=10mm,right=10mm,top=10mm,bottom=0mm]{geometry}"); writer.newLine();
writer.write("\\setlength{\\parindent}{0ex}");  writer.newLine();
writer.newLine();
writer.write("\\begin{document}");
writer.newLine(); writer.newLine();
writer.write("\\include{"+FILE_NAME_BODY.substring (0, FILE_NAME_BODY.indexOf ('.'))+"}");
writer.newLine(); writer.newLine();
writer.write("\\end{document}"); writer.newLine();
writer.flush();
writer.close();
}

}


it is just quick and dirty code, with several chances to fail, but for a small example it works for me.

if you want to use it, first you need to chance the name of the input file in the code to the name of your file (variable FILE_NAME). afterwards you need to compile the program (javac test.java) and run it (java test).

good luck

-