diff --git a/console/tidy.c b/console/tidy.c
index 0d6179b..d340c86 100755
--- a/console/tidy.c
+++ b/console/tidy.c
@@ -576,6 +576,12 @@ static void GetOption(TidyDoc tdoc, /**< The tidy document. */
d->vals = "tagX, tagY, ...";
d->def = NULL;
break;
+
+ case TidyPriorityAttributes:
+ d->type = "Attributes Names";
+ d->vals = "attributeX, attributeY, ...";
+ d->def = NULL;
+ break;
case TidyCharEncoding:
case TidyInCharEncoding:
diff --git a/include/tidy.h b/include/tidy.h
index 29ccc09..3b5762a 100644
--- a/include/tidy.h
+++ b/include/tidy.h
@@ -925,7 +925,7 @@ TIDY_EXPORT TidyIterator TIDY_CALL tidyOptGetDocLinksList(TidyDoc tdoc, /**< T
/** Given a valid TidyIterator initiated with tidyOptGetDocLinksList(), returns
** a TidyOption instance.
- ** @result Returns in instane of TidyOption.
+ ** @result Returns in instance of TidyOption.
*/
TIDY_EXPORT TidyOption TIDY_CALL tidyOptGetNextDocLinks(TidyDoc tdoc, /**< The tidy document to query. */
TidyIterator* pos /**< The TidyIterator (initiated with tidyOptGetDocLinksList()) token. */
diff --git a/include/tidyenum.h b/include/tidyenum.h
old mode 100644
new mode 100755
index 4bbae26..6f4ff19
--- a/include/tidyenum.h
+++ b/include/tidyenum.h
@@ -220,6 +220,7 @@ extern "C" {
FN(MISSING_ENDTAG_FOR) \
FN(MISSING_IMAGEMAP) \
FN(MISSING_QUOTEMARK) \
+ FN(MISSING_QUOTEMARK_OPEN) \
FN(MISSING_SEMICOLON_NCR) \
FN(MISSING_SEMICOLON) \
FN(MISSING_STARTTAG) \
@@ -607,6 +608,7 @@ typedef enum
TidyPPrintTabs, /**< Indent using tabs istead of spaces */
TidyPreserveEntities, /**< Preserve entities */
TidyPreTags, /**< Declared pre tags */
+ TidyPriorityAttributes, /**< Attributes to place first in an element */
#if SUPPORT_ASIAN_ENCODINGS
TidyPunctWrap, /**< consider punctuation and breaking spaces for wrapping */
#else
diff --git a/localize/translations/tidy.pot b/localize/translations/tidy.pot
index 27a3879..3a5c734 100644
--- a/localize/translations/tidy.pot
+++ b/localize/translations/tidy.pot
@@ -5,7 +5,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: HTML Tidy poconvert.rb\n"
"Project-Id-Version: \n"
-"POT-Creation-Date: 2017-09-19 14:00:03\n"
+"POT-Creation-Date: 2017-09-23 07:53:22\n"
"Last-Translator: jderry\n"
"Language-Team: \n"
@@ -1055,6 +1055,24 @@ msgid ""
"This option is ignored in XML mode. "
msgstr ""
+#. Important notes for translators:
+#. - Use only
, , , , and
+#.
.
+#. - Entities, tags, attributes, etc., should be enclosed in
.
+#. - Option values should be enclosed in .
+#. - It's very important that
be self-closing!
+#. - The strings "Tidy" and "HTML Tidy" are the program name and must not
+#. be translated.
+msgctxt "TidyPriorityAttributes"
+msgid ""
+"This option allows prioritizing the writing of attributes in tidied "
+"documents, allowing them to written before the other attributes of an "
+"element. For example, you might specify that id and "
+"name are written before every other attribute. "
+"
"
+"This option takes a space or comma separated list of attribute names. "
+msgstr ""
+
#. Important notes for translators:
#. - Use only
, , , , and
#.
.
@@ -1226,6 +1244,10 @@ msgid ""
"This option specifies that Tidy should sort attributes within an element "
"using the specified sort algorithm. If set to alpha, the "
"algorithm is an ascending alphabetic sort. "
+"
"
+"When used while sorting with priority-attributes
, any "
+"attribute sorting will take place after the priority attributes have "
+"been output. "
msgstr ""
#. Important notes for translators:
@@ -2329,6 +2351,11 @@ msgctxt "MISSING_QUOTEMARK"
msgid "%s attribute with missing trailing quote mark"
msgstr ""
+#, c-format
+msgctxt "MISSING_QUOTEMARK_OPEN"
+msgid "value for attribute \"%s\" missing quote marks"
+msgstr ""
+
#, c-format
msgctxt "MISSING_SEMICOLON_NCR"
msgid "numeric character reference \"%s\" doesn't end in ';'"
diff --git a/src/attrs.c b/src/attrs.c
index a4cb379..adb2695 100644
--- a/src/attrs.c
+++ b/src/attrs.c
@@ -929,6 +929,49 @@ AttVal* TY_(RepairAttrValue)(TidyDocImpl* doc, Node* node, ctmbstr name, ctmbstr
return TY_(AddAttribute)(doc, node, name, value);
}
+
+void TY_(FreeAttrPriorityList)( TidyDocImpl* doc )
+{
+ PriorityAttribs *priorities = &(doc->attribs.priorityAttribs);
+
+ if ( priorities->list )
+ {
+ uint i = 0;
+ while ( priorities->list[i] != NULL )
+ {
+ TidyFree( doc->allocator, priorities->list[i] );
+ i++;
+ }
+
+ TidyFree( doc->allocator, priorities->list );
+ }
+}
+
+void TY_(DefinePriorityAttribute)(TidyDocImpl* doc, ctmbstr name)
+{
+ enum { capacity = 10 };
+ PriorityAttribs *priorities = &(doc->attribs.priorityAttribs);
+
+ if ( !priorities->list )
+ {
+ priorities->list = TidyAlloc(doc->allocator, sizeof(ctmbstr) * capacity );
+ priorities->list[0] = NULL;
+ priorities->capacity = capacity;
+ priorities->count = 0;
+ }
+
+ if ( priorities->count >= priorities->capacity )
+ {
+ priorities->capacity = priorities->capacity * 2;
+ priorities->list = realloc( priorities->list, sizeof(tmbstr) * priorities->capacity + 1 );
+ }
+
+ priorities->list[priorities->count] = TY_(tmbstrdup)( doc->allocator, name);
+ priorities->count++;
+ priorities->list[priorities->count] = NULL;
+}
+
+
static Bool CheckAttrType( TidyDocImpl* doc,
ctmbstr attrname, AttrCheck type )
{
@@ -2174,15 +2217,15 @@ void CheckType( TidyDocImpl* doc, Node *node, AttVal *attval)
}
static
-AttVal *SortAttVal( AttVal* list, TidyAttrSortStrategy strat );
+AttVal *SortAttVal( TidyDocImpl* doc, AttVal* list, TidyAttrSortStrategy strat );
-void TY_(SortAttributes)(Node* node, TidyAttrSortStrategy strat)
+void TY_(SortAttributes)(TidyDocImpl* doc, Node* node, TidyAttrSortStrategy strat)
{
while (node)
{
- node->attributes = SortAttVal( node->attributes, strat );
+ node->attributes = SortAttVal( doc, node->attributes, strat );
if (node->content)
- TY_(SortAttributes)(node->content, strat);
+ TY_(SortAttributes)(doc, node->content, strat);
node = node->next;
}
}
@@ -2219,25 +2262,88 @@ void TY_(SortAttributes)(Node* node, TidyAttrSortStrategy strat)
* SOFTWARE.
*/
-typedef int(*ptAttValComparator)(AttVal *one, AttVal *two);
+typedef int(*ptAttValComparator)(AttVal *one, AttVal *two, ctmbstr *list);
-/* Comparison function for TidySortAttrAlpha */
+/* Returns the index of the item in the array, or -1 if not in the array */
static
-int AlphaComparator(AttVal *one, AttVal *two)
+int indexof( ctmbstr item, ctmbstr *list )
{
+ if ( list )
+ {
+ uint i = 0;
+ while ( list[i] != NULL ) {
+ if ( TY_(tmbstrcasecmp)(item, list[i]) == 0 )
+ return i;
+ i++;
+ }
+ }
+
+ return -1;
+}
+
+/* Comparison function for TidySortAttrAlpha. Will also consider items in
+ the passed in list as higher-priority, and will group them first.
+ */
+static
+int AlphaComparator(AttVal *one, AttVal *two, ctmbstr *list)
+{
+ int oneIndex = indexof( one->attribute, list );
+ int twoIndex = indexof( two->attribute, list );
+
+ /* If both on the list, the lower index has priority. */
+ if ( oneIndex >= 0 && twoIndex >= 0 )
+ return oneIndex < twoIndex ? -1 : 1;
+
+ /* If A on the list but B not on the list, then A has priority. */
+ if ( oneIndex >= 0 && twoIndex == -1 )
+ return -1;
+
+ /* If A not on the list but B is on the list, then B has priority. */
+ if ( oneIndex == -1 && twoIndex >= 0 )
+ return 1;
+
+ /* Otherwise nothing is on the list, so just compare strings. */
return TY_(tmbstrcmp)(one->attribute, two->attribute);
}
+/* Comparison function for prioritizing list items. It doesn't otherwise
+ sort.
+ */
+static
+int PriorityComparator(AttVal *one, AttVal *two, ctmbstr *list)
+{
+ int oneIndex = indexof( one->attribute, list );
+ int twoIndex = indexof( two->attribute, list );
+
+ /* If both on the list, the lower index has priority. */
+ if ( oneIndex >= 0 && twoIndex >= 0 )
+ return oneIndex < twoIndex ? -1 : 1;
+
+ /* If A on the list but B not on the list, then A has priority. */
+ if ( oneIndex >= 0 && twoIndex == -1 )
+ return -1;
+
+ /* If A not on the list but B is on the list, then B has priority. */
+ if ( oneIndex == -1 && twoIndex >= 0 )
+ return 1;
+
+ /* Otherwise nothing is on the list, so just mark them as the same. */
+ return 0;
+}
+
+
/* The "factory method" that returns a pointer to the comparator function */
static
-ptAttValComparator GetAttValComparator(TidyAttrSortStrategy strat)
+ptAttValComparator GetAttValComparator(TidyAttrSortStrategy strat, ctmbstr *list)
{
switch (strat)
{
case TidySortAttrAlpha:
return AlphaComparator;
case TidySortAttrNone:
+ if ( list && list[0] )
+ return PriorityComparator;
break;
}
return 0;
@@ -2245,9 +2351,14 @@ ptAttValComparator GetAttValComparator(TidyAttrSortStrategy strat)
/* The sort routine */
static
-AttVal *SortAttVal( AttVal *list, TidyAttrSortStrategy strat)
+AttVal *SortAttVal( TidyDocImpl* doc, AttVal *list, TidyAttrSortStrategy strat)
{
- ptAttValComparator ptComparator = GetAttValComparator(strat);
+ /* Get the list from the passed-in tidyDoc. */
+// ctmbstr* priorityList = (ctmbstr*)doc->attribs.priorityAttribs.list;
+// ctmbstr priorityList[] = { "id", NULL };
+ ctmbstr* priorityList = (ctmbstr*)doc->attribs.priorityAttribs.list;
+
+ ptAttValComparator ptComparator = GetAttValComparator(strat, priorityList);
AttVal *p, *q, *e, *tail;
int insize, nmerges, psize, qsize, i;
@@ -2258,6 +2369,10 @@ AttVal *SortAttVal( AttVal *list, TidyAttrSortStrategy strat)
if (!list)
return NULL;
+ /* If no comparator, return the list as-is */
+ if (ptComparator == 0)
+ return list;
+
insize = 1;
while (1) {
@@ -2291,7 +2406,7 @@ AttVal *SortAttVal( AttVal *list, TidyAttrSortStrategy strat)
} else if (qsize == 0 || !q) {
/* q is empty; e must come from p. */
e = p; p = p->next; psize--;
- } else if (ptComparator(p,q) <= 0) {
+ } else if (ptComparator(p,q, priorityList) <= 0) {
/* First element of p is lower (or same);
* e must come from p. */
e = p; p = p->next; psize--;
diff --git a/src/attrs.h b/src/attrs.h
index 0192efc..22b4041 100644
--- a/src/attrs.h
+++ b/src/attrs.h
@@ -60,6 +60,13 @@ enum
ANCHOR_HASH_SIZE=1021u
};
+/* Keeps a list of attributes that are sorted ahead of the others. */
+typedef struct _priorityAttribs {
+ tmbstr* list;
+ uint count;
+ uint capacity;
+} PriorityAttribs;
+
struct _TidyAttribImpl
{
/* anchor/node lookup */
@@ -68,6 +75,9 @@ struct _TidyAttribImpl
/* Declared literal attributes */
Attribute* declared_attr_list;
+ /* Prioritized list of attributes to write */
+ PriorityAttribs priorityAttribs;
+
#if ATTRIBUTE_HASH_LOOKUP
AttrHash* hashtab[ATTRIBUTE_HASH_SIZE];
#endif
@@ -93,6 +103,9 @@ AttVal* TY_(AddAttribute)( TidyDocImpl* doc,
AttVal* TY_(RepairAttrValue)(TidyDocImpl* doc, Node* node, ctmbstr name, ctmbstr value);
+/* Add an item to the list of priority attributes to write first. */
+void TY_(DefinePriorityAttribute)(TidyDocImpl* doc, ctmbstr name);
+
Bool TY_(IsUrl)( TidyDocImpl* doc, ctmbstr attrname );
/* Bool IsBool( TidyDocImpl* doc, ctmbstr attrname ); */
@@ -132,13 +145,15 @@ void TY_(FreeAnchors)( TidyDocImpl* doc );
void TY_(InitAttrs)( TidyDocImpl* doc );
void TY_(FreeAttrTable)( TidyDocImpl* doc );
+void TY_(FreeAttrPriorityList)( TidyDocImpl* doc );
+
void TY_(AppendToClassAttr)( TidyDocImpl* doc, AttVal *classattr, ctmbstr classname );
/*
the same attribute name can't be used
more than once in each element
*/
void TY_(RepairDuplicateAttributes)( TidyDocImpl* doc, Node* node, Bool isXml );
-void TY_(SortAttributes)(Node* node, TidyAttrSortStrategy strat);
+void TY_(SortAttributes)(TidyDocImpl* doc, Node* node, TidyAttrSortStrategy strat);
Bool TY_(IsBoolAttribute)( AttVal* attval );
Bool TY_(attrIsEvent)( AttVal* attval );
diff --git a/src/config.c b/src/config.c
index 64003ea..8de74c6 100644
--- a/src/config.c
+++ b/src/config.c
@@ -175,6 +175,9 @@ static void AdjustConfig( TidyDocImpl* doc );
/* parser for integer values */
static ParseProperty ParseInt;
+/* a space or comma separated list */
+static ParseProperty ParseList;
+
/* a string excluding whitespace */
static ParseProperty ParseName;
@@ -277,6 +280,7 @@ static const TidyOptionImpl option_defs[] =
{ TidyPPrintTabs, PP, "indent-with-tabs", BL, no, ParseTabs, &boolPicks }, /* 20150515 - Issue #108 */
{ TidyPreserveEntities, MU, "preserve-entities", BL, no, ParsePickList, &boolPicks },
{ TidyPreTags, MU, "new-pre-tags", ST, 0, ParseTagNames, NULL },
+ { TidyPriorityAttributes, MU, "priority-attributes", ST, 0, ParseList, NULL },
#if SUPPORT_ASIAN_ENCODINGS
{ TidyPunctWrap, PP, "punctuation-wrap", BL, no, ParsePickList, &boolPicks },
#endif
@@ -1087,6 +1091,106 @@ void AdjustConfig( TidyDocImpl* doc )
}
}
+
+/* Coordinates Config update and Attributes data for priority attributes, as
+ a service to ParseList().
+ */
+void TY_(DeclarePriorityAttrib)( TidyDocImpl* doc, TidyOptionId optId, ctmbstr name )
+{
+ ctmbstr prvval = cfgStr( doc, optId );
+ tmbstr catval = NULL;
+ ctmbstr theval = name;
+ if ( prvval )
+ {
+ uint len = TY_(tmbstrlen)(name) + TY_(tmbstrlen)(prvval) + 3;
+ catval = TY_(tmbstrndup)( doc->allocator, prvval, len );
+ TY_(tmbstrcat)( catval, ", " );
+ TY_(tmbstrcat)( catval, name );
+ theval = catval;
+ }
+
+ TY_(DefinePriorityAttribute)( doc, name );
+ SetOptionValue( doc, optId, theval );
+ if ( catval )
+ TidyDocFree( doc, catval );
+ }
+
+/* a space or comma separated list of attribute names */
+Bool ParseList( TidyDocImpl* doc, const TidyOptionImpl* option )
+{
+ TidyConfigImpl* cfg = &doc->config;
+ tmbchar buf[1024];
+ uint i = 0, nItems = 0;
+ uint c = SkipWhite( cfg );
+
+ SetOptionValue( doc, option->id, NULL );
+
+ do
+ {
+ if (c == ' ' || c == '\t' || c == ',')
+ {
+ c = AdvanceChar( cfg );
+ continue;
+ }
+
+ if ( c == '\r' || c == '\n' )
+ {
+ uint c2 = AdvanceChar( cfg );
+ if ( c == '\r' && c2 == '\n' )
+ c = AdvanceChar( cfg );
+ else
+ c = c2;
+
+ if ( !TY_(IsWhite)(c) )
+ {
+ buf[i] = 0;
+ TY_(UngetChar)( c, cfg->cfgIn );
+ TY_(UngetChar)( '\n', cfg->cfgIn );
+ break;
+ }
+ }
+
+ while ( i < sizeof(buf)-2 && c != EndOfStream && !TY_(IsWhite)(c) && c != ',' )
+ {
+ buf[i++] = (tmbchar) c;
+ c = AdvanceChar( cfg );
+ }
+
+ buf[i] = '\0';
+ if (i == 0) /* Skip empty attribute definition. Possible when */
+ continue; /* there is a trailing space on the line. */
+
+ /* add attribute to array */
+ switch ( option->id )
+ {
+ case TidyPriorityAttributes:
+ TY_(DeclarePriorityAttrib)( doc, option->id, buf );
+ break;
+
+ default:
+ break;
+ }
+
+ i = 0;
+ ++nItems;
+ }
+ while ( c != EndOfStream );
+
+ if ( i > 0 )
+ switch ( option->id )
+ {
+ case TidyPriorityAttributes:
+ TY_(DeclarePriorityAttrib)( doc, option->id, buf );
+ break;
+
+ default:
+ break;
+ }
+
+ return ( nItems > 0 );
+}
+
+
/* unsigned integers */
Bool ParseInt( TidyDocImpl* doc, const TidyOptionImpl* entry )
{
@@ -1351,9 +1455,9 @@ Bool ParseTagNames( TidyDocImpl* doc, const TidyOptionImpl* option )
return ( nTags > 0 );
}
+
/* a string including whitespace */
/* munges whitespace sequences */
-
Bool ParseString( TidyDocImpl* doc, const TidyOptionImpl* option )
{
TidyConfigImpl* cfg = &doc->config;
diff --git a/src/language_en.h b/src/language_en.h
old mode 100644
new mode 100755
index addf8d1..18db40c
--- a/src/language_en.h
+++ b/src/language_en.h
@@ -1005,6 +1005,22 @@ static languageDefinition language_en = { whichPluralForm_en, {
"
"
"This option is ignored in XML mode. "
},
+ {/* Important notes for translators:
+ - Use only
, , , , and
+
.
+ - Entities, tags, attributes, etc., should be enclosed in
.
+ - Option values should be enclosed in .
+ - It's very important that
be self-closing!
+ - The strings "Tidy" and "HTML Tidy" are the program name and must not
+ be translated. */
+ TidyPriorityAttributes, 0,
+ "This option allows prioritizing the writing of attributes in tidied "
+ "documents, allowing them to written before the other attributes of an "
+ "element. For example, you might specify that id and "
+ "name are written before every other attribute. "
+ "
"
+ "This option takes a space or comma separated list of attribute names. "
+ },
#if SUPPORT_ASIAN_ENCODINGS
{/* Important notes for translators:
- Use only
, , , , and
@@ -1156,6 +1172,10 @@ static languageDefinition language_en = { whichPluralForm_en, {
"This option specifies that Tidy should sort attributes within an element "
"using the specified sort algorithm. If set to alpha, the "
"algorithm is an ascending alphabetic sort. "
+ "
"
+ "When used while sorting with priority-attributes
, any "
+ "attribute sorting will take place after the priority attributes have "
+ "been output. "
},
{/* Important notes for translators:
- Use only
, , , , and
@@ -1877,6 +1897,7 @@ static languageDefinition language_en = { whichPluralForm_en, {
{ MISSING_ENDTAG_FOR, 0, "missing %s>" },
{ MISSING_IMAGEMAP, 0, "%s should use client-side image map" },
{ MISSING_QUOTEMARK, 0, "%s attribute with missing trailing quote mark" },
+ { MISSING_QUOTEMARK_OPEN, 0, "value for attribute \"%s\" missing quote marks" },
{ MISSING_SEMICOLON_NCR, 0, "numeric character reference \"%s\" doesn't end in ';'" },
{ MISSING_SEMICOLON, 0, "entity \"%s\" doesn't end in ';'" },
{ MISSING_STARTTAG, 0, "missing <%s>" },
diff --git a/src/lexer.c b/src/lexer.c
old mode 100644
new mode 100755
index a23ed8e..4ff4388
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -3621,8 +3621,9 @@ static Node *ParsePhp( TidyDocImpl* doc )
}
/* consumes the '>' terminating start tags */
+/* @TODO: float the errors back to the calling method */
static tmbstr ParseAttribute( TidyDocImpl* doc, Bool *isempty,
- Node **asp, Node **php)
+ Node **asp, Node **php )
{
Lexer* lexer = doc->lexer;
int start, len = 0;
@@ -3984,8 +3985,6 @@ static tmbstr ParseValue( TidyDocImpl* doc, ctmbstr name,
{
uint q = c;
- TY_(ReportAttrError)( doc, lexer->token, NULL, UNEXPECTED_QUOTEMARK );
-
/* handle and ... */
/* this doesn't handle which browsers treat as */
/* 'foo"/' nor which browser treat as 'foo"' */
@@ -4156,7 +4155,7 @@ static tmbstr ParseValue( TidyDocImpl* doc, ctmbstr name,
value = NULL;
/* note delimiter if given */
- *pdelim = (delim ? delim : '"');
+ *pdelim = delim;
return value;
}
@@ -4273,11 +4272,13 @@ static AttVal* ParseAttrs( TidyDocImpl* doc, Bool *isempty )
(cfgBool(doc, TidyXmlTags) && IsValidXMLAttrName(attribute))))
{
av = TY_(NewAttribute)(doc);
- av->delim = delim;
+ av->delim = delim ? delim : '"';
av->attribute = attribute;
av->value = value;
av->dict = TY_(FindAttribute)( doc, av );
- AddAttrToList( &list, av );
+ AddAttrToList( &list, av );
+ if ( !delim && value )
+ TY_(ReportAttrError)( doc, lexer->token, av, MISSING_QUOTEMARK_OPEN);
}
else
{
diff --git a/src/message.c b/src/message.c
index f9149b4..409f571 100755
--- a/src/message.c
+++ b/src/message.c
@@ -309,6 +309,7 @@ static struct _dispatchTable {
{ MISSING_ENDTAG_FOR, TidyWarning, formatStandard },
{ MISSING_IMAGEMAP, TidyWarning, formatAttributeReport },
{ MISSING_QUOTEMARK, TidyWarning, formatAttributeReport },
+ { MISSING_QUOTEMARK_OPEN, TidyInfo, formatAttributeReport },
{ MISSING_SEMICOLON_NCR, TidyWarning, formatStandard },
{ MISSING_SEMICOLON, TidyWarning, formatStandard },
{ MISSING_STARTTAG, TidyWarning, formatStandard },
@@ -531,6 +532,9 @@ TidyMessageImpl *formatAttributeReport(TidyDocImpl* doc, Node *element, Node *no
switch (code)
{
+ case MISSING_QUOTEMARK_OPEN:
+ return TY_(tidyMessageCreateWithNode)(doc, node, code, level, name );
+
case BACKSLASH_IN_URI:
case ESCAPED_ILLEGAL_URI:
case FIXED_BACKSLASH:
@@ -546,14 +550,12 @@ TidyMessageImpl *formatAttributeReport(TidyDocImpl* doc, Node *element, Node *no
case UNEXPECTED_QUOTEMARK:
case WHITE_IN_URI:
return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc );
- break;
case ATTRIBUTE_IS_NOT_ALLOWED:
case JOINING_ATTRIBUTE:
case MISSING_ATTR_VALUE:
case PROPRIETARY_ATTRIBUTE:
return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, name );
- break;
case ATTRIBUTE_VALUE_REPLACED:
case BAD_ATTRIBUTE_VALUE:
@@ -561,30 +563,25 @@ TidyMessageImpl *formatAttributeReport(TidyDocImpl* doc, Node *element, Node *no
case INSERTING_AUTO_ATTRIBUTE:
case INVALID_ATTRIBUTE:
return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, name, value );
- break;
case MISMATCHED_ATTRIBUTE_ERROR:
case MISMATCHED_ATTRIBUTE_WARN:
return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, name, HTMLVersion(doc));
- break;
case ANCHOR_NOT_UNIQUE:
case ATTR_VALUE_NOT_LCASE:
case PROPRIETARY_ATTR_VALUE:
case XML_ID_SYNTAX:
return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, value );
- break;
case REPEATED_ATTRIBUTE:
return TY_(tidyMessageCreateWithNode)(doc, node, code, level, tagdesc, value, name );
- break;
case UNEXPECTED_END_OF_FILE_ATTR:
/* on end of file adjust reported position to end of input */
doc->lexer->lines = doc->docIn->curline;
doc->lexer->columns = doc->docIn->curcol;
return TY_(tidyMessageCreateWithLexer)(doc, code, level, tagdesc );
- break;
}
return NULL;
@@ -1427,6 +1424,7 @@ static const TidyOptionId TidyNumEntitiesLinks[] = { TidyDoctype, TidyPreser
static const TidyOptionId TidyOutCharEncodingLinks[] = { TidyCharEncoding, TidyUnknownOption };
static const TidyOptionId TidyOutFileLinks[] = { TidyErrFile, TidyUnknownOption };
static const TidyOptionId TidyPreTagsLinks[] = { TidyBlockTags, TidyEmptyTags, TidyInlineTags, TidyUseCustomTags, TidyUnknownOption };
+static const TidyOptionId TidySortAttributesLinks[] = { TidyPriorityAttributes, TidyUnknownOption };
static const TidyOptionId TidyUseCustomTagsLinks[] = { TidyBlockTags, TidyEmptyTags, TidyInlineTags, TidyPreTags, TidyUnknownOption };
static const TidyOptionId TidyWrapAttValsLinks[] = { TidyWrapScriptlets, TidyLiteralAttribs, TidyUnknownOption };
static const TidyOptionId TidyWrapScriptletsLinks[] = { TidyWrapAttVals, TidyUnknownOption };
@@ -1454,6 +1452,7 @@ static const TidyOptionDoc docs_xrefs[] =
{ TidyOutCharEncoding, TidyOutCharEncodingLinks },
{ TidyOutFile, TidyOutFileLinks },
{ TidyPreTags, TidyPreTagsLinks },
+ { TidySortAttributes, TidySortAttributesLinks },
{ TidyUseCustomTags, TidyUseCustomTagsLinks },
{ TidyWrapAttVals, TidyWrapAttValsLinks },
{ TidyWrapScriptlets, TidyWrapScriptletsLinks },
diff --git a/src/tidylib.c b/src/tidylib.c
index 162fe5d..c6104eb 100755
--- a/src/tidylib.c
+++ b/src/tidylib.c
@@ -181,6 +181,7 @@ void tidyDocRelease( TidyDocImpl* doc )
TY_(FreeConfig)( doc );
TY_(FreeAttrTable)( doc );
+ TY_(FreeAttrPriorityList)( doc );
TY_(FreeTags)( doc );
/*\
* Issue #186 - Now FreeNode depend on the doctype, so the lexer is needed
@@ -2215,8 +2216,7 @@ int tidyDocSaveStream( TidyDocImpl* doc, StreamOut* out )
else
TY_(ReplacePreformattedSpaces)(doc, &doc->root);
- if ( sortAttrStrat != TidySortAttrNone )
- TY_(SortAttributes)(&doc->root, sortAttrStrat);
+ TY_(SortAttributes)(doc, &doc->root, sortAttrStrat);
if ( showMarkup && (doc->errors == 0 || forceOutput) )
{