make/jdk/src/classes/build/tools/fixuppandoc/Main.java
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 55651 45fc36beb0aa
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     1
/*
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     2
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     4
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    10
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    15
 * accompanied this code).
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    16
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    20
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    23
 * questions.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    24
 */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    25
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    26
package build.tools.fixuppandoc;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    27
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    28
import java.io.BufferedReader;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    29
import java.io.BufferedWriter;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    30
import java.io.IOException;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    31
import java.io.InputStreamReader;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    32
import java.io.OutputStreamWriter;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    33
import java.io.PrintStream;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    34
import java.io.PrintWriter;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    35
import java.io.Reader;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    36
import java.io.Writer;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    37
import java.nio.file.Files;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    38
import java.nio.file.Path;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    39
import java.util.ArrayList;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    40
import java.util.LinkedHashMap;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    41
import java.util.LinkedHashSet;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    42
import java.util.List;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    43
import java.util.Locale;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    44
import java.util.Map;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    45
import java.util.Objects;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    46
import java.util.Set;
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    47
import java.util.regex.Matcher;
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    48
import java.util.regex.Pattern;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    49
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    50
/**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    51
 * Fixup HTML generated by pandoc.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    52
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    53
 * <h2>{@code <html>}</h2>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    54
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    55
 * Replace the existing element with {@code <html lang="en">}, removing references to XML.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    56
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    57
 * <h2>{@code <main>}</h2>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    58
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    59
 * {@code <main>} is inserted if palpable content is found that is not with a
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    60
 * section such as {@code header},  {@code footer},  {@code aside}.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    61
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    62
 * {@code </main>} is inserted if {@code <main>} was inserted and a section
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    63
 * is started that should not be included in the main section.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    64
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    65
 * <h2>Tables: row headings</h2>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    66
 *
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    67
 * For simple tables, as typically generated by _pandoc_, determine the column
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    68
 * whose contents are unique, and convert the cells in that column to be header
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    69
 * cells with {@code scope="row"}. In case of ambiguity, a column containing a
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    70
 * {@code <th>} whose contents begin with <em>name</em> is preferred.
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    71
 * When converting the cell, the {@code style} attribute will be updated to
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    72
 * specify {@code font-weight: normal}, and if there is not already an explicit
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    73
 * setting for {@code text-align}, then the style will be updated to include
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    74
 * {@code text-align:left;}.
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    75
 *
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    76
 * These rules do not apply if the table contains any cells that include
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    77
 * a setting for the {@code scope} attribute, or if the table contains
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
    78
 * spanning cells or nested tables.
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    79
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    80
 * <h2>{@code <meta name="generator">}</h2>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    81
 *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    82
 * Update the content string, to indicate it has been processed by this program.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    83
 *
55651
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
    84
 * <h2>{@code <nav id="TOC">}</h2>
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
    85
 *
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
    86
 * Set attribute {@code title="Table Of Contents"}
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
    87
 *
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    88
 */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    89
public class Main {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    90
    /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    91
     * Runs the program.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    92
     *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    93
     * <pre>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    94
     *     java build.tools.fixuppandoc.Main [-o output-file] [input-file]
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    95
     * </pre>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    96
     *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    97
     * If no input file is specified, the program will read from standard input.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    98
     * If no output file is specified, the program will write to standard output.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
    99
     * Any error messages will be written to the standard error stream.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   100
     *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   101
     * @param args the command-line arguments
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   102
     */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   103
    public static void main(String... args) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   104
        try {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   105
            new Main().run(args);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   106
        } catch (IOException | IllegalArgumentException e) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   107
            System.err.println(e);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   108
            System.exit(1);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   109
        } catch (Throwable t) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   110
            t.printStackTrace(System.err);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   111
            System.exit(1);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   112
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   113
    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   114
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   115
    private void run(String... args) throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   116
        Path inFile = null;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   117
        Path outFile = null;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   118
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   119
        for (int i = 0; i < args.length; i++) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   120
            String arg = args[i];
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   121
            if (arg.equals("-o") && i + 1 < args.length) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   122
                outFile = Path.of(args[++i]);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   123
            } else if (arg.startsWith("-")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   124
                throw new IllegalArgumentException(arg);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   125
            } else if (inFile == null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   126
                inFile = Path.of(arg);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   127
            } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   128
                throw new IllegalArgumentException(arg);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   129
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   130
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   131
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   132
        new Fixup().run(inFile, outFile);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   133
    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   134
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   135
    /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   136
     * A class to read HTML, copying input to output, modifying
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   137
     * fragments as needed.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   138
     */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   139
    class Fixup extends HtmlParser {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   140
        /** The output stream. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   141
        PrintWriter out;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   142
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   143
        /** A stream for reporting errors. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   144
        PrintStream err = System.err;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   145
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   146
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   147
         * Flag to indicate when {@code <main>} is permitted around palpable content.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   148
         * Set within {@code <body>}; disabled within elements in which {@code <main>}
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   149
         * is not permitted.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   150
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   151
        boolean allowMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   152
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   153
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   154
         * Flag to indicate that {@code <main>} is required.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   155
         * Set on {@code <body>}; reset when {@code <main>} is either found or generated.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   156
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   157
        boolean needMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   158
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   159
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   160
         * Flag to indicate that {@code </main>} is required.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   161
         * Set if {@code <main>} is generated.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   162
         * Reset when a start or end element is found that requires that {@code </main>}
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   163
         * needs to be generated if necessary.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   164
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   165
        boolean needEndMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   166
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   167
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   168
         * Handler for {@code <table>} elements.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   169
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   170
        Table table;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   171
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   172
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   173
         * Run the program, copying an input file to an output file.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   174
         * If the input file is {@code null}, input is read from the standard input.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   175
         * If the output file is {@code null}, output is written to the standard output.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   176
         *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   177
         * @param inFile the input file
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   178
         * @param outFile the output file
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   179
         * @throws IOException if an IO error occurs
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   180
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   181
        void run(Path inFile, Path outFile) throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   182
            try (Writer out = openWriter(outFile)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   183
                this.out = new PrintWriter(out);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   184
                if (inFile != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   185
                    read(inFile);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   186
                } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   187
                    read(new BufferedReader(new InputStreamReader(System.in)));
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   188
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   189
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   190
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   191
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   192
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   193
         * Returns a writer for a file, or for the standard output if the file is {@code null}.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   194
         *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   195
         * @param file the file
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   196
         * @return the writer
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   197
         * @throws IOException if an IO error occurs
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   198
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   199
        private Writer openWriter(Path file) throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   200
            if (file != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   201
                return Files.newBufferedWriter(file);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   202
            } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   203
                return new BufferedWriter(new OutputStreamWriter(System.out) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   204
                    @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   205
                    public void close() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   206
                        flush();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   207
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   208
                });
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   209
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   210
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   211
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   212
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   213
        protected void error(Path file, int lineNumber, String message) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   214
            err.print(file == null ? "<stdin>" : file);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   215
            if (lineNumber > 0) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   216
                err.print(":");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   217
                err.print(lineNumber);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   218
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   219
            err.print(": ");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   220
            err.println(message);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   221
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   222
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   223
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   224
        protected void error(Path file, int lineNumber, Throwable t) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   225
            error(file, lineNumber, t.toString());
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   226
            t.printStackTrace(err);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   227
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   228
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   229
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   230
         * The buffer in which input is stored until an appropriate action can be determined.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   231
         * Using the buffer ensures that the output exactly matches the input, except where
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   232
         * it is intentionally modified.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   233
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   234
        private StringBuilder buffer = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   235
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   236
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   237
        public int nextChar() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   238
            if (ch > 0) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   239
                buffer.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   240
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   241
            return super.nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   242
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   243
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   244
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   245
        protected void doctype(String s) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   246
            flushBuffer();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   247
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   248
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   249
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   250
        protected void startElement(String name, Map<String,String> attrs, boolean selfClosing) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   251
            switch (name) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   252
                case "html":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   253
                    // replace the existing <html> fragment
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   254
                    out.write("<html lang=\"en\">");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   255
                    buffer.setLength(0);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   256
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   257
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   258
                case "meta":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   259
                    // update the meta-data for the generator
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   260
                    if (Objects.equals(attrs.get("name"), "generator")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   261
                        out.write(buffer.toString()
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   262
                                .replaceAll("(content=\"[^\"]*)(\")", "$1,fixuphtml$2"));
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   263
                        buffer.setLength(0);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   264
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   265
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   266
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   267
                case "article":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   268
                case "aside":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   269
                case "footer":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   270
                case "header":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   271
                case "nav":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   272
                    // starting one of these elements will terminate <main> if one is being
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   273
                    // inserted
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   274
                    if (needEndMain) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   275
                        out.write("</main>");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   276
                        needEndMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   277
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   278
                    // <main> is not permitted within these elements
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   279
                    allowMain = false;
55651
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
   280
                    if (name.equals("nav") && Objects.equals(attrs.get("id"), "TOC")) {
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
   281
                        out.write(buffer.toString()
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
   282
                                .replaceAll(">$", " title=\"Table Of Contents\">"));
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
   283
                        buffer.setLength(0);
45fc36beb0aa 8227416: Add a "Table Of Contents" to HTML version of man pages
jjg
parents: 55300
diff changeset
   284
                    }
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   285
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   286
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   287
                case "body":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   288
                    // within <body>, <main> is both permitted and required
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   289
                    allowMain = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   290
                    needMain = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   291
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   292
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   293
                case "main":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   294
                    // an explicit <main> found in the input; no need to add one
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   295
                    needMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   296
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   297
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   298
                case "table":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   299
                    // The entire content of a <table> is buffered, until it can be
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   300
                    // determined in which column of the table contains the cells
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   301
                    // that can be used to identify the row.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   302
                    if (table == null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   303
                        table = new Table();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   304
                    } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   305
                        // tables containing nested tables are not updated
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   306
                        table.simple = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   307
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   308
                    table.nestDepth++;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   309
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   310
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   311
                case "thead":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   312
                case "tbody":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   313
                    if (table != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   314
                        table.endCell();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   315
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   316
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   317
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   318
                case "tr":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   319
                    if (table != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   320
                        table.endCell();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   321
                        table.nextCellColumnIndex = 0;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   322
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   323
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   324
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   325
                case "td":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   326
                case "th":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   327
                    if (table != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   328
                        if (attrs.containsKey("rowspan")
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   329
                                || attrs.containsKey("colspan")
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   330
                                || attrs.containsKey("scope")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   331
                            // tables containing spanning cells and tables that already
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   332
                            // contain scope attributes are not updated
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   333
                            table.simple = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   334
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   335
                        table.startCell(name);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   336
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   337
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   338
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   339
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   340
            // by default, the content is deemed to be palpable content, and so
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   341
            // insert <main> if it is permitted and one is still required,
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   342
            // while also ensuring that it does not appear before <body>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   343
            if (allowMain && needMain && !name.equals("body")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   344
                out.write("<main>");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   345
                needMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   346
                needEndMain = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   347
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   348
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   349
            flushBuffer();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   350
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   351
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   352
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   353
        protected void endElement(String name) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   354
            switch (name) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   355
                case "article":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   356
                case "aside":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   357
                case "footer":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   358
                case "header":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   359
                case "nav":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   360
                    // The code does not handle nested elements of these kinds, but could.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   361
                    // So, assuming they are not nested, ending these elements implies
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   362
                    // that <main> is once again permitted.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   363
                    allowMain = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   364
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   365
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   366
                case "body":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   367
                    // The document is nearly done; insert <main> if needed
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   368
                    if (needEndMain) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   369
                        out.write("</main>");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   370
                        needEndMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   371
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   372
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   373
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   374
                case "table":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   375
                    // if the table is finished, analyze it and write it out
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   376
                    if (table != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   377
                        if (--table.nestDepth == 0) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   378
                            table.add(buffer.toString());
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   379
                            table.write(out);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   380
                            table = null;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   381
                            buffer.setLength(0);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   382
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   383
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   384
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   385
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   386
                case "thead":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   387
                case "tbody":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   388
                case "tr":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   389
                case "td":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   390
                case "th":
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   391
                    // ending any of these elements implicity or explicitly ends the
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   392
                    // current cell
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   393
                    table.endCell();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   394
                    break;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   395
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   396
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   397
            flushBuffer();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   398
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   399
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   400
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   401
        protected void content(String content) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   402
            if (table != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   403
                table.content(content);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   404
            } else if (allowMain && needMain && !content.isBlank()) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   405
                // insert <main> if required and if we have palpable content
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   406
                out.write("<main>");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   407
                needMain = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   408
                needEndMain = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   409
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   410
            flushBuffer();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   411
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   412
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   413
        @Override
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   414
        protected void comment(String comment) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   415
            flushBuffer();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   416
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   417
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   418
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   419
         * Flushes the buffer, either by adding it into a table, if one is
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   420
         * in progress, or by writing it out.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   421
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   422
        private void flushBuffer() {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   423
            String s = buffer.toString();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   424
            if (table != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   425
                table.add(s);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   426
            } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   427
                out.write(s);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   428
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   429
            buffer.setLength(0);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   430
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   431
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   432
    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   433
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   434
    /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   435
     * Storage for the content of a {@code <table>} element} until we can determine
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   436
     * whether we should add {@code scope="row"} to the cells in a given column,
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   437
     * and if so, which column.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   438
     *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   439
     * The column with the highest number of unique entries is selected;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   440
     * in case of ambiguity, a column whose heading begins "name" is chosen.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   441
     *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   442
     * Only "simple" tables are supported. Tables with any of the following
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   443
     * features are not considered "simple" and will not be modified:
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   444
     * <ul>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   445
     *     <li>Tables containing nested tables</li>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   446
     *     <li>Tables containing cells that use "rowspan" and "colspan" attributes</li>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   447
     *     <li>Tables containing cells that already use "scope" attributes</li>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   448
     * </ul>
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   449
     */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   450
    class Table {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   451
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   452
         * A fragment of HTML in this table.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   453
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   454
        class Entry {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   455
            /** The fragment. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   456
            final String html;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   457
            /** The column for a {@code <td>} fragment, or -1. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   458
            final int column;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   459
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   460
            Entry(String html, int column) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   461
                this.html = html;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   462
                this.column = column;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   463
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   464
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   465
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   466
        /** Whether or not this is a "simple" table. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   467
        boolean simple = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   468
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   469
        /** The nesting depth of the current table, within enclosing tables. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   470
        int nestDepth;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   471
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   472
        /** A list of the HTML fragments that make up this table. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   473
        List<Entry> entries;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   474
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   475
        /** The plain text contents of each column, used to determine the primary column. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   476
        List<Set<String>> columnContents;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   477
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   478
        /** The column index of the next cell to be found. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   479
        int nextCellColumnIndex;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   480
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   481
        /** A flag to mark the start of a {@code <td>} cell. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   482
        boolean startTDCell;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   483
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   484
        /** The column index of the current cell, or -1 if not in a cell. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   485
        int currCellColumnIndex;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   486
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   487
        /** The plain text contents of the current column. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   488
        Set<String> currColumnContents;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   489
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   490
        /** The plain text content of the current cell. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   491
        StringBuilder currCellContent;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   492
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   493
        /** The kind ({@code th} or {@code td}) of the current cell. */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   494
        String currCellKind;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   495
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   496
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   497
         * The index of the column, if any, containing a heading beginning "name".
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   498
         * This column is given preferential treatment when deciding the primary column.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   499
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   500
        int nameColumn;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   501
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   502
        Table() {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   503
            entries = new ArrayList<>();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   504
            columnContents = new ArrayList<>();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   505
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   506
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   507
        void startCell(String name) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   508
            endCell();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   509
            startTDCell = name.equals("td");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   510
            currCellColumnIndex = nextCellColumnIndex++;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   511
            currColumnContents = getColumn(currCellColumnIndex);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   512
            currCellContent = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   513
            currCellKind = name;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   514
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   515
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   516
        void endCell() {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   517
            if (currCellContent != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   518
                String c = currCellContent.toString().trim();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   519
                if (Objects.equals(currCellKind, "th")
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   520
                        && c.toLowerCase(Locale.US).startsWith("name")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   521
                    nameColumn = currCellColumnIndex;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   522
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   523
                currColumnContents.add(c);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   524
                currCellContent = null;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   525
                currCellColumnIndex = -1;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   526
                currColumnContents = null;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   527
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   528
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   529
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   530
        void content(String content) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   531
            if (currCellContent != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   532
                currCellContent.append(content);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   533
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   534
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   535
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   536
        void add(String html) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   537
            int index = startTDCell ? currCellColumnIndex : -1;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   538
            entries.add(new Entry(html, index));
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   539
            startTDCell = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   540
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   541
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   542
        void write(PrintWriter out) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   543
            int max = -1;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   544
            int maxIndex = -1;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   545
            int index = 0;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   546
            for (Set<String> c : columnContents) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   547
                if (c.size() > max || c.size() == max && index == nameColumn) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   548
                    max = c.size();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   549
                    maxIndex = index;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   550
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   551
                index++;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   552
            }
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   553
            boolean updateEndTd = false;
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   554
            Pattern styleAttr = Pattern.compile("(?<before>.*style=\")(?<style>[^\"]*)(?<after>\".*)");
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   555
            for (Entry e : entries) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   556
                if (simple && e.column == maxIndex) {
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   557
                    String attrs = e.html.substring(3, e.html.length() - 1);
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   558
                    out.write("<th");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   559
                    Matcher m = styleAttr.matcher(attrs);
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   560
                    if (m.matches()) {
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   561
                        out.write(m.group("before"));
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   562
                        out.write("font-weight: normal; ");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   563
                        String style = m.group("style");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   564
                        if (!style.contains("text-align")) {
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   565
                            out.write("text-align: left; ");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   566
                        }
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   567
                        out.write(style);
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   568
                        out.write(m.group("after"));
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   569
                    } else {
55300
1e0b948cc122 8224257: fix issues in files generated by pandoc
jjg
parents: 55297
diff changeset
   570
                        out.write(" style=\"font-weight: normal; text-align:left;\" ");
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   571
                        out.write(attrs);
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   572
                    }
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   573
                    out.write(" scope=\"row\"");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   574
                    out.write(">");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   575
                    updateEndTd = true;
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   576
                } else if (updateEndTd && e.html.equalsIgnoreCase("</td>")) {
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   577
                    out.write("</th>");
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   578
                    updateEndTd = false;
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   579
                } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   580
                    out.write(e.html);
55297
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   581
                    if (updateEndTd && e.html.regionMatches(true, 0, "<td", 0, 3)) {
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   582
                        // a new cell has been started without explicitly closing the
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   583
                        // cell that was being updated
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   584
                        updateEndTd = false;
fd61ef6c4091 8224257: fix issues in files generated by pandoc
jjg
parents: 55113
diff changeset
   585
                    }
55113
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   586
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   587
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   588
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   589
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   590
        private Set<String> getColumn(int index) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   591
            while (columnContents.size() <= index) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   592
                columnContents.add(new LinkedHashSet<>());
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   593
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   594
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   595
            return columnContents.get(index);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   596
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   597
    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   598
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   599
    /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   600
     * A basic HTML parser.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   601
     * Override the protected methods as needed to get notified of significant items
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   602
     * in any file that is read.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   603
     */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   604
    abstract class HtmlParser {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   605
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   606
        private Path file;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   607
        private Reader in;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   608
        protected int ch;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   609
        private int lineNumber;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   610
        private boolean inScript;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   611
        private boolean xml;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   612
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   613
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   614
         * Read a file.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   615
         * @param file the file
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   616
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   617
        void read(Path file) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   618
            try (Reader r = Files.newBufferedReader(file)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   619
                this.file = file;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   620
                read(r);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   621
            } catch (IOException e) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   622
                error(file, -1, e);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   623
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   624
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   625
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   626
        HtmlParser() { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   627
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   628
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   629
         * Read a stream.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   630
         * @param r the stream
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   631
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   632
        void read(Reader r) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   633
            try {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   634
                this.in = r;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   635
                StringBuilder content = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   636
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   637
                startFile(file);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   638
                try {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   639
                    lineNumber = 1;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   640
                    xml = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   641
                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   642
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   643
                    while (ch != -1) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   644
                        if (ch == '<') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   645
                            content(content.toString());
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   646
                            content.setLength(0);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   647
                            html();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   648
                        } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   649
                            content.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   650
                            if (ch == '\n') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   651
                                content(content.toString());
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   652
                                content.setLength(0);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   653
                            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   654
                            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   655
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   656
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   657
                } finally {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   658
                    endFile();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   659
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   660
            } catch (IOException e) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   661
                error(file, lineNumber, e);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   662
            } catch (Throwable t) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   663
                error(file, lineNumber, t);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   664
                t.printStackTrace(System.err);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   665
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   666
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   667
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   668
        protected int getLineNumber() {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   669
            return lineNumber;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   670
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   671
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   672
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   673
         * Called when a file has been opened, before parsing begins.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   674
         * This is always the first notification when reading a file.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   675
         * This implementation does nothing.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   676
         *
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   677
         * @param file the file
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   678
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   679
        protected void startFile(Path file) { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   680
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   681
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   682
         * Called when the parser has finished reading a file.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   683
         * This is always the last notification when reading a file,
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   684
         * unless any errors occur while closing the file.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   685
         * This implementation does nothing.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   686
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   687
        protected void endFile() { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   688
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   689
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   690
         * Called when a doctype declaration is found, at the beginning of the file.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   691
         * This implementation does nothing.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   692
         * @param s the doctype declaration
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   693
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   694
        protected void doctype(String s) { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   695
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   696
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   697
         * Called when the opening tag of an HTML element is encountered.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   698
         * This implementation does nothing.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   699
         * @param name the name of the tag
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   700
         * @param attrs the attribute
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   701
         * @param selfClosing whether or not this is a self-closing tag
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   702
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   703
        protected void startElement(String name, Map<String,String> attrs, boolean selfClosing) { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   704
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   705
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   706
         * Called when the closing tag of an HTML tag is encountered.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   707
         * This implementation does nothing.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   708
         * @param name the name of the tag
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   709
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   710
        protected void endElement(String name) { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   711
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   712
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   713
         * Called for sequences of character content.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   714
         * @param content the character content
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   715
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   716
        protected void content(String content) { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   717
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   718
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   719
         * Called for sequences of comment.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   720
         * @param comment the comment
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   721
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   722
        protected void comment(String comment) { }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   723
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   724
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   725
         * Called when an error has been encountered.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   726
         * @param file the file being read
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   727
         * @param lineNumber the line number of line containing the error
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   728
         * @param message a description of the error
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   729
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   730
        protected abstract void error(Path file, int lineNumber, String message);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   731
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   732
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   733
         * Called when an exception has been encountered.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   734
         * @param file the file being read
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   735
         * @param lineNumber the line number of the line being read when the exception was found
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   736
         * @param t the exception
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   737
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   738
        protected abstract void error(Path file, int lineNumber, Throwable t);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   739
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   740
        protected int nextChar() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   741
            ch = in.read();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   742
            if (ch == '\n')
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   743
                lineNumber++;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   744
            return ch;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   745
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   746
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   747
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   748
         * Read the start or end of an HTML tag, or an HTML comment
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   749
         * {@literal <identifier attrs> } or {@literal </identifier> }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   750
         * @throws java.io.IOException if there is a problem reading the file
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   751
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   752
        protected void html() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   753
            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   754
            if (isIdentifierStart((char) ch)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   755
                String name = readIdentifier().toLowerCase(Locale.US);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   756
                Map<String,String> attrs = htmlAttrs();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   757
                if (attrs != null) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   758
                    boolean selfClosing = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   759
                    if (ch == '/') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   760
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   761
                        selfClosing = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   762
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   763
                    if (ch == '>') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   764
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   765
                        startElement(name, attrs, selfClosing);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   766
                        if (name.equals("script")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   767
                            inScript = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   768
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   769
                        return;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   770
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   771
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   772
            } else if (ch == '/') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   773
                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   774
                if (isIdentifierStart((char) ch)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   775
                    String name = readIdentifier().toLowerCase(Locale.US);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   776
                    skipWhitespace();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   777
                    if (ch == '>') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   778
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   779
                        endElement(name);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   780
                        if (name.equals("script")) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   781
                            inScript = false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   782
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   783
                        return;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   784
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   785
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   786
            } else if (ch == '!') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   787
                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   788
                if (ch == '-') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   789
                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   790
                    if (ch == '-') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   791
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   792
                        StringBuilder comment = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   793
                        while (ch != -1) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   794
                            int dash = 0;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   795
                            while (ch == '-') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   796
                                dash++;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   797
                                comment.append(ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   798
                                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   799
                            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   800
                            // Strictly speaking, a comment should not contain "--"
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   801
                            // so dash > 2 is an error, dash == 2 implies ch == '>'
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   802
                            // See http://www.w3.org/TR/html-markup/syntax.html#syntax-comments
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   803
                            // for more details.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   804
                            if (dash >= 2 && ch == '>') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   805
                                comment.setLength(comment.length() - 2);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   806
                                comment(comment.toString());
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   807
                                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   808
                                return;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   809
                            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   810
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   811
                            comment.append(ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   812
                            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   813
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   814
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   815
                } else if (ch == '[') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   816
                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   817
                    if (ch == 'C') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   818
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   819
                        if (ch == 'D') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   820
                            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   821
                            if (ch == 'A') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   822
                                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   823
                                if (ch == 'T') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   824
                                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   825
                                    if (ch == 'A') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   826
                                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   827
                                        if (ch == '[') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   828
                                            while (true) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   829
                                                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   830
                                                if (ch == ']') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   831
                                                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   832
                                                    if (ch == ']') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   833
                                                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   834
                                                        if (ch == '>') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   835
                                                            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   836
                                                            return;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   837
                                                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   838
                                                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   839
                                                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   840
                                            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   841
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   842
                                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   843
                                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   844
                                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   845
                            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   846
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   847
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   848
                } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   849
                    StringBuilder sb = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   850
                    while (ch != -1 && ch != '>') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   851
                        sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   852
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   853
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   854
                    Pattern p = Pattern.compile("(?is)doctype\\s+html\\s?.*");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   855
                    String s = sb.toString();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   856
                    if (p.matcher(s).matches()) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   857
                        doctype(s);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   858
                        return;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   859
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   860
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   861
            } else if (ch == '?') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   862
                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   863
                if (ch == 'x') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   864
                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   865
                    if (ch == 'm') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   866
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   867
                        if (ch == 'l') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   868
                            Map<String,String> attrs = htmlAttrs();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   869
                            if (ch == '?') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   870
                                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   871
                                if (ch == '>') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   872
                                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   873
                                    xml = true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   874
                                    return;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   875
                                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   876
                            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   877
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   878
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   879
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   880
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   881
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   882
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   883
            if (!inScript) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   884
                error(file, lineNumber, "bad html");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   885
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   886
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   887
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   888
        /**
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   889
         * Read a series of HTML attributes, terminated by {@literal > }.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   890
         * Each attribute is of the form {@literal identifier[=value] }.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   891
         * "value" may be unquoted, single-quoted, or double-quoted.
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   892
         */
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   893
        private Map<String,String> htmlAttrs() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   894
            Map<String, String> map = new LinkedHashMap<>();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   895
            skipWhitespace();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   896
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   897
            while (isIdentifierStart((char) ch)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   898
                String name = readAttributeName().toLowerCase(Locale.US);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   899
                skipWhitespace();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   900
                String value = null;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   901
                if (ch == '=') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   902
                    nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   903
                    skipWhitespace();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   904
                    if (ch == '\'' || ch == '"') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   905
                        char quote = (char) ch;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   906
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   907
                        StringBuilder sb = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   908
                        while (ch != -1 && ch != quote) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   909
                            sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   910
                            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   911
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   912
                        value = sb.toString() // hack to replace common entities
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   913
                                .replace("&lt;", "<")
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   914
                                .replace("&gt;", ">")
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   915
                                .replace("&amp;", "&");
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   916
                        nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   917
                    } else {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   918
                        StringBuilder sb = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   919
                        while (ch != -1 && !isUnquotedAttrValueTerminator((char) ch)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   920
                            sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   921
                            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   922
                        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   923
                        value = sb.toString();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   924
                    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   925
                    skipWhitespace();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   926
                }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   927
                map.put(name, value);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   928
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   929
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   930
            return map;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   931
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   932
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   933
        private boolean isIdentifierStart(char ch) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   934
            return Character.isUnicodeIdentifierStart(ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   935
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   936
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   937
        private String readIdentifier() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   938
            StringBuilder sb = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   939
            sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   940
            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   941
            while (ch != -1 && Character.isUnicodeIdentifierPart(ch)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   942
                sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   943
                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   944
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   945
            return sb.toString();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   946
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   947
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   948
        private String readAttributeName() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   949
            StringBuilder sb = new StringBuilder();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   950
            sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   951
            nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   952
            while (ch != -1 && Character.isUnicodeIdentifierPart(ch)
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   953
                    || ch == '-'
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   954
                    || (xml || sb.toString().startsWith("xml")) && ch == ':') {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   955
                sb.append((char) ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   956
                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   957
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   958
            return sb.toString();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   959
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   960
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   961
        private boolean isWhitespace(char ch) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   962
            return Character.isWhitespace(ch);
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   963
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   964
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   965
        private void skipWhitespace() throws IOException {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   966
            while (isWhitespace((char) ch)) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   967
                nextChar();
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   968
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   969
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   970
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   971
        private boolean isUnquotedAttrValueTerminator(char ch) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   972
            switch (ch) {
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   973
                case '\f': case '\n': case '\r': case '\t':
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   974
                case ' ':
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   975
                case '"': case '\'': case '`':
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   976
                case '=': case '<': case '>':
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   977
                    return true;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   978
                default:
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   979
                    return false;
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   980
            }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   981
        }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   982
    }
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   983
a41029c383bf 8225066: Add missing file
jjg
parents:
diff changeset
   984
}