diff --git a/include/tidyenum.h b/include/tidyenum.h
index 5f96935..58454fe 100644
--- a/include/tidyenum.h
+++ b/include/tidyenum.h
@@ -270,7 +270,9 @@ extern "C" {
FN(COERCE_TO_ENDTAG) \
FN(ELEMENT_NOT_EMPTY) \
FN(UNEXPECTED_END_OF_FILE) \
- FN(UNEXPECTED_ENDTAG)
+ FN(UNEXPECTED_ENDTAG) \
+ FN(MOVED_STYLE_TO_HEAD) \
+ FN(FOUND_STYLE_IN_BODY)
/** These are report messages added by Tidy's accessibility module. */
@@ -648,6 +650,7 @@ typedef enum
TidyXmlPIs, /**< If set to yes PIs must end with ?> */
TidyXmlSpace, /**< If set to yes adds xml:space attr as needed */
TidyXmlTags, /**< Treat input as XML */
+ TidyStyleTags, /**< Move sytle to head */
N_TIDY_OPTIONS /**< Must be last */
} TidyOptionId;
diff --git a/src/clean.c b/src/clean.c
index 779ddec..9ef3d8b 100644
--- a/src/clean.c
+++ b/src/clean.c
@@ -2647,6 +2647,57 @@ void TY_(FixAnchors)(TidyDocImpl* doc, Node *node, Bool wantName, Bool wantId)
}
}
+/* Issue #567 - move style elements from body to head
+ * ==================================================
+ */
+static void StyleToHead(TidyDocImpl* doc, Node *head, Node *node, Bool fix, int indent)
+{
+ Node *next;
+ while (node)
+ {
+ next = node->next; /* get 'next' now , in case the node is moved */
+ /* dbg_show_node(doc, node, 0, indent); */
+ if (nodeIsSTYLE(node))
+ {
+ if (fix)
+ {
+ TY_(RemoveNode)(node); /* unhook style node from body */
+ TY_(InsertNodeAtEnd)(head, node); /* add to end of head */
+ TY_(ReportNotice)(doc, node, head, MOVED_STYLE_TO_HEAD); /* report move */
+ }
+ else
+ {
+ TY_(ReportNotice)(doc, node, head, FOUND_STYLE_IN_BODY);
+ }
+ }
+ else if (node->content)
+ {
+ StyleToHead(doc, head, node->content, fix, indent + 1);
+ }
+ node = next; /* process the 'next', if any */
+ }
+}
+
+
+void TY_(CleanStyle)(TidyDocImpl* doc, Node *html)
+{
+ Node *head = NULL, *body = NULL;
+ Bool fix = cfgBool(doc, TidyStyleTags);
+
+ if (!html)
+ return; /* oops, not given a start node */
+
+ head = TY_(FindHEAD)( doc );
+ body = TY_(FindBody)( doc );
+
+ if ((head != NULL) && (body != NULL))
+ {
+ StyleToHead(doc, head, body, fix, 0); /* found head and body */
+ }
+}
+/* ==================================================
+ */
+
/*
* local variables:
* mode: c
diff --git a/src/clean.h b/src/clean.h
index 00d4923..eb659fd 100644
--- a/src/clean.h
+++ b/src/clean.h
@@ -78,5 +78,7 @@ void TY_(FixAnchors)(TidyDocImpl* doc, Node *node, Bool wantName, Bool wantId);
void TY_(FixXhtmlNamespace)(TidyDocImpl* doc, Bool wantXmlns);
void TY_(FixLanguageInformation)(TidyDocImpl* doc, Node* node, Bool wantXmlLang, Bool wantLang);
+/* Issue #567 - move style elements from body to head */
+void TY_(CleanStyle)(TidyDocImpl* doc, Node *html);
#endif /* __CLEAN_H__ */
diff --git a/src/config.c b/src/config.c
index cd1d20c..6acb350 100644
--- a/src/config.c
+++ b/src/config.c
@@ -312,6 +312,7 @@ static const TidyOptionImpl option_defs[] =
{ TidyXmlPIs, MU, "assume-xml-procins", BL, no, ParsePickList, &boolPicks },
{ TidyXmlSpace, MU, "add-xml-space", BL, no, ParsePickList, &boolPicks },
{ TidyXmlTags, MU, "input-xml", BL, no, ParsePickList, &boolPicks },
+ { TidyStyleTags, MU, "fix-style-tags", BL, yes, ParsePickList, &boolPicks },
{ N_TIDY_OPTIONS, XX, NULL, XY, 0, NULL, NULL }
};
diff --git a/src/language_en.h b/src/language_en.h
index 8628e9b..976acda 100644
--- a/src/language_en.h
+++ b/src/language_en.h
@@ -1512,6 +1512,18 @@ static languageDefinition language_en = { whichPluralForm_en, {
"This option specifies if Tidy should use the XML parser rather than the "
"error correcting HTML parser. "
},
+ {/* 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. */
+ TidyStyleTags, 0,
+ "This option specifies if Tidy should move all style tags to the "
+ "head of the document. "
+ },
/********************************************
@@ -1890,8 +1902,9 @@ static languageDefinition language_en = { whichPluralForm_en, {
{ ELEMENT_NOT_EMPTY, 0, "%s element not empty or not closed" }, /* ReportError, ReportAttrError */
{ UNEXPECTED_END_OF_FILE, 0, "unexpected end of file %s" }, /* ReportError, ReportAttrError */
{ UNEXPECTED_ENDTAG, 0, "unexpected %s>" }, /* ReportError, ReportFatal */
+ { MOVED_STYLE_TO_HEAD, 0, "moved