0

Im developing a script in awk to convert a tex document into html, according to my preferences.

#!/bin/awk -f

BEGIN {
    FS="\n";
    print "<html><body>"
}
# Function to print a row with one argument to handle either a 'th' tag or 'td' tag
function printRow(tag) {
    for(i=1; i<=NF; i++) print "<"tag">"$i"</"tag">";
}

NR>1 {
   [conditions]
   printRow("p")
}

END {
    print "</body></html>"
}

Its in a very young stage of development, as seen.

\documentclass[a4paper, 11pt, titlepage]{article}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{imakeidx}
[...]

\begin{document}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla placerat lectus sit amet augue facilisis, eget viverra sem pellentesque. Nulla vehicula metus risus, vel condimentum nunc dignissim eget. Vivamus quis sagittis tellus, eget ullamcorper libero. Nulla vitae fringilla nunc. Vivamus id suscipit mi. Phasellus porta lacinia dolor, at congue eros rhoncus vitae. Donec vel condimentum sapien. Curabitur est massa, finibus vel iaculis id, dignissim nec nisl. Sed non justo orci. Morbi quis orci efficitur sem porttitor pulvinar. Duis consectetur rhoncus posuere. Duis cursus neque semper lectus fermentum rhoncus.

\end{document}

What I want, is that the script only interprets the lines that are between \begin{document} and \end{document}, since before they are imports of libraries, variables, etc; which at the moment do not interest me.

How do I make it so that it only processes the text within that pattern?

3

2 Answers 2

3

Don't use a shebang to call awk, it just makes things more complicated and robs you of the ability to leverage shell features and awk features and tightly couples the script to awk-specific syntax, see https://stackoverflow.com/a/61002754/1745001.

Here's how to start writing your script:

#!/usr/bin/env bash

awk '

    BEGIN {
        print "<html><body>"
    }
    
    # Function to print a row with one argument to handle either a "p" or "th" tag or "td" tag
    function printRow(tag,    i) {
        for(i=1; i<=NF; i++) print "<"tag">" $i "</"tag">"
    }
    
    $0 == "\begin{document}" { f=1 }
    $0 == "\end{document}"   { f=0 }
    
    !f { next }
    
    [conditions] {
       printRow("p")      # or "th" or "td"
    }
    
    END {
        print "</body></html>"
    }

' "${@:--}"

I remove the FS="\n" because you're using a loop from 1 to NF in your function and that wouldn't make sense if FS and RS were the same thing since that would cause NF to always be 1.

1

I think that should be easy to implement: You could e.g. specify a flag that is initialized as 0 in your BEGIN block (this is optional as awk will evaluate non-initialized variables as "false" in boolean tests). You the instruct awk to exclusively check if the line states \begin{document} if the flag is unset but otherwise ignore the line. Only when the \begin statement is encountered do you set the flag to 1, and then perform the usual processing. The flag would then be reset if an \end{document} is encountered.

So, you could modify the script as follows:

!f{if ($1=="\begin{document}") f=1; next}

f && ($1=="\end{document}") {f=0; next}

f==1 {
   [conditions]
   printRow("p")
}

The "set" and "reset" conditions are different here, because while f is unset, you want to skip every line (including the \begin{document}) line, but in addition set the flag if the \begin statement was found, whereas if f is set, you want to reset it and skip the line only if the current line reads \end{document}.

You must log in to answer this question.

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