1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package Torello.JavaDoc;

import java.io.IOException;
import java.util.Vector;

import Torello.HTML.*;

import Torello.HTML.NodeSearch.TagNodeFind;
import Torello.Java.HiLiteMe;
import Torello.JDUInternal.Throwables.HiLiteError;

/**
 * A simple Functional-Interface allowing a user to swap in any customized, alternate or
 * proprietary Syntax HiLiter to replace the default HiLiter used by this Upgrader Tool.
 * 
 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=HILITER>
 */
@FunctionalInterface
public interface HiLiter
{
    /**
     * This {@code Functional Interface} expects this method to be implemented.  Any HiLiter that
     * would be "plugged into" this Documentation Tool must be able to <B>Pretty-Print HiLite</B>
     * input Source-Code (passed as a {@code java.lang.String}) <I>and return HTML</I>.
     * 
     * <BR /><BR /><B>NOTE:</B> Any Code HiLiter that can operate with this input may be plugged
     * in here.  In order to "Vectorize" HTML, just use the
     * {@code HTMLPage.getPageTokens(String, false)} method.
     *
     * @param code This is the Source-Code as a {@code java.lang.String}
     * 
     * @param codeType This is a short descriptor of what kind of code is being passed.  The most
     * frequent values for this parameter are: {@code 'java', 'html', 'js'} etc...
     * 
     * @param snippetOrComplete This is a {@code boolean} that when {@code TRUE}, indicates that
     * a <B>code-snippet</B> has been passed, and when {@code FALSE} indicates that a <B>complete
     * source code file</B> has been passed.
     * 
     * @return The intention is to return a Vectorized-HTML page (or sub-page) that contains a
     * <B>HiLited &AMP; Pretty-Printed</B> version of the source-code.
     * 
     * @throws IOException This method is not defined, but it is permitted to throw 
     * {@code IOException} - if there have been I/O problems when attempting to transform the
     * source-code.
     *
     * @throws HiLiteException This exception may be used if other problems occur during the
     * transformation process.
     */
    public Vector<HTMLNode> hiLite
        (String code, String codeType, boolean snippetOrComplete)
        throws IOException, HiLiteException;

    /**
     * The Default <B>Code HiLiter</B> uses the class {@link Torello.Java.HiLiteMe}.  This method
     * is invoked by the {@link Upgrade} class and used to HiLite <I>BOTH</I> code-snippets
     * <I>AND</I> complete source-code files.
     * 
     * @param c This is the Server-Cache that <I>may or may not be used</I>.  If this parameter
     * is passed {@code 'null'}, it will be ignored.
     * 
     * @param snippetStyleCode Some of the source-code passed to this {@code HiLiter} will be
     * short <I>code-snippets</I>, while other passed values of source-code will be <I>complete
     * source-code files.</I>  This {@code String} is the {@code 'Style Parameter'} used for
     * code-snippets.
     * 
     * <BR /><BR />You may view the complete-list of valid Style Parameters in use with this
     * HiLiter with {@link HiLiteMe#getStyleTypes()}.
     * 
     * @param completeStyleCode When the {@code HiLiter} is asked to Hi-Lite and entire source
     * code file, this parameter will be used for a {@code 'Style Parameter'} with the 
     * {@code HiLiter}.
     * 
     * @return An instance of {@code HiLiter} that can be used by the {@code Upgrade} Tool
     * 
     * @throws IllegalArgumentException If invalid Styling-Parameters were passed either to
     * {@code 'snippetStyleCode'} or {@code 'completeStyleCode'}.
     * 
     * @see HiLiteMe#prettyPrintScrapeToVectorAndSimplify(String, String, String, boolean)
     * @see HiLiteMe#prettyPrintScrapeToVectorAndSimplify(String, String, String, boolean, HiLiteMe.Cache)
     */
    public static HiLiter getDefault
        (Torello.Java.HiLiteMe.Cache c, String snippetStyleCode, String completeStyleCode)
    {
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // FAIL-FAST: Make sure that VALID Code-Styling Parameters were passed before building
        //            the HiLiter
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        if (! HiLiteMe.isStyleType(snippetStyleCode)) throw new IllegalArgumentException(
            "You have passed \"" + snippetStyleCode + "\" to parameter 'snippetStyleCode', but " +
            "this is not actually a valid Style Parameter for class HiLite.Me.  Review the list " +
            "Style Types in that class using HiLiteMe.getStyleTypes(), or look at the docs for " +
            "that class"
        );

        if (! HiLiteMe.isStyleType(completeStyleCode)) throw new IllegalArgumentException(
            "You have passed \"" + completeStyleCode + "\" to parameter 'completeStyleCode', but " +
            "this is not actually a valid Style Parameter for class HiLite.Me.  Review the list " +
            "Style Types in that class using HiLiteMe.getStyleTypes(), or look at the docs for " +
            "that class"
        );

        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Return a HiLiter instance that uses Torello.Java.HiLiteMe
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        return (c == null)
            ? new HiLiter()
            {
                private final String snippetSC  = snippetStyleCode;
                private final String completeSC = completeStyleCode;

                public Vector<HTMLNode> hiLite
                    (String code, String codeType, boolean snippetOrComplete)
                    throws IOException
                { 
                    return snippetOrComplete

                        ? HiLiteMe.prettyPrintScrapeToVectorAndSimplify
                            (code, codeType, snippetSC, false)

                        : addAnchorIDs(
                            HiLiteMe.prettyPrintScrapeToVectorAndSimplify
                                (code, codeType, completeSC, true));
                }
            }
            : new HiLiter()
            {
                // This one has a Cache
                private final Torello.Java.HiLiteMe.Cache cache = c;

                private final String snippetSC  = snippetStyleCode;
                private final String completeSC = completeStyleCode;

                public Vector<HTMLNode> hiLite
                    (String code, String codeType, boolean snippetOrComplete)
                    throws IOException
                {
                    // The Parameters to this Invokation are identical to the call above.  See
                    // comments above...  This method includes 'cache' parameter, which is the last
                    // parameter to this method.

                    return snippetOrComplete

                        ? HiLiteMe.prettyPrintScrapeToVectorAndSimplify
                            (code, codeType, snippetSC, false /* no line nums */,  cache)

                        : addAnchorIDs(
                            HiLiteMe.prettyPrintScrapeToVectorAndSimplify
                                (code, codeType, completeSC, true /* line nums */,  cache));
                }
            };
    }

    static Vector<HTMLNode> addAnchorIDs(Vector<HTMLNode> v)
    {
        int pos = TagNodeFind.first(v, TC.OpeningTags, "pre") + 1;

        if (pos == 0) throw new HiLiteError
            ("A <PRE> Element was not found in the returned HTML from Pygments.org");

        StringBuilder sb = new StringBuilder();

        for (String s : v.elementAt(pos).str.split("\n"))
            sb.append("<A ID=L" + s.trim() + ">" + s.trim() + "</A>\n");

        v.setElementAt(new TextNode(sb.toString()), pos);

        return v;
    }
}