mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-02-04 01:47:02 +03:00
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
This commit is contained in:
parent
5f9d9ceb3d
commit
d2e62311cd
@ -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;
|
||||
|
||||
|
||||
|
22
xmllint.c
22
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++;
|
||||
|
92
xmlsave.c
92
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);
|
||||
}
|
||||
@ -500,32 +502,90 @@ static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
|
||||
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
|
||||
@ -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))) {
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user