TableAnalyzer.java

/*
 * Copyright © 2018-2025 The CTAN Team and individual authors
 *
 * This file is distributed under the 3-clause BSD license.
 * See file LICENSE for details.
 */
package org.ctan.markup.html2latex;

import org.jsoup.nodes.Node;
import org.jsoup.select.NodeVisitor;

/**
 * This class analyzes a HTML table to find out which columns are present.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
public class TableAnalyzer {

    /**
     * This class visits the nodes.
     */
    private class NoVisitor implements NodeVisitor {

        /**
         * The field <code>columns</code> contains the total number of columns.
         */
        protected int columns = 0;

        /**
         * The field <code>col</code> contains the current column.
         */
        private int col = 0;

        /**
         * {@inheritDoc}
         *
         * @see org.jsoup.select.NodeVisitor#head(org.jsoup.nodes.Node, int)
         */
        @Override
        public void head(Node node, int depth) {

            if (depth == 2 && "tr".equals(node.nodeName())) {
                col = 0;
            } else if (depth == 3 && "td".equals(node.nodeName())) {
                col++;
            }
        }

        /**
         * {@inheritDoc}
         *
         * @see org.jsoup.select.NodeVisitor#tail(org.jsoup.nodes.Node, int)
         */
        @Override
        public void tail(Node node, int depth) {

            if (depth == 2 && "tr".equals(node.nodeName()) && col > columns) {
                columns = col;
            }
        }
    }

    /**
     * The method <code>analyze</code> collects the specifications for columns
     * of a table.
     *
     * @param node the node to analyze
     *
     * @return the specification for tabular
     */
    public String analyze(Node node) {

        var nodeVisitor = new NoVisitor();
        node.traverse(nodeVisitor);
        var sb = new StringBuilder();
        for (var i = nodeVisitor.columns; i > 0; i--) {
            sb.append("l");
        }
        return sb.toString();
    }

}