Revision: 2117 http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=2117&view=re... Author: ctabin Date: 2011-08-03 09:49:27 +0000 (Wed, 03 Aug 2011)
Log Message: ----------- XML Pretty Printer: many bugfixes
Modified Paths: -------------- trunk/geany-plugins/pretty-printer/src/ConfigUI.c trunk/geany-plugins/pretty-printer/src/PluginEntry.c trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h
Modified: trunk/geany-plugins/pretty-printer/src/ConfigUI.c =================================================================== --- trunk/geany-plugins/pretty-printer/src/ConfigUI.c 2011-08-02 21:05:20 UTC (rev 2116) +++ trunk/geany-plugins/pretty-printer/src/ConfigUI.c 2011-08-03 09:49:27 UTC (rev 2117) @@ -20,7 +20,7 @@
//======================= FUNCTIONS ====================================================================
-static GtkWidget* createTwoOptionsBox(const char* label, const char* checkBox1, const char* checkBox2, gboolean cb1Active, gboolean cb2Active, GtkWidget** option1, GtkWidget** option2); +//static GtkWidget* createTwoOptionsBox(const char* label, const char* checkBox1, const char* checkBox2, gboolean cb1Active, gboolean cb2Active, GtkWidget** option1, GtkWidget** option2); static GtkWidget* createThreeOptionsBox(const char* label, const char* checkBox1, const char* checkBox2, const char* checkBox3, gboolean cb1Active, gboolean cb2Active, gboolean cb3Active, GtkWidget** option1, GtkWidget** option2, GtkWidget** option3); static GtkWidget* createEmptyTextOptions(gboolean emptyNodeStripping, gboolean emptyNodeStrippingSpace, gboolean forceEmptyNodeSplit); static GtkWidget* createIndentationOptions(char indentation, int count); @@ -36,6 +36,7 @@ static GtkWidget* textAlign; static GtkWidget* cdataOneLine; static GtkWidget* cdataInline; +static GtkWidget* cdataAlign; static GtkWidget* emptyNodeStripping; static GtkWidget* emptyNodeStrippingSpace; static GtkWidget* emptyNodeSplit; @@ -60,7 +61,7 @@ GtkWidget* leftBox = gtk_vbox_new(FALSE, 6); GtkWidget* commentOptions = createThreeOptionsBox(_("Comments"), _("Put on one line"), _("Inline if possible"), _("Alignment"), ppo->oneLineComment, ppo->inlineComment, ppo->alignComment, &commentOneLine, &commentInline, &commentAlign); GtkWidget* textOptions = createThreeOptionsBox(_("Text nodes"), _("Put on one line"), _("Inline if possible"), _("Alignment"), ppo->oneLineText, ppo->inlineText, ppo->alignText, &textOneLine, &textInline, &textAlign); - GtkWidget* cdataOptions = createTwoOptionsBox(_("CDATA"), _("Put on one line"), _("Inline if possible"), ppo->oneLineCdata, ppo->inlineCdata, &cdataOneLine, &cdataInline); + GtkWidget* cdataOptions = createThreeOptionsBox(_("CDATA"), _("Put on one line"), _("Inline if possible"), _("Alignment"), ppo->oneLineCdata, ppo->inlineCdata, ppo->alignCdata, &cdataOneLine, &cdataInline, &cdataAlign); GtkWidget* emptyOptions = createEmptyTextOptions(ppo->emptyNodeStripping, ppo->emptyNodeStrippingSpace, ppo->forceEmptyNodeSplit); GtkWidget* indentationOptions = createIndentationOptions(ppo->indentChar, ppo->indentLength); GtkWidget* lineReturnOptions = createLineReturnOptions(ppo->newLineChars); @@ -95,6 +96,7 @@
ppo->oneLineCdata = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cdataOneLine)); ppo->inlineCdata = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cdataInline)); + ppo->alignCdata = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cdataAlign));
ppo->emptyNodeStripping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(emptyNodeStripping)); ppo->emptyNodeStrippingSpace = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(emptyNodeStrippingSpace)); @@ -111,7 +113,7 @@
//============================================= PRIVATE FUNCTIONS =======================================
-GtkWidget* createTwoOptionsBox(const char* label, +/*GtkWidget* createTwoOptionsBox(const char* label, const char* checkBox1, const char* checkBox2, gboolean cb1Active, @@ -141,7 +143,7 @@ *option2 = chb2;
return container; -} +}*/
static GtkWidget* createThreeOptionsBox(const char* label, const char* checkBox1,
Modified: trunk/geany-plugins/pretty-printer/src/PluginEntry.c =================================================================== --- trunk/geany-plugins/pretty-printer/src/PluginEntry.c 2011-08-02 21:05:20 UTC (rev 2116) +++ trunk/geany-plugins/pretty-printer/src/PluginEntry.c 2011-08-03 09:49:27 UTC (rev 2117) @@ -27,7 +27,7 @@
PLUGIN_VERSION_CHECK(130) PLUGIN_SET_INFO("XML PrettyPrinter", "Formats an XML and makes it human-readable.", - "1.2", "Cédric Tabin - http://www.astorm.ch") + PRETTY_PRINTER_VERSION, "Cédric Tabin - http://www.astorm.ch") PLUGIN_KEY_GROUP(prettyprinter, 1)
//========================================== DECLARATIONS ================================================================
Modified: trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c =================================================================== --- trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c 2011-08-02 21:05:20 UTC (rev 2116) +++ trunk/geany-plugins/pretty-printer/src/PrettyPrinter.c 2011-08-03 09:49:27 UTC (rev 2117) @@ -29,6 +29,7 @@ static char getNextChar(); //returns the next char but do not increase the input buffer index (use readNextChar for that) static char getPreviousInsertedChar(); //returns the last inserted char into the new buffer static bool isWhite(char c); //check if the specified char is a white +static bool isSpace(char c); //check if the specified char is a space static bool isLineBreak(char c); //check if the specified char is a new line static bool isQuote(char c); //check if the specified char is a quote (simple or double) static int putNewLine(); //put a new line into the new char buffer with the correct number of whites (indentation) @@ -81,9 +82,13 @@ //initialize the variables result = PRETTY_PRINTING_SUCCESS; bool freeOptions = FALSE; - if (ppOptions == NULL) { ppOptions = createDefaultPrettyPrintingOptions(); freeOptions = TRUE; } + if (ppOptions == NULL) + { + ppOptions = createDefaultPrettyPrintingOptions(); + freeOptions = TRUE; + } + options = ppOptions; - currentNodeName = NULL; appendIndentation = FALSE; lastNodeOpen = FALSE; @@ -162,6 +167,7 @@ defaultOptions->trimTrailingWhites = TRUE; defaultOptions->alignComment = TRUE; defaultOptions->alignText = TRUE; + defaultOptions->alignCdata = TRUE;
return defaultOptions; } @@ -252,11 +258,16 @@
bool isWhite(char c) { - return (c == ' ' || - c == '\t' || + return (isSpace(c) || isLineBreak(c)); }
+bool isSpace(char c) +{ + return (c == ' ' || + c == '\t'); +} + bool isLineBreak(char c) { return (c == '\n' || @@ -272,13 +283,14 @@ int secondChar = inputBuffer[inputBufferIndex+1]; //should be '!' int thirdChar = inputBuffer[inputBufferIndex+2]; //should be '-' or '['
+ //loop through the content up to the next opening/closing node int currentIndex = inputBufferIndex+1; if (firstChar == '<') { //another node is being open ==> no inline ! if (secondChar != '!') { return FALSE; }
- //okay we are in a comment node, so read until it is closed + //okay we are in a comment/cdata node, so read until it is closed
//select the closing char char closingComment = '-'; @@ -286,12 +298,12 @@
//read until closing char oldChar = ' '; - currentIndex += 3; //that by pass meanless chars + currentIndex += 3; //that bypass meanless chars bool loop = TRUE; while (loop) { char current = inputBuffer[currentIndex]; - if (current == closingComment && oldChar == closingComment) { loop = FALSE; } //end of comment + if (current == closingComment && oldChar == closingComment) { loop = FALSE; } //end of comment/cdata oldChar = current; ++currentIndex; } @@ -316,7 +328,7 @@ if (currentChar == '/') { //as we are in a correct XML (so far...), if the node is - //being directly close, the inline is allowed !!! + //being directly closed, the inline is allowed !!! return TRUE; } } @@ -699,17 +711,32 @@
if (!isLineBreak(nextChar)) //the comment simply continues { - putCharInBuffer(nextChar); - oldChar = nextChar; + if (options->oneLineComment && isSpace(nextChar)) + { + //removes all the unecessary spaces + while(isSpace(getNextChar())) + { + nextChar = readNextChar(); + } + putCharInBuffer(' '); + oldChar = ' '; + } + else + { + //comment is left untouched + putCharInBuffer(nextChar); + oldChar = nextChar; + }
if (!loop && options->alignComment) //end of comment { - //ensures the chars preceding the first '-' are all spaces + //ensures the chars preceding the first '-' are all spaces (there are at least + //5 spaces in front of the '-->' for the alignment with '<!--') bool onlySpaces = xmlPrettyPrinted[xmlPrettyPrintedIndex-3] == ' ' && - xmlPrettyPrinted[xmlPrettyPrintedIndex-4] == ' ' && - xmlPrettyPrinted[xmlPrettyPrintedIndex-5] == ' ' && - xmlPrettyPrinted[xmlPrettyPrintedIndex-6] == ' ' && - xmlPrettyPrinted[xmlPrettyPrintedIndex-7] == ' '; + xmlPrettyPrinted[xmlPrettyPrintedIndex-4] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-5] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-6] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-7] == ' ';
//if all the preceding chars are white, then go for replacement if (onlySpaces) @@ -732,7 +759,7 @@ }
putNewLine(); //put a new indentation line - putCharsInBuffer(" "); + putCharsInBuffer(" "); //align with <!-- oldChar = ' '; //and update the last char } else @@ -744,9 +771,11 @@ else //the comments must be inlined { readWhites(TRUE); //strip the whites and add a space if needed - if (getPreviousInsertedChar() != ' ') + if (getPreviousInsertedChar() != ' ' && + strncmp(xmlPrettyPrinted+xmlPrettyPrintedIndex-4, "<!--", 4) != 0) //prevents adding a space at the beginning { putCharInBuffer(' '); + oldChar = ' '; } } } @@ -772,14 +801,17 @@ bool inlineTextAllowed = FALSE; if (options->inlineText) { inlineTextAllowed = isInlineNodeAllowed(); } if (inlineTextAllowed && !options->oneLineText) { inlineTextAllowed = isOnSingleLine(0, '<', '/'); } - if (inlineTextAllowed || !options->alignText) { resetBackwardIndentation(TRUE); } //remove previous indentation - + if (inlineTextAllowed || !options->alignText) + { + resetBackwardIndentation(TRUE); //remove previous indentation + if (!inlineTextAllowed) { putNewLine(); } + } + //the leading whites are automatically stripped. So we re-add it if (!options->trimLeadingWhites) { int backwardIndex = inputBufferIndex-1; - while (inputBuffer[backwardIndex] == ' ' || - inputBuffer[backwardIndex] == '\t') + while (isSpace(inputBuffer[backwardIndex])) { --backwardIndex; //backward rolling } @@ -810,12 +842,9 @@ //as we can put text on one line, remove the line break //and replace it by a space but only if the previous //char wasn't a space - if (getPreviousInsertedChar() != ' ') - { - putCharInBuffer(' '); - } + if (getPreviousInsertedChar() != ' ') { putCharInBuffer(' '); } } - else if (options->alignComment) + else if (options->alignText) { int read = readWhites(FALSE); if (nextChar == '\r' && read == 0 && getNextChar() == '\n') //handles the '\r\n' @@ -852,7 +881,7 @@ }
//remove the indentation for the closing tag - if (inlineTextAllowed || !options->alignText) { appendIndentation = FALSE; } + if (inlineTextAllowed) { appendIndentation = FALSE; }
//there vas no node open lastNodeOpen = FALSE; @@ -862,6 +891,7 @@ { bool inlineAllowed = FALSE; if (options->inlineCdata) { inlineAllowed = isInlineNodeAllowed(); } + if (inlineAllowed && !options->oneLineCdata) { inlineAllowed = isOnSingleLine(9, ']', ']'); } if (inlineAllowed) { resetBackwardIndentation(TRUE); }
putNextCharsInBuffer(9); //putting the '<![CDATA[' into the buffer @@ -876,24 +906,93 @@
if (!isLineBreak(nextChar)) //the cdata simply continues { - putCharInBuffer(nextChar); - oldChar = nextChar; + if (options->oneLineCdata && isSpace(nextChar)) + { + //removes all the unecessary spaces + while(isSpace(nextChar2)) + { + nextChar = readNextChar(); + nextChar2 = getNextChar(); + } + + putCharInBuffer(' '); + oldChar = ' '; + } + else + { + //comment is left untouched + putCharInBuffer(nextChar); + oldChar = nextChar; + } + + if (!loop && options->alignCdata) //end of cdata + { + //ensures the chars preceding the first '-' are all spaces (there are at least + //10 spaces in front of the ']]>' for the alignment with '<![CDATA[') + bool onlySpaces = xmlPrettyPrinted[xmlPrettyPrintedIndex-3] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-4] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-5] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-6] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-7] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-8] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-9] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-10] == ' ' && + xmlPrettyPrinted[xmlPrettyPrintedIndex-11] == ' '; + + //if all the preceding chars are white, then go for replacement + if (onlySpaces) + { + xmlPrettyPrintedIndex -= 11; //remove indentation spaces + putCharsInBuffer("]]"); //reset the first chars of '-->' + } + } } - else if (!options->oneLineCdata) + else if (!options->oneLineCdata && !inlineAllowed) //line break { - readWhites(TRUE); //strip the whites and new line - putNewLine(); //put a new indentation line - oldChar = ' '; //and update the last char - - //TODO manage relative spacing + //if the cdata need to be aligned, just add 9 spaces + if (options->alignCdata) + { + int read = readWhites(FALSE); //strip the whites and new line + if (nextChar == '\r' && read == 0 && getNextChar() == '\n') //handles the \r\n return line + { + readNextChar(); + readWhites(FALSE); + } + + putNewLine(); //put a new indentation line + putCharsInBuffer(" "); //align with <![CDATA[ + oldChar = ' '; //and update the last char + } + else + { + putCharInBuffer(nextChar); + oldChar = nextChar; + } } else //cdata are inlined { readWhites(TRUE); //strip the whites and add a space if necessary - if(getPreviousInsertedChar() != ' ') { putCharInBuffer(' '); } + if(getPreviousInsertedChar() != ' ' && + strncmp(xmlPrettyPrinted+xmlPrettyPrintedIndex-9, "<![CDATA[", 9) != 0) //prevents adding a space at the beginning + { + putCharInBuffer(' '); + oldChar = ' '; + } } }
+ //if the cdata is inline, then all the trailing spaces are removed + if (options->oneLineCdata) + { + xmlPrettyPrintedIndex -= 2; //because of the last ']]' inserted + while(isWhite(xmlPrettyPrinted[xmlPrettyPrintedIndex-1])) + { + --xmlPrettyPrintedIndex; + } + putCharsInBuffer("]]"); + } + + //finalize the cdata char lastChar = readNextChar(); //should be '>' if (lastChar != '>') { @@ -906,7 +1005,7 @@
if (inlineAllowed) { appendIndentation = FALSE; }
- //there vas no node open + //there was no node open lastNodeOpen = FALSE; }
Modified: trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h =================================================================== --- trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h 2011-08-02 21:05:20 UTC (rev 2116) +++ trunk/geany-plugins/pretty-printer/src/PrettyPrinter.h 2011-08-03 09:49:27 UTC (rev 2117) @@ -32,6 +32,8 @@
//========================================== DEFINES ===========================================================
+#define PRETTY_PRINTER_VERSION "1.3" + #define PRETTY_PRINTING_SUCCESS 0 #define PRETTY_PRINTING_INVALID_CHAR_ERROR 1 #define PRETTY_PRINTING_EMPTY_XML 2 @@ -72,6 +74,7 @@ bool trimTrailingWhites; //trim the trailing whites in a text node bool alignComment; //align the comments. If false, comments are untouched (only if oneLineComment = false) bool alignText; //align the text in a node. If false, text is untouched (only if oneLineText = false) + bool alignCdata; //align the cdata. If false, cdata is untouched (only if oneLineCdata = false) } PrettyPrintingOptions;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.