#!/usr/bin/gawk -f
# Extract HTML headings from a HTML file or an ePub file.
# Ian E. Gorman 2023
# To extract the headings from an ePub file, unzip the ePub file into an empty
# directory and run this program on all the HTML files in the directory.
# This AWK program assumes that the input is one or more valid HTML files.
# The program is written for GNU AWK and may not work in other versions of AWK.
# The program has not been tested in POSIX AWK
# AWK is often considered to be a line-oriented language that iterates over
# the lines in a text file. AWK is actually a record-oriented language.
# The default record separator is a platform-specific sequence of characters:
# "\n", "\r\n". or "\r" that are an US-specific line-end.
# Splitting input lines on '<' instead of '\n' places each tag at the
# beginning of a line, but ddrops the '<' character. A new '<"
# character must be inserted in the corresponding output line.
BEGIN {
SystemLineEnd = ORS # We will still need the ordinary line-end
ORS = RS = "<" # Change record separators from default to '<'
}
# Enter heading, output the start tag and following content
/^[Hh][1-6][^>]*>/ { # heading start tag
print "" # Output the record separator (ORS = "<")
printf("%s", $0) # Output the tag and the following content
IN_HEADING = 1 # True
next
}
# Exit heading: output the end tag, but not the following content
match($0, /^\/[Hh][1-6][^>]*>/) { # Heading end tag
print "" # Output the record separator (ORS = "<")
printf("%s", substr($0, 1, RLENGTH)) # output the tag only
printf("%s", SystemLineEnd) # Output ordinary line-end
IN_HEADING = 0 # False
next
}
# output any other content between header start tag and header end tag
IN_HEADING {
print "" # Output the record separator (ORS = "<")
printf("%s", $0) # Output the input data
next
}
# All other input is discarded
{ next }