HTML Tidy in NetBeans IDE

Posted by Geertjan on Oracle Blogs See other posts from Oracle Blogs or by Geertjan
Published on Mon, 4 Jun 2012 23:36:52 +0000 Indexed on 2012/06/05 4:45 UTC
Read the original article Hit count: 210

Filed under:

First step in integrating HTML Tidy (via its JTidy implementation) into NetBeans IDE:

The reason why I started doing this is because I want to integrate this into the pluggable analyzer functionality of NetBeans IDE that I recently blogged about, i.e., where the FindBugs functionality is found.

So a logical first step is to get it working in an Action class, after which I can port it into the analyzer infrastructure:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionRegistration;
import org.openide.cookies.EditorCookie;
import org.openide.cookies.LineCookie;
import org.openide.loaders.DataObject;
import org.openide.text.Line;
import org.openide.text.Line.ShowOpenType;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.IOProvider;
import org.openide.windows.InputOutput;
import org.openide.windows.OutputEvent;
import org.openide.windows.OutputListener;
import org.openide.windows.OutputWriter;
import org.w3c.tidy.Tidy;

@ActionID(
    category = "Tools",
id = "org.jtidy.TidyAction")
@ActionRegistration(
    displayName = "#CTL_TidyAction")
@ActionReferences({
    @ActionReference(path = "Loaders/text/html/Actions", position = 150),
    @ActionReference(path = "Editors/text/html/Popup", position = 750)
})
@Messages("CTL_TidyAction=Run HTML Tidy")
public final class TidyAction implements ActionListener {

    private final DataObject context;
    private final OutputWriter writer;
    private EditorCookie ec = null;

    public TidyAction(DataObject context) {
        this.context = context;
        ec = context.getLookup().lookup(org.openide.cookies.EditorCookie.class);
        InputOutput io = IOProvider.getDefault().getIO("HTML Tidy", false);
        io.select();
        writer = io.getOut();
    }

    @Override
    public void actionPerformed(ActionEvent ev) {
        Tidy tidy = new Tidy();
        try {
            writer.reset();
            StringWriter stringWriter = new StringWriter();
            PrintWriter errorWriter = new PrintWriter(stringWriter);
            tidy.setErrout(errorWriter);
            tidy.parse(context.getPrimaryFile().getInputStream(), System.out);
            String[] split = stringWriter.toString().split("\n");
            for (final String string : split) {
                final int end = string.indexOf(" c");
                if (string.startsWith("line")) {
                    writer.println(string, new OutputListener() {
                        @Override
                        public void outputLineAction(OutputEvent oe) {
                            LineCookie lc = context.getLookup().lookup(LineCookie.class);
                            int lineNumber = Integer.parseInt(string.substring(0, end).replace("line ", ""));
                            Line line = lc.getLineSet().getOriginal(lineNumber - 1);
                            line.show(ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS);
                        }
                        @Override
                        public void outputLineSelected(OutputEvent oe) {}
                        @Override
                        public void outputLineCleared(OutputEvent oe) {}
                    });
                }
            }
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
 
}

The string parsing above is ugly but gets the job done for now.

A problem integrating this into the pluggable analyzer functionality is the limitation of its scope. The analyzer lets you select one or more projects, or individual files, but not a folder. So it doesn't work on folders in the Favorites window, for example, which is where I'd like to apply HTML Tidy, across multiple folders via the analyzer functionality. That's a bit of a bummer that I'm hoping to get around somehow.

© Oracle Blogs or respective owner

Related posts about /NetBeans IDE