001package Torello.JavaDoc;
002
003import java.io.IOException;
004import java.util.Vector;
005
006import Torello.HTML.*;
007
008import Torello.HTML.NodeSearch.TagNodeFind;
009import Torello.Java.HiLiteMe;
010import Torello.JDUInternal.Throwables.HiLiteError;
011
012/**
013 * A simple Functional-Interface allowing a user to swap in any customized, alternate or
014 * proprietary Syntax HiLiter to replace the default HiLiter used by this Upgrader Tool.
015 * 
016 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=HILITER>
017 */
018@FunctionalInterface
019public interface HiLiter
020{
021    /**
022     * This {@code Functional Interface} expects this method to be implemented.  Any HiLiter that
023     * would be "plugged into" this Documentation Tool must be able to <B>Pretty-Print HiLite</B>
024     * input Source-Code (passed as a {@code java.lang.String}) <I>and return HTML</I>.
025     * 
026     * <BR /><BR /><B>NOTE:</B> Any Code HiLiter that can operate with this input may be plugged
027     * in here.  In order to "Vectorize" HTML, just use the
028     * {@code HTMLPage.getPageTokens(String, false)} method.
029     *
030     * @param code This is the Source-Code as a {@code java.lang.String}
031     * 
032     * @param codeType This is a short descriptor of what kind of code is being passed.  The most
033     * frequent values for this parameter are: {@code 'java', 'html', 'js'} etc...
034     * 
035     * @param snippetOrComplete This is a {@code boolean} that when {@code TRUE}, indicates that
036     * a <B>code-snippet</B> has been passed, and when {@code FALSE} indicates that a <B>complete
037     * source code file</B> has been passed.
038     * 
039     * @return The intention is to return a Vectorized-HTML page (or sub-page) that contains a
040     * <B>HiLited &AMP; Pretty-Printed</B> version of the source-code.
041     * 
042     * @throws IOException This method is not defined, but it is permitted to throw 
043     * {@code IOException} - if there have been I/O problems when attempting to transform the
044     * source-code.
045     *
046     * @throws HiLiteException This exception may be used if other problems occur during the
047     * transformation process.
048     */
049    public Vector<HTMLNode> hiLite
050        (String code, String codeType, boolean snippetOrComplete)
051        throws IOException, HiLiteException;
052
053    /**
054     * The Default <B>Code HiLiter</B> uses the class {@link Torello.Java.HiLiteMe}.  This method
055     * is invoked by the {@link Upgrade} class and used to HiLite <I>BOTH</I> code-snippets
056     * <I>AND</I> complete source-code files.
057     * 
058     * @param c This is the Server-Cache that <I>may or may not be used</I>.  If this parameter
059     * is passed {@code 'null'}, it will be ignored.
060     * 
061     * @param snippetStyleCode Some of the source-code passed to this {@code HiLiter} will be
062     * short <I>code-snippets</I>, while other passed values of source-code will be <I>complete
063     * source-code files.</I>  This {@code String} is the {@code 'Style Parameter'} used for
064     * code-snippets.
065     * 
066     * <BR /><BR />You may view the complete-list of valid Style Parameters in use with this
067     * HiLiter with {@link HiLiteMe#getStyleTypes()}.
068     * 
069     * @param completeStyleCode When the {@code HiLiter} is asked to Hi-Lite and entire source
070     * code file, this parameter will be used for a {@code 'Style Parameter'} with the 
071     * {@code HiLiter}.
072     * 
073     * @return An instance of {@code HiLiter} that can be used by the {@code Upgrade} Tool
074     * 
075     * @throws IllegalArgumentException If invalid Styling-Parameters were passed either to
076     * {@code 'snippetStyleCode'} or {@code 'completeStyleCode'}.
077     * 
078     * @see HiLiteMe#prettyPrintScrapeToVectorAndSimplify(String, String, String, boolean)
079     * @see HiLiteMe#prettyPrintScrapeToVectorAndSimplify(String, String, String, boolean, HiLiteMe.Cache)
080     */
081    public static HiLiter getDefault
082        (Torello.Java.HiLiteMe.Cache c, String snippetStyleCode, String completeStyleCode)
083    {
084        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
085        // FAIL-FAST: Make sure that VALID Code-Styling Parameters were passed before building
086        //            the HiLiter
087        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
088
089        if (! HiLiteMe.isStyleType(snippetStyleCode)) throw new IllegalArgumentException(
090            "You have passed \"" + snippetStyleCode + "\" to parameter 'snippetStyleCode', but " +
091            "this is not actually a valid Style Parameter for class HiLite.Me.  Review the list " +
092            "Style Types in that class using HiLiteMe.getStyleTypes(), or look at the docs for " +
093            "that class"
094        );
095
096        if (! HiLiteMe.isStyleType(completeStyleCode)) throw new IllegalArgumentException(
097            "You have passed \"" + completeStyleCode + "\" to parameter 'completeStyleCode', but " +
098            "this is not actually a valid Style Parameter for class HiLite.Me.  Review the list " +
099            "Style Types in that class using HiLiteMe.getStyleTypes(), or look at the docs for " +
100            "that class"
101        );
102
103        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
104        // Return a HiLiter instance that uses Torello.Java.HiLiteMe
105        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
106
107        return (c == null)
108            ? new HiLiter()
109            {
110                private final String snippetSC  = snippetStyleCode;
111                private final String completeSC = completeStyleCode;
112
113                public Vector<HTMLNode> hiLite
114                    (String code, String codeType, boolean snippetOrComplete)
115                    throws IOException
116                { 
117                    return snippetOrComplete
118
119                        ? HiLiteMe.prettyPrintScrapeToVectorAndSimplify
120                            (code, codeType, snippetSC, false)
121
122                        : addAnchorIDs(
123                            HiLiteMe.prettyPrintScrapeToVectorAndSimplify
124                                (code, codeType, completeSC, true));
125                }
126            }
127            : new HiLiter()
128            {
129                // This one has a Cache
130                private final Torello.Java.HiLiteMe.Cache cache = c;
131
132                private final String snippetSC  = snippetStyleCode;
133                private final String completeSC = completeStyleCode;
134
135                public Vector<HTMLNode> hiLite
136                    (String code, String codeType, boolean snippetOrComplete)
137                    throws IOException
138                {
139                    // The Parameters to this Invokation are identical to the call above.  See
140                    // comments above...  This method includes 'cache' parameter, which is the last
141                    // parameter to this method.
142
143                    return snippetOrComplete
144
145                        ? HiLiteMe.prettyPrintScrapeToVectorAndSimplify
146                            (code, codeType, snippetSC, false /* no line nums */,  cache)
147
148                        : addAnchorIDs(
149                            HiLiteMe.prettyPrintScrapeToVectorAndSimplify
150                                (code, codeType, completeSC, true /* line nums */,  cache));
151                }
152            };
153    }
154
155    static Vector<HTMLNode> addAnchorIDs(Vector<HTMLNode> v)
156    {
157        int pos = TagNodeFind.first(v, TC.OpeningTags, "pre") + 1;
158
159        if (pos == 0) throw new HiLiteError
160            ("A <PRE> Element was not found in the returned HTML from Pygments.org");
161
162        StringBuilder sb = new StringBuilder();
163
164        for (String s : v.elementAt(pos).str.split("\n"))
165            sb.append("<A ID=L" + s.trim() + ">" + s.trim() + "</A>\n");
166
167        v.setElementAt(new TextNode(sb.toString()), pos);
168
169        return v;
170    }
171}