OSDN Git Service

Correct errors relating to LaTeX images & editing.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / xml / NoteFormatter.java
index 1da2050..0632121 100644 (file)
@@ -1,9 +1,14 @@
 package cx.fbn.nevernote.xml;\r
 \r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
 import java.io.File;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
 \r
+import org.w3c.tidy.Tidy;\r
+import org.w3c.tidy.TidyMessage;\r
+\r
 import com.evernote.edam.type.Note;\r
 import com.evernote.edam.type.Resource;\r
 import com.trolltech.qt.core.QByteArray;\r
@@ -12,6 +17,7 @@ import com.trolltech.qt.core.QFile;
 import com.trolltech.qt.core.QIODevice;\r
 import com.trolltech.qt.core.QIODevice.OpenModeFlag;\r
 import com.trolltech.qt.core.QTemporaryFile;\r
+import com.trolltech.qt.core.QTextCodec;\r
 import com.trolltech.qt.core.QUrl;\r
 import com.trolltech.qt.core.Qt.BGMode;\r
 import com.trolltech.qt.gui.QColor;\r
@@ -44,6 +50,7 @@ public class NoteFormatter {
        ArrayList<QTemporaryFile> tempFiles;\r
        private EnSearch enSearch;\r
        private boolean noteHistory;\r
+       public boolean formatError;\r
        \r
        public NoteFormatter(ApplicationLogger logger, DatabaseConnection conn, List<QTemporaryFile> tempFiles2) {\r
                this.logger = logger;\r
@@ -52,6 +59,34 @@ public class NoteFormatter {
        }\r
        \r
        \r
+       private class TidyListener implements org.w3c.tidy.TidyMessageListener {\r
+               \r
+               ApplicationLogger logger;\r
+               public boolean errorFound; \r
+               \r
+               public TidyListener(ApplicationLogger logger) {\r
+                       this.logger = logger;\r
+                       errorFound = false;\r
+               }\r
+               @Override\r
+               public void messageReceived(TidyMessage msg) {\r
+                       if (msg.getLevel() == TidyMessage.Level.ERROR) {\r
+                               logger.log(logger.LOW, "******* JTIDY ERORR *******");\r
+                               logger.log(logger.LOW, "Error Code: " +msg.getErrorCode());\r
+                               logger.log(logger.LOW, "Column: " +msg.getColumn());\r
+                               logger.log(logger.LOW, "Column: " +msg.getColumn());\r
+                               logger.log(logger.LOW, "Line: " +msg.getLine());\r
+                               logger.log(logger.LOW, "Message: " +msg.getMessage());\r
+                               logger.log(logger.LOW, "***************************");\r
+                               errorFound = true;\r
+                       } else \r
+                               logger.log(logger.EXTREME, "JTidy Results: "+msg.getMessage());\r
+               }\r
+               \r
+       }\r
+\r
+       \r
+       \r
        public void setNote(Note note, boolean pdfPreview) {\r
                currentNote = note;\r
                this.pdfPreview = pdfPreview;\r
@@ -81,6 +116,7 @@ public class NoteFormatter {
        \r
        // Rebuild the note HTML to something usable\r
        public String rebuildNoteHTML() {\r
+               formatError = false;\r
                if (currentNote == null)\r
                        return null;\r
                logger.log(logger.HIGH, "Entering NeverNote.rebuildNoteHTML");\r
@@ -88,12 +124,49 @@ public class NoteFormatter {
                logger.log(logger.EXTREME, "Note Text:" +currentNote);\r
                QDomDocument doc = new QDomDocument();\r
                QDomDocument.Result result = doc.setContent(currentNote.getContent());\r
+\r
+               // Handle any errors\r
+               if (!result.success) {\r
+                       logger.log(logger.LOW, "Error parsing document.  Attempting to restructure");\r
+                       Tidy tidy = new Tidy();\r
+                       TidyListener tidyListener = new TidyListener(logger);\r
+                       tidy.setMessageListener(tidyListener);\r
+                       tidy.getStderr().close();  // the listener will capture messages\r
+                       tidy.setXmlTags(true);\r
+                       \r
+                       QTextCodec codec;\r
+                       codec = QTextCodec.codecForName("UTF-8");\r
+               QByteArray unicode =  codec.fromUnicode(currentNote.getContent());\r
+               \r
+               logger.log(logger.MEDIUM, "Starting JTidy check");\r
+               logger.log(logger.MEDIUM, "Start of JTidy Input");\r
+               logger.log(logger.MEDIUM, currentNote.getContent());\r
+               logger.log(logger.MEDIUM, "End Of JTidy Input");\r
+                       ByteArrayInputStream is = new ByteArrayInputStream(unicode.toByteArray());\r
+               ByteArrayOutputStream os = new ByteArrayOutputStream();\r
+               tidy.setInputEncoding("UTF-8");\r
+                       tidy.parse(is, os);\r
+                       String tidyContent = os.toString();\r
+                       if (tidyListener.errorFound) {\r
+                               logger.log(logger.LOW, "Restructure failed!!!");\r
+                       } else {\r
+                               doc = null;\r
+                               doc = new QDomDocument();\r
+                               result = doc.setContent(tidyContent);\r
+                       }\r
+               }\r
                if (!result.success) {\r
-                       logger.log(logger.MEDIUM, "Parse error when rebuilding HTML");\r
+                       logger.log(logger.MEDIUM, "Parse error when rebuilding XML to HTML");\r
                        logger.log(logger.MEDIUM, "Note guid: " +currentNoteGuid);\r
-                       logger.log(logger.EXTREME, "Start of unmodified note HTML");\r
+                       logger.log(logger.MEDIUM, "Error: "+result.errorMessage);\r
+                       logger.log(logger.MEDIUM, "Line: " +result.errorLine + " Column: " +result.errorColumn);\r
+                       System.out.println("Error: "+result.errorMessage);\r
+                       System.out.println("Line: " +result.errorLine + " Column: " +result.errorColumn);\r
+                       logger.log(logger.EXTREME, "**** Start of unmodified note HTML");\r
                        logger.log(logger.EXTREME, currentNote.getContent());\r
-                       logger.log(logger.EXTREME, "End of unmodified note HTML");\r
+                       logger.log(logger.EXTREME, "**** End of unmodified note HTML");\r
+                       formatError = true;\r
+                       readOnly = true;\r
                        return currentNote.getContent();\r
                }\r
 \r
@@ -244,14 +317,16 @@ public class NoteFormatter {
                enmedia.setAttribute("src", tfile.fileName().toString());\r
                enmedia.setAttribute("en-tag", "en-media");\r
                enmedia.setTagName("img");\r
-               if (r.getAttributes().getSourceURL() == null || !r.getAttributes().getSourceURL().toLowerCase().startsWith("http://latex.codecogs.com/gif.latex?"))\r
+               if (r != null && r.getAttributes() != null && \r
+                               (r.getAttributes().getSourceURL() == null || !r.getAttributes().getSourceURL().toLowerCase().startsWith("http://latex.codecogs.com/gif.latex?")))\r
                        enmedia.setAttribute("onContextMenu", "window.jambi.imageContextMenu('" +tfile.fileName()  +"');");\r
                else {\r
                        QDomElement newText = doc.createElement("a");\r
                        enmedia.setAttribute("src", tfile.fileName().toString());\r
                        enmedia.setAttribute("en-tag", "en-latex");\r
                        newText.setAttribute("onMouseOver", "style.cursor='hand'");\r
-                       newText.setAttribute("title", r.getAttributes().getSourceURL());\r
+                       if (r!= null && r.getAttributes() != null && r.getAttributes().getSourceURL() != null)\r
+                               newText.setAttribute("title", r.getAttributes().getSourceURL());\r
                        newText.setAttribute("href", "latex://"+tfile.fileName().toString());\r
                        enmedia.parentNode().replaceChild(newText, enmedia);\r
                        newText.appendChild(enmedia);\r
@@ -276,7 +351,7 @@ public class NoteFormatter {
                // Modify en-media tags\r
                QDomNodeList anchors = docElem.elementsByTagName("en-media");\r
                int enMediaCount = anchors.length();\r
-               for (int i=enMediaCount-1; i>=0; i--) {\r
+               for (int i=enMediaCount-1; i>=0; --i) {\r
                        QDomElement enmedia = anchors.at(i).toElement();\r
                        if (enmedia.hasAttribute("type")) {\r
                                QDomAttr attr = enmedia.attributeNode("type");\r