[libxml2] Add xmlSaveOption XML_SAVE_WSNONSIG



commit d2e62311cd15651e68f921167c7fcf05b19378f9
Author: Adam Spragg <adam spra gg>
Date:   Wed Nov 3 15:33:40 2010 +0100

    Add xmlSaveOption XML_SAVE_WSNONSIG
    
    non destructive indentation option using spaces within markup
    constructs and hence not modifying content
    * include/libxml/xmlsave.h: new option
    * xmlsave.c: some refactoring and new code for the new option
    * xmllint.c: adds --pretty option where option 2 uses the new formatting

 include/libxml/xmlsave.h |    3 +-
 xmllint.c                |   22 +++++++++++
 xmlsave.c                |   92 +++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 107 insertions(+), 10 deletions(-)
---
diff --git a/include/libxml/xmlsave.h b/include/libxml/xmlsave.h
index 4201b4d..fb329b2 100644
--- a/include/libxml/xmlsave.h
+++ b/include/libxml/xmlsave.h
@@ -33,7 +33,8 @@ typedef enum {
     XML_SAVE_NO_XHTML	= 1<<3, /* disable XHTML1 specific rules */
     XML_SAVE_XHTML	= 1<<4, /* force XHTML1 specific rules */
     XML_SAVE_AS_XML     = 1<<5, /* force XML serialization on HTML doc */
-    XML_SAVE_AS_HTML    = 1<<6  /* force HTML serialization on XML doc */
+    XML_SAVE_AS_HTML    = 1<<6, /* force HTML serialization on XML doc */
+    XML_SAVE_WSNONSIG   = 1<<7  /* format with non-significant whitespace */
 } xmlSaveOption;
 
 
diff --git a/xmllint.c b/xmllint.c
index aca0a7d..b7af32f 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -2658,6 +2658,8 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
 
                 if (format == 1)
 		    saveOpts |= XML_SAVE_FORMAT;
+                else if (format == 2)
+                    saveOpts |= XML_SAVE_WSNONSIG;
 
 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
                 if (xmlout)
@@ -3014,6 +3016,10 @@ static void usage(const char *name) {
     printf("\t--format : reformat/reindent the input\n");
     printf("\t--encode encoding : output in the given encoding\n");
     printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
+    printf("\t--pretty STYLE : pretty-print in a particular style\n");
+    printf("\t                 0 Do not pretty print\n");
+    printf("\t                 1 Format the XML content, as --format\n");
+    printf("\t                 2 Add whitespace inside tags, preserving content\n");
 #endif /* LIBXML_OUTPUT_ENABLED */
     printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
     printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
@@ -3338,6 +3344,17 @@ main(int argc, char **argv) {
 #endif /* LIBXML_OUTPUT_ENABLED */
 	     xmlKeepBlanksDefault(0);
 	}
+	else if ((!strcmp(argv[i], "-pretty")) ||
+	         (!strcmp(argv[i], "--pretty"))) {
+	     i++;
+#ifdef LIBXML_OUTPUT_ENABLED
+	     format = atoi(argv[i]);
+#endif /* LIBXML_OUTPUT_ENABLED */
+	     if (format == 1) {
+	         noblanks++;
+	         xmlKeepBlanksDefault(0);
+	     }
+	}
 #ifdef LIBXML_READER_ENABLED
 	else if ((!strcmp(argv[i], "-stream")) ||
 	         (!strcmp(argv[i], "--stream"))) {
@@ -3624,6 +3641,11 @@ main(int argc, char **argv) {
 	    i++;
 	    continue;
         }
+	if ((!strcmp(argv[i], "-pretty")) ||
+	         (!strcmp(argv[i], "--pretty"))) {
+	    i++;
+	    continue;
+        }
 	if ((!strcmp(argv[i], "-schema")) ||
 	         (!strcmp(argv[i], "--schema"))) {
 	    i++;
diff --git a/xmlsave.c b/xmlsave.c
index 745b98d..ddf7143 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -408,6 +408,8 @@ xmlNewSaveCtxt(const char *encoding, int options)
     ret->options = options;
     if (options & XML_SAVE_FORMAT)
         ret->format = 1;
+    else if (options & XML_SAVE_WSNONSIG)
+        ret->format = 2;
 
     return(ret);
 }
@@ -501,32 +503,90 @@ void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur);
 static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
 
 /**
+ * xmlOutputBufferWriteWSNonSig:
+ * @ctxt:  The save context
+ * @extra: Number of extra indents to apply to ctxt->level
+ *
+ * Write out formatting for non-significant whitespace output.
+ */
+static void
+xmlOutputBufferWriteWSNonSig(xmlSaveCtxtPtr ctxt, int extra)
+{
+    int i;
+    if ((ctxt == NULL) || (ctxt->buf == NULL))
+        return;
+    xmlOutputBufferWrite(ctxt->buf, 1, "\n");
+    for (i = 0; i < (ctxt->level + extra); i += ctxt->indent_nr) {
+        xmlOutputBufferWrite(ctxt->buf, ctxt->indent_size *
+                ((ctxt->level + extra - i) > ctxt->indent_nr ?
+                 ctxt->indent_nr : (ctxt->level + extra - i)),
+                ctxt->indent);
+    }
+}
+
+/**
  * xmlNsDumpOutput:
  * @buf:  the XML buffer output
  * @cur:  a namespace
+ * @ctxt: the output save context. Optional.
  *
  * Dump a local Namespace definition.
  * Should be called in the context of attributes dumps.
+ * If @ctxt is supplied, @buf should be its buffer.
  */
 static void
-xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur, xmlSaveCtxtPtr ctxt) {
     if ((cur == NULL) || (buf == NULL)) return;
     if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
 	if (xmlStrEqual(cur->prefix, BAD_CAST "xml"))
 	    return;
 
+	if (ctxt != NULL && ctxt->format == 2)
+	    xmlOutputBufferWriteWSNonSig(ctxt, 2);
+	else
+	    xmlOutputBufferWrite(buf, 1, " ");
+
         /* Within the context of an element attributes */
 	if (cur->prefix != NULL) {
-	    xmlOutputBufferWrite(buf, 7, " xmlns:");
+	    xmlOutputBufferWrite(buf, 6, "xmlns:");
 	    xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
 	} else
-	    xmlOutputBufferWrite(buf, 6, " xmlns");
+	    xmlOutputBufferWrite(buf, 5, "xmlns");
 	xmlOutputBufferWrite(buf, 1, "=");
 	xmlBufferWriteQuotedString(buf->buffer, cur->href);
     }
 }
 
 /**
+ * xmlNsDumpOutputCtxt
+ * @ctxt: the save context
+ * @cur:  a namespace
+ *
+ * Dump a local Namespace definition to a save context.
+ * Should be called in the context of attribute dumps.
+ */
+static void
+xmlNsDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
+    xmlNsDumpOutput(ctxt->buf, cur, ctxt);
+}
+
+/**
+ * xmlNsListDumpOutputCtxt
+ * @ctxt: the save context
+ * @cur:  the first namespace
+ *
+ * Dump a list of local namespace definitions to a save context.
+ * Should be called in the context of attribute dumps.
+ */
+static void
+xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
+    while (cur != NULL) {
+        xmlNsDumpOutput(ctxt->buf, cur, ctxt);
+	cur = cur->next;
+    }
+}
+
+/**
  * xmlNsListDumpOutput:
  * @buf:  the XML buffer output
  * @cur:  the first namespace
@@ -537,7 +597,7 @@ xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
 void
 xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
     while (cur != NULL) {
-        xmlNsDumpOutput(buf, cur);
+        xmlNsDumpOutput(buf, cur, NULL);
 	cur = cur->next;
     }
 }
@@ -612,7 +672,10 @@ xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
     if (cur == NULL) return;
     buf = ctxt->buf;
     if (buf == NULL) return;
-    xmlOutputBufferWrite(buf, 1, " ");
+    if (ctxt->format == 2)
+        xmlOutputBufferWriteWSNonSig(ctxt, 2);
+    else
+        xmlOutputBufferWrite(buf, 1, " ");
     if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
         xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
 	xmlOutputBufferWrite(buf, 1, ":");
@@ -808,13 +871,18 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
 	    xmlOutputBufferWrite(buf, 2, "<?");
 	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
 	    if (cur->content != NULL) {
-		xmlOutputBufferWrite(buf, 1, " ");
+	        if (ctxt->format == 2)
+	            xmlOutputBufferWriteWSNonSig(ctxt, 0);
+	        else
+	            xmlOutputBufferWrite(buf, 1, " ");
 		xmlOutputBufferWriteString(buf, (const char *)cur->content);
 	    }
 	    xmlOutputBufferWrite(buf, 2, "?>");
 	} else {
 	    xmlOutputBufferWrite(buf, 2, "<?");
 	    xmlOutputBufferWriteString(buf, (const char *)cur->name);
+	    if (ctxt->format == 2)
+	        xmlOutputBufferWriteWSNonSig(ctxt, 0);
 	    xmlOutputBufferWrite(buf, 2, "?>");
 	}
 	return;
@@ -862,7 +930,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
 	return;
     }
     if (cur->type == XML_NAMESPACE_DECL) {
-	xmlNsDumpOutput(buf, (xmlNsPtr) cur);
+	xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
 	return;
     }
 
@@ -887,16 +955,20 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
 
     xmlOutputBufferWriteString(buf, (const char *)cur->name);
     if (cur->nsDef)
-        xmlNsListDumpOutput(buf, cur->nsDef);
+        xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
     if (cur->properties != NULL)
         xmlAttrListDumpOutput(ctxt, cur->properties);
 
     if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
 	(cur->children == NULL) && ((ctxt->options & XML_SAVE_NO_EMPTY) == 0)) {
+        if (ctxt->format == 2)
+            xmlOutputBufferWriteWSNonSig(ctxt, 0);
         xmlOutputBufferWrite(buf, 2, "/>");
 	ctxt->format = format;
 	return;
     }
+    if (ctxt->format == 2)
+        xmlOutputBufferWriteWSNonSig(ctxt, 1);
     xmlOutputBufferWrite(buf, 1, ">");
     if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
 	xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
@@ -919,6 +991,8 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
     }
 
     xmlOutputBufferWriteString(buf, (const char *)cur->name);
+    if (ctxt->format == 2)
+        xmlOutputBufferWriteWSNonSig(ctxt, 0);
     xmlOutputBufferWrite(buf, 1, ">");
     ctxt->format = format;
 }
@@ -1410,7 +1484,7 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
 
     xmlOutputBufferWriteString(buf, (const char *)cur->name);
     if (cur->nsDef)
-        xmlNsListDumpOutput(buf, cur->nsDef);
+        xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
     if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
 	(cur->ns == NULL) && (cur->nsDef == NULL))) {
 	/*



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]