#!/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 }