diff --git a/configdoc/usage.xml b/configdoc/usage.xml index beab30c27..7acaf3751 100644 --- a/configdoc/usage.xml +++ b/configdoc/usage.xml @@ -238,6 +238,11 @@ 279 + + + 282 + + 27 diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php index 321bdc566..5eaf2182a 100644 --- a/library/HTMLPurifier.includes.php +++ b/library/HTMLPurifier.includes.php @@ -162,6 +162,7 @@ require 'HTMLPurifier/HTMLModule/Image.php'; require 'HTMLPurifier/HTMLModule/Legacy.php'; require 'HTMLPurifier/HTMLModule/List.php'; +require 'HTMLPurifier/HTMLModule/MathML.php'; require 'HTMLPurifier/HTMLModule/Name.php'; require 'HTMLPurifier/HTMLModule/Nofollow.php'; require 'HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php'; @@ -191,6 +192,7 @@ require 'HTMLPurifier/Injector/AutoParagraph.php'; require 'HTMLPurifier/Injector/DisplayLinkURI.php'; require 'HTMLPurifier/Injector/Linkify.php'; +require 'HTMLPurifier/Injector/MathMLSpaceNormalize.php'; require 'HTMLPurifier/Injector/PurifierLinkify.php'; require 'HTMLPurifier/Injector/RemoveEmpty.php'; require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php'; diff --git a/library/HTMLPurifier.safe-includes.php b/library/HTMLPurifier.safe-includes.php index a3261f8a3..002938756 100644 --- a/library/HTMLPurifier.safe-includes.php +++ b/library/HTMLPurifier.safe-includes.php @@ -156,6 +156,7 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/Image.php'; require_once $__dir . '/HTMLPurifier/HTMLModule/Legacy.php'; require_once $__dir . '/HTMLPurifier/HTMLModule/List.php'; +require_once $__dir . '/HTMLPurifier/HTMLModule/MathML.php'; require_once $__dir . '/HTMLPurifier/HTMLModule/Name.php'; require_once $__dir . '/HTMLPurifier/HTMLModule/Nofollow.php'; require_once $__dir . '/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php'; @@ -185,6 +186,7 @@ require_once $__dir . '/HTMLPurifier/Injector/AutoParagraph.php'; require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php'; require_once $__dir . '/HTMLPurifier/Injector/Linkify.php'; +require_once $__dir . '/HTMLPurifier/Injector/MathMLSpaceNormalize.php'; require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php'; require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php'; require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php'; diff --git a/library/HTMLPurifier/AttrDef/MathML/Character.php b/library/HTMLPurifier/AttrDef/MathML/Character.php new file mode 100644 index 000000000..94248c559 --- /dev/null +++ b/library/HTMLPurifier/AttrDef/MathML/Character.php @@ -0,0 +1,25 @@ +get('Attr.IDPrefix'); + if ($prefix !== '') { + $prefix .= $config->get('Attr.IDPrefixLocal'); + // prevent re-appending the prefix + if (strpos($id, $prefix) !== 0) { + $id = $prefix . $id; + } + } elseif ($config->get('Attr.IDPrefixLocal') !== '') { + trigger_error( + '%Attr.IDPrefixLocal cannot be used unless ' . + '%Attr.IDPrefix is set', + E_USER_WARNING + ); + } + + // we purposely avoid using regex, hopefully this is faster + + if ($config->get('Attr.ID.HTML5') === true) { + if (preg_match('/[\t\n\x0b\x0c ]/', $id)) { + return false; + } + } else { + if (ctype_alpha($id)) { + // OK + } else { + if (!ctype_alpha(@$id[0])) { + return false; + } + // primitive style of regexps, I suppose + $trim = trim( + $id, + 'A..Za..z0..9:-._' + ); + if ($trim !== '') { + return false; + } + } + } + + $regexp = $config->get('Attr.IDBlacklistRegexp'); + if ($regexp && preg_match($regexp, $id)) { + return false; + } + + // if no change was made to the ID, return the result + // else, return the new id if stripping whitespace made it + // valid, or return false. + return $id; + } +} \ No newline at end of file diff --git a/library/HTMLPurifier/AttrDef/MathML/Length.php b/library/HTMLPurifier/AttrDef/MathML/Length.php new file mode 100644 index 000000000..98daee946 --- /dev/null +++ b/library/HTMLPurifier/AttrDef/MathML/Length.php @@ -0,0 +1,36 @@ +parseCDATA($string); + + // Optimizations + if ($string === '') { + return false; + } + if ($string === '0') { + return '0'; + } + + $length = HTMLPurifier_MathMLLength::make($string); + if (!$length->isValid()) { + return false; + } + + return $length->toString(); + } +} \ No newline at end of file diff --git a/library/HTMLPurifier/AttrTypes.php b/library/HTMLPurifier/AttrTypes.php index 3b70520b6..069137e57 100644 --- a/library/HTMLPurifier/AttrTypes.php +++ b/library/HTMLPurifier/AttrTypes.php @@ -50,10 +50,23 @@ public function __construct() // "proprietary" types $this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class(); + $this->info['CSS'] = new HTMLPurifier_AttrDef_CSS(); // number is really a positive integer (one or more digits) // FIXME: ^^ not always, see start and value of list items $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); + + // MathML types + $this->info['MathML_ID'] = new HTMLPurifier_AttrDef_MathML_ID(); + $this->info['MathML_Length'] = new HTMLPurifier_AttrDef_MathML_Length(); + $this->info['MathML_UnsignedInteger'] = new HTMLPurifier_AttrDef_Integer(false, true, true); + $this->info['MathML_PositiveInteger'] = new HTMLPurifier_AttrDef_Integer(false, false, true); + $this->info['MathML_Integer'] = new HTMLPurifier_AttrDef_Integer(true, true, true); + $this->info['MathML_UnsignedNumber'] = new HTMLPurifier_AttrDef_CSS_Number(true); + $this->info['MathML_Number'] = new HTMLPurifier_AttrDef_CSS_Number(false); + $this->info['MathML_Character'] = new HTMLPurifier_AttrDef_MathML_Character(); + $this->info['MathML_Color'] = new HTMLPurifier_AttrDef_MathML_Color(); + } private static function makeEnum($in) diff --git a/library/HTMLPurifier/ConfigSchema/schema.ser b/library/HTMLPurifier/ConfigSchema/schema.ser index b3fa2fb31..83345b736 100644 --- a/library/HTMLPurifier/ConfigSchema/schema.ser +++ b/library/HTMLPurifier/ConfigSchema/schema.ser @@ -1 +1 @@ -O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:125:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:125:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:138:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file +O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:126:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:11:"HTML.MathML";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:126:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:11:"HTML.MathML";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:139:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:11:"HTML.MathML";i:7;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file diff --git a/library/HTMLPurifier/ConfigSchema/schema/HTML.MathML.txt b/library/HTMLPurifier/ConfigSchema/schema/HTML.MathML.txt new file mode 100644 index 000000000..06698f7b1 --- /dev/null +++ b/library/HTMLPurifier/ConfigSchema/schema/HTML.MathML.txt @@ -0,0 +1,7 @@ +HTML.MathML +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +

+ Enable MathML.

+--# vim: et sw=4 sts=4 diff --git a/library/HTMLPurifier/HTMLModule/MathML.php b/library/HTMLPurifier/HTMLModule/MathML.php new file mode 100644 index 000000000..170b3ba23 --- /dev/null +++ b/library/HTMLPurifier/HTMLModule/MathML.php @@ -0,0 +1,2255 @@ +info_injector[] = new HTMLPurifier_Injector_MathMLSpaceNormalize(); + + /***************************************************************** + * Meta variables + * Used in this file to simplify code and help adapt the DTD + *****************************************************************/ + + // The elements inside are not supposed to be outside, so they + // can't be neither block nor inline: + $default_display = false; + + // This array will contain all the necessary DTD entities used + // throughout the MathML DTD, in order to avoid collisions and allow + // for special characters ('.', '-') in entity names + $E = array(); + + // Prefix used for xlink attrs; is not specified by the MathML DTD + $E['XLINK.prefix'] = 'xlink'; + + $proprietary_att_wrs = array( + 'wrs:valign' => 'CDATA', + 'wrs:columnalign' => 'CDATA', + 'wrs:positionable' => 'CDATA', + 'wrs:linecolor' => 'CDATA', + 'wrs:baseline' => 'CDATA', + 'wrs:reserved' => 'CDATA', + 'wrs:decimalseparators' => 'CDATA' + // TODO: Add xmlns:wrs + ); + + $proprietary_att_dsi = array( + 'xmlns:dsi' => 'Bool#http://www.dessci.com/mathml', + 'dsi:background' => 'CDATA', + 'dsi:color' => 'CDATA' + ); + + /***************************************************************** + * DTD code + * Code from the DTD ported and adapted + *****************************************************************/ + + $E['MalignExpression'] = 'maligngroup|malignmark'; + $E['TokenExpression'] = 'mi|mn|mo|mtext|mspace|ms'; + $E['PresentationExpression'] = + $E['TokenExpression'] . + '|' . $E['MalignExpression'] . + '|mrow|mfrac|msqrt|mroot|mstyle|merror|mpadded|mphantom|mfenced' . + '|menclose|msub|msup|msubsup|munder|mover|munderover' . + '|mmultiscripts|mtable|mstack|mlongdiv|maction'; + + $E['DefEncAtt'] = array( + 'encoding' => 'CDATA', + 'definitionurl' => 'URI' + ); + + $E['CommonAtt'] = array_merge( + array( + 'xmlns' => 'Bool#http://www.w3.org/1998/Math/MathML', + $E['XLINK.prefix'] . ':href' => 'URI', + $E['XLINK.prefix'] . ':type' => 'CDATA', + 'xml:lang' => 'CDATA', + 'xml:space' => 'Enum#default,preserve', + 'id' => 'MathML_ID', // MathML allows multiple elements with same ID + 'xref' => 'MathML_ID', + 'class' => 'Class', + 'style' => 'CSS', + 'href' => 'URI', + 'other' => 'CDATA', + ), + $proprietary_att_wrs, + $proprietary_att_dsi + ); + + // These two sets of attrs appear commonly together. + // For conciseness and efficiency we merge them here once: + $CDEAtt = array_merge( + $E['CommonAtt'], + $E['DefEncAtt'] + ); + + $this->addElement( + 'cn', + $default_display, + 'Custom: (#PCDATA|mglyph|sep|' . $E['PresentationExpression'] . ')*', + array(), + array_merge( + $CDEAtt, + array( + 'type' => 'CDATA', + 'base' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'ci', + $default_display, + 'Custom: (#PCDATA|mglyph|' . $E['PresentationExpression'] . ')*', + array(), + array_merge( + $CDEAtt, + array( + 'type' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'csymbol', + $default_display, + 'Custom: (#PCDATA|mglyph|' . $E['PresentationExpression'] . ')*', + array(), + array_merge( + $CDEAtt, + array( + 'type' => 'CDATA', + 'cd' => 'CDATA' + ) + ) + ); + + $E['SymbolName'] = '#PCDATA'; + $E['BvarQ'] = '(bvar)*'; + $E['DomainQ'] = '(domainofapplication|condition|(lowlimit,uplimit?))*'; + $E['constant-arith.mmlclass'] = 'exponentiale|imaginaryi|notanumber' . + '|true|false|pi|eulergamma|infinity'; + $E['constant-set.mmlclass'] = 'integers|reals|rationals' . + '|naturalnumbers|complexes|primes|emptyset'; + $E['binary-linalg.mmlclass'] = 'vectorproduct|scalarproduct' . + '|outerproduct'; + $E['nary-linalg.mmlclass'] = 'selector'; + $E['unary-linalg.mmlclass'] = 'determinant|transpose'; + $E['nary-constructor.mmlclass'] = 'vector|matrix|matrixrow'; + $E['nary-stats.mmlclass'] = 'mean|sdev|variance|median|mode'; + $E['unary-elementary.mmlclass'] = 'sin|cos|tan|sec|csc|cot|sinh|cosh|tanh|sech' . + '|csch|coth|arcsin|arccos|arctan|arccosh|arccot|arccoth|arccsc' . + '|arccsch|arcsec|arcsech|arcsinh|arctanh'; + $E['limit.mmlclass'] = 'limit'; + $E['product.mmlclass'] = 'product'; + $E['sum.mmlclass'] = 'sum'; + $E['unary-set.mmlclass'] = 'card'; + $E['nary-set-reln.mmlclass'] = 'subset|prsubset'; + $E['binary-set.mmlclass'] = 'in|notin|notsubset|notprsubset|setdiff'; + $E['nary-set.mmlclass'] = 'union|intersect|cartesianproduct'; + $E['nary-setlist-constructor.mmlclass'] = 'set|list'; + $E['unary-veccalc.mmlclass'] = 'divergence|grad|curl|laplacian'; + $E['partialdiff.mmlclass'] = 'partialdiff'; + $E['Differential-Operator.mmlclass'] = 'diff'; + $E['int.mmlclass'] = 'int'; + $E['binary-reln.mmlclass'] = 'neq|approx|factorof|tendsto'; + $E['nary-reln.mmlclass'] = 'eq|gt|lt|geq|leq'; + $E['quantifier.mmlclass'] = 'forall|exists'; + $E['binary-logical.mmlclass'] = 'implies|equivalent'; + $E['unary-logical.mmlclass'] = 'not'; + $E['nary-logical.mmlclass'] = 'and|or|xor'; + $E['nary-arith.mmlclass'] = 'plus|times|gcd|lcm'; + $E['nary-minmax.mmlclass'] = 'max|min'; + $E['unary-arith.mmlclass'] = 'factorial|abs|conjugate|arg|real' . + '|imaginary|floor|ceiling|exp'; + $E['binary-arith.mmlclass'] = 'quotient|divide|minus|power|rem|root'; + $E['nary-functional.mmlclass'] = 'compose'; + $E['lambda.mmlclass'] = 'lambda'; + $E['unary-functional.mmlclass'] = 'inverse|ident|domain|codomain' . + '|image|ln|log|moment'; + $E['interval.mmlclass'] = 'interval'; + $E['DeprecatedContExp'] = 'reln|fn|declare'; + $E['Qualifier'] = '(' . $E['DomainQ'] . ')|degree|momentabout|logbase'; + $E['ContExp'] = 'piecewise|' . + $E['DeprecatedContExp'] . + '|' . $E['interval.mmlclass'] . + '|' . $E['unary-functional.mmlclass'] . + '|' . $E['lambda.mmlclass'] . + '|' . $E['nary-functional.mmlclass'] . + '|' . $E['binary-arith.mmlclass'] . + '|' . $E['unary-arith.mmlclass'] . + '|' . $E['nary-minmax.mmlclass'] . + '|' . $E['nary-arith.mmlclass'] . + '|' . $E['nary-logical.mmlclass'] . + '|' . $E['unary-logical.mmlclass'] . + '|' . $E['binary-logical.mmlclass'] . + '|' . $E['quantifier.mmlclass'] . + '|' . $E['nary-reln.mmlclass'] . + '|' . $E['binary-reln.mmlclass'] . + '|' . $E['int.mmlclass'] . + '|' . $E['Differential-Operator.mmlclass'] . + '|' . $E['partialdiff.mmlclass'] . + '|' . $E['unary-veccalc.mmlclass'] . + '|' . $E['nary-setlist-constructor.mmlclass'] . + '|' . $E['nary-set.mmlclass'] . + '|' . $E['binary-set.mmlclass'] . + '|' . $E['nary-set-reln.mmlclass'] . + '|' . $E['unary-set.mmlclass'] . + '|' . $E['sum.mmlclass'] . + '|' . $E['product.mmlclass'] . + '|' . $E['limit.mmlclass'] . + '|' . $E['unary-elementary.mmlclass'] . + '|' . $E['nary-stats.mmlclass'] . + '|' . $E['nary-constructor.mmlclass'] . + '|' . $E['unary-linalg.mmlclass'] . + '|' . $E['nary-linalg.mmlclass'] . + '|' . $E['binary-linalg.mmlclass'] . + '|' . $E['constant-set.mmlclass'] . + '|' . $E['constant-arith.mmlclass'] . + '|semantics|cn|ci|csymbol|apply|bind|share|cerror|cbytes|cs'; + + $E['apply.content'] = '(' . $E['ContExp'] . '),(' . $E['BvarQ'] . + '),(' . $E['Qualifier'] . ')*,(' . $E['ContExp'] . ')*'; + + $this->addElement( + 'apply', + $default_display, + 'Custom: ' . $E['apply.content'], + array(), + $E['CommonAtt'] + ); + + $this->addElement( + 'bind', + $default_display, + 'Custom: ' . $E['apply.content'], + array(), + $E['CommonAtt'] + ); + + $this->addElement( + 'share', + $default_display, + 'Empty', + array(), + array_merge( + $E['CommonAtt'], + array('src' => 'CDATA') + ) + ); + + $this->addElement( + 'cerror', + $default_display, + 'Custom: (csymbol,(' . $E['ContExp'] . ')*)', + array(), + $E['CommonAtt'] + ); + + $this->addElement( + 'cbytes', + $default_display, + // The * is not in the DTD but we add it to allow empty tag + 'Custom: (#PCDATA)*', + array(), + $CDEAtt + ); + + $this->addElement( + 'cs', + $default_display, + // The * is not in the DTD but we add it to allow empty tag + 'Custom: (#PCDATA)*', + array(), + $CDEAtt + ); + + $this->addElement( + 'bvar', + $default_display, + 'Custom: ((degree,(ci|semantics))|((ci|semantics),(degree)?))', + array(), + $E['CommonAtt'] + ); + + $this->addElement( + 'sep', + $default_display, + 'Empty', + array(), + array() + ); + + $this->addElement( + 'domainofapplication', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'condition', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'uplimit', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'lowlimit', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'degree', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'momentabout', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'logbase', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'piecewise', + $default_display, + 'Custom: (piece|otherwise)*', + array(), + $CDEAtt + ); + + $this->addElement( + 'piece', + $default_display, + 'Custom: ((' . $E['ContExp'] . '),(' . $E['ContExp'] . '))', + array(), + $CDEAtt + ); + + $this->addElement( + 'otherwise', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + $CDEAtt + ); + + $this->addElement( + 'reln', + $default_display, + 'Custom: (' . $E['ContExp'] . ')*', + array(), + array() + ); + + $this->addElement( + 'fn', + $default_display, + 'Custom: (' . $E['ContExp'] . ')', + array(), + array() + ); + + $this->addElement( + 'declare', + $default_display, + 'Custom: (' . $E['ContExp'] . ')+', + array(), + array_merge( + array( + 'type' => 'CDATA', + 'scope' => 'CDATA', + 'nargs' => 'CDATA', + 'occurrence' => 'Enum#prefix,infix,function-model' + ), + $E['DefEncAtt'] + ) + ); + + $this->addElement( + 'interval', + $default_display, + 'Custom: ((' . $E['ContExp'] . '),(' . $E['ContExp'] . '))', + array(), + array_merge( + $CDEAtt, + array('closure' => 'CDATA') + ) + ); + + $this->addElement( + 'inverse', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'ident', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'domain', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'codomain', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'image', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'ln', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'log', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'moment', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'lambda', + $default_display, + 'Custom: ((' . $E['BvarQ'] . '),(' . $E['DomainQ'] . '),(' . + $E['ContExp'] . '))', + array(), + $CDEAtt + ); + + $this->addElement( + 'compose', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'quotient', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'divide', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'minus', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'power', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'rem', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'root', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'factorial', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'abs', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'conjugate', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arg', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'real', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'imaginary', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'floor', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'ceiling', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'exp', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'max', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'min', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'plus', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'times', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'gcd', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'lcm', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'and', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'or', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'xor', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'not', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'implies', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'equivalent', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'forall', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'exists', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'eq', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'gt', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'lt', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'geq', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'leq', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'neq', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'approx', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'factorof', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'tendsto', + $default_display, + 'Empty', + array(), + array_merge( + $CDEAtt, + array('type' => 'CDATA') + ) + ); + + $this->addElement( + 'int', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'diff', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'partialdiff', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'divergence', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'grad', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'curl', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'laplacian', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'set', + $default_display, + 'Custom: ((' . $E['BvarQ'] . ')*,(' . $E['DomainQ'] . ')*,(' . + $E['ContExp'] . ')*)', + array(), + array_merge( + $CDEAtt, + array('type' => 'CDATA') + ) + ); + + $this->addElement( + 'list', + $default_display, + 'Custom: ((' . $E['BvarQ'] . ')*,(' . $E['DomainQ'] . ')*,(' . + $E['ContExp'] . ')*)', + array(), + array_merge( + $CDEAtt, + array('order' => 'Enum#numeric,lexicographic') + ) + ); + + $this->addElement( + 'union', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'intersect', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'cartesianproduct', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'in', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'notin', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'notsubset', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'notprsubset', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'setdiff', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'subset', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'prsubset', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'card', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'sum', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'product', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'limit', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'sin', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'cos', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'tan', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'sec', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'csc', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'cot', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'sinh', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'cosh', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'tanh', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'sech', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'csch', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'coth', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arcsin', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arccos', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arctan', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arccosh', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arccot', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arccoth', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arccsc', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arccsch', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arcsec', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arcsech', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arcsinh', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'arctanh', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'mean', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'sdev', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'variance', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'median', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'mode', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'vector', + $default_display, + 'Custom: ((' . $E['BvarQ'] . '),(' . $E['DomainQ'] . '),(' . + $E['ContExp'] . ')*)', + array(), + $CDEAtt + ); + + $this->addElement( + 'matrix', + $default_display, + 'Custom: ((' . $E['BvarQ'] . '),(' . $E['DomainQ'] . '),(' . + $E['ContExp'] . ')*)', + array(), + $CDEAtt + ); + + $this->addElement( + 'matrixrow', + $default_display, + 'Custom: ((' . $E['BvarQ'] . '),(' . $E['DomainQ'] . '),(' . + $E['ContExp'] . ')*)', + array(), + $CDEAtt + ); + + $this->addElement( + 'determinant', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'transpose', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'selector', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'vectorproduct', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'scalarproduct', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'outerproduct', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'integers', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'reals', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'rationals', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'naturalnumbers', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'complexes', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'primes', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'emptyset', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'exponentiale', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'imaginaryi', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'notanumber', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'true', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'false', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'pi', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'eulergamma', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $this->addElement( + 'infinity', + $default_display, + 'Empty', + array(), + $CDEAtt + ); + + $E['MathExpression'] = $E['ContExp'] . + '|' . $E['PresentationExpression']; + $E['ImpliedMrow'] = '(' . $E['MathExpression'] . ')*'; + $E['TableRowExpression'] = 'mtr|mlabeledtr'; + $E['TableCellExpression'] = 'mtd'; + $E['MstackExpression'] = $E['MathExpression'] . + '|mscarries|msline|msrow|msgroup'; + $E['MsrowExpression'] = $E['MathExpression'] . '|none'; + $E['MultiscriptExpression'] = '(' . + $E['MathExpression'] . '|none),(' . + $E['MathExpression'] . '|none)'; + + $E['mpadded-length'] = 'CDATA'; + $E['linestyle'] = 'Enum#none,solid,dashed'; + $E['columnalignstyle'] = 'Enum#left,center,right'; + $E['unsigned-integer'] = 'MathML_UnsignedInteger'; + $E['integer'] = 'MathML_Integer'; + $E['number'] = 'MathML_Number'; + $E['character'] = 'MathML_Character'; + $E['color'] = 'MathML_Color'; + $E['positive-integer'] = 'MathML_PositiveInteger'; + + $E['token.content'] = '#PCDATA|mglyph|malignmark'; + + $E['length'] = 'MathML_Length'; + $E['DeprecatedTokenAtt'] = array( + 'fontfamily' => 'CDATA', + 'fontweight' => 'Enum#normal,bold', + 'fontstyle' => 'Enum#normal,italic', + 'fontsize' => $E['length'], + 'color' => $E['color'], + 'background' => 'CDATA' + ); + $E['TokenAtt'] = array_merge( + array( + 'mathvariant' => 'Enum#normal,bold,italic,bold-italic' . + ',double-struck,bold-fraktur,script,bold-script,fraktur' . + ',sans-serif,bold-sans-serif,sans-serif-italic' . + ',sans-serif-bold-italic,monospace,initial,tailed,looped' . + ',stretched', + 'mathsize' => 'CDATA', + 'dir' => 'Enum#ltr,rtl' + ), + $E['DeprecatedTokenAtt'] + ); + $E['CommonPresAtt'] = array( + 'mathcolor' => $E['color'], + 'mathbackground' => 'CDATA' + ); + + // These sets of attrs appear commonly together. + // For conciseness and efficiency we merge them here once: + $CCPAtt = array_merge( + $E['CommonAtt'], + $E['CommonPresAtt'] + ); + $CCPTAtt = array_merge( + $CCPAtt, + $E['TokenAtt'] + ); + + $this->addElement( + 'mi', + $default_display, + 'Custom: (' . $E['token.content'] . ')*', + array(), + $CCPTAtt + ); + + $this->addElement( + 'mn', + $default_display, + 'Custom: (' . $E['token.content'] . ')*', + array(), + $CCPTAtt + ); + + $this->addElement( + 'mo', + $default_display, + 'Custom: (' . $E['token.content'] . ')*', + array(), + array_merge( + $CCPTAtt, + array( + 'form' => 'Enum#prefix,infix,postfix', + 'fence' => 'Enum#true,false', + 'separator' => 'Enum#true,false', + 'lspace' => $E['length'], + 'rspace' => $E['length'], + 'stretchy' => 'Enum#true,false', + 'symmetric' => 'Enum#true,false', + 'maxsize' => 'CDATA', + 'minsize' => $E['length'], + 'largeop' => 'Enum#true,false', + 'movablelimits' => 'Enum#true,false', + 'accent' => 'Enum#true,false', + 'linebreak' => 'Enum#auto,newline,nobreak,goodbreak' . + ',badbreak', + 'lineleading' => $E['length'], + 'linebreakstyle' => 'Enum#before,after,duplicate' . + ',infixlinebreakstyle', + 'linebreakmultchar' => 'CDATA', + 'indentalign' => 'Enum#left,center,right,auto,id', + 'indentshift' => $E['length'], + 'indenttarget' => 'CDATA', + 'indentalignfirst' => 'Enum#left,center,right,auto,id' . + ',indentalign', + 'indentshiftfirst' => 'CDATA', + 'indentalignlast' => 'Enum#left,center,right,auto,id' . + ',indentalign', + 'indentshiftlast' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'mtext', + $default_display, + 'Custom: (' . $E['token.content'] . ')*', + array(), + $CCPTAtt + ); + + $this->addElement( + 'mspace', + $default_display, + 'Empty', + array(), + array_merge( + $CCPTAtt, + array( + 'width' => $E['length'], + 'height' => $E['length'], + 'depth' => $E['length'], + 'linebreak' => 'Enum#auto,newline,nobreak,goodbreak' . + ',badbreak,indentingnewline', + 'indentalign' => 'Enum#left,center,right,auto,id', + 'indentshift' => $E['length'], + 'indenttarget' => 'CDATA', + 'indentalignfirst' => 'Enum#left,center,right,auto,id' . + ',indentalign', + 'indentshiftfirst' => 'CDATA', + 'indentalignlast' => 'Enum#left,center,right,auto,id' . + ',indentalign', + 'indentshiftlast' => 'CDATA', + ) + ) + ); + + $this->addElement( + 'ms', + $default_display, + 'Custom: (' . $E['token.content'] . ')*', + array(), + array_merge( + $CCPTAtt, + array( + 'lquote' => 'CDATA', + 'rquote' => 'CDATA' + ) + ) + ); + + $E['mglyph.deprecatedattributes'] = array_merge( + array( + 'index' => $E['integer'], + 'mathvariant' => 'Enum#normal,bold,italic,bold-italic' . + ',double-struck,bold-fraktur,script,bold-script,fraktur' . + ',sans-serif,bold-sans-serif,sans-serif-italic' . + ',sans-serif-bold-italic,monospace,initial,tailed,looped' . + ',stretched', + 'mathsize' => 'CDATA' + ), + $E['DeprecatedTokenAtt'] + ); + + $E['mglyph.attributes'] = array_merge( + $CCPAtt, + array( + 'src' => 'CDATA', + 'width' => $E['length'], + 'height' => $E['length'], + 'valign' => $E['length'], + 'alt' => 'CDATA' + ) + ); + + $this->addElement( + 'mglyph', + $default_display, + 'Empty', + array(), + array_merge( + $E['mglyph.attributes'], + $E['mglyph.deprecatedattributes'] + ) + ); + + $this->addElement( + 'msline', + $default_display, + 'Empty', + array(), + array_merge( + $CCPAtt, + array( + 'position' => $E['integer'], + 'length' => $E['unsigned-integer'], + 'leftoverhang' => $E['length'], + 'rightoverhang' => $E['length'], + 'mslinethickness' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'none', + $default_display, + 'Empty', + array(), + $CCPAtt + ); + + $this->addElement( + 'mprescripts', + $default_display, + 'Empty', + array(), + $CCPAtt + ); + + $this->addElement( + 'malignmark', + $default_display, + 'Empty', + array(), + array_merge( + $CCPAtt, + array('edge' => 'Enum#left,right') + ) + ); + + $this->addElement( + 'maligngroup', + $default_display, + 'Empty', + array(), + array_merge( + $CCPAtt, + array('groupalign' => 'Enum#left,right,right,decimalpoint') + ) + ); + + $this->addElement( + 'mrow', + $default_display, + 'Custom: (' . $E['MathExpression'] . ')*', + array(), + array_merge( + $CCPAtt, + array('dir' => 'Enum#ltr,rtl') + ) + ); + + $this->addElement( + 'mfrac', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + array_merge( + $CCPAtt, + array( + 'linethickness' => 'CDATA', + 'numalign' => 'Enum#left,center,right', + 'denomalign' => 'Enum#left,center,right', + 'bevelled' => 'Enum#true,false' + ) + ) + ); + + $this->addElement( + 'msqrt', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + $CCPAtt + ); + + $this->addElement( + 'mroot', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + $CCPAtt + ); + + $E['mstyle.deprecatedattributes'] = array_merge( + $E['DeprecatedTokenAtt'], + array( + 'veryverythinmathspace' => $E['length'], + 'verythinmathspace' => $E['length'], + 'thinmathspace' => $E['length'], + 'mediummathspace' => $E['length'], + 'thickmathspace' => $E['length'], + 'verythickmathspace' => $E['length'], + 'veryverythickmathspace' => $E['length'] + ) + ); + + $E['mstyle.generalattributes'] = array( + 'accent' => 'Enum#true,false', + 'accentunder' => 'Enum#true,false', + 'align' => 'Enum#left,right,center', + 'alignmentscope' => 'CDATA', + 'bevelled' => 'Enum#true,false', + 'charalign' => 'Enum#left,center,right', + 'charspacing' => 'CDATA', + 'close' => 'CDATA', + 'columnalign' => 'CDATA', + 'columnlines' => 'CDATA', + 'columnspacing' => 'CDATA', + 'columnspan' => $E['positive-integer'], + 'columnwidth' => 'CDATA', + 'crossout' => 'CDATA', + 'denomalign' => 'Enum#left,center,right', + 'depth' => $E['length'], + 'dir' => 'Enum#ltr,rtl', + 'edge' => 'Enum#left,right', + 'equalcolumns' => 'Enum#true,false', + 'equalrows' => 'Enum#true,false', + 'fence' => 'Enum#true,false', + 'form' => 'Enum#prefix,infix,postfix', + 'frame' => $E['linestyle'], + 'framespacing' => 'CDATA', + 'groupalign' => 'CDATA', + 'height' => $E['length'], + 'indentalign' => 'Enum#left,center,right,auto,id', + 'indentalignfirst' => 'Enum#left,center,right,auto,id,indentalign', + 'indentalignlast' => 'Enum#left,center,right,auto,id,indentalign', + 'indentshift' => $E['length'], + 'indentshiftfirst' => 'CDATA', + 'indentshiftlast' => 'CDATA', + 'indenttarget' => 'CDATA', + 'largeop' => 'Enum#true,false', + 'leftoverhang' => $E['length'], + 'length' => $E['unsigned-integer'], + 'linebreak' => 'Enum#auto,newline,nobreak,goodbreak,badbreak', + 'linebreakmultchar' => 'CDATA', + 'linebreakstyle' => 'Enum#before,after,duplicate' . + ',infixlinebreakstyle', + 'lineleading' => $E['length'], + 'linethickness' => 'CDATA', + 'location' => 'Enum#w,nw,n,ne,e,se,s,sw', + 'longdivstyle' => 'CDATA', + 'lquote' => 'CDATA', + 'lspace' => $E['length'], + 'mathsize' => 'CDATA', + 'mathvariant' => 'Enum#normal,bold,italic,bold-italic' . + ',double-struck,bold-fraktur,script,bold-script,fraktur' . + ',sans-serif,bold-sans-serif,sans-serif-italic' . + ',sans-serif-bold-italic,monospace,initial,tailed,looped' . + ',stretched', + 'maxsize' => 'CDATA', + 'minlabelspacing' => $E['length'], + 'minsize' => $E['length'], + 'movablelimits' => 'Enum#true,false', + 'mslinethickness' => 'CDATA', + 'notation' => 'CDATA', + 'numalign' => 'Enum#left,center,right', + 'open' => 'CDATA', + 'position' => $E['integer'], + 'rightoverhang' => $E['length'], + 'rowalign' => 'CDATA', + 'rowlines' => 'CDATA', + 'rowspacing' => 'CDATA', + 'rowspan' => $E['positive-integer'], + 'rquote' => 'CDATA', + 'rspace' => $E['length'], + 'selection' => $E['positive-integer'], + 'separator' => 'Enum#true,false', + 'separators' => 'CDATA', + 'shift' => $E['integer'], + 'side' => 'Enum#left,right,leftoverlap,rightoverlap', + 'stackalign' => 'Enum#left,center,right,decimalpoint', + 'stretchy' => 'Enum#true,false', + 'subscriptshift' => $E['length'], + 'superscriptshift' => $E['length'], + 'symmetric' => 'Enum#true,false', + 'valign' => $E['length'], + 'width' => $E['length'] + ); + + $E['mstyle.specificattributes'] = array( + 'scriptlevel' => $E['integer'], + 'displaystyle' => 'Enum#true,false', + 'scriptsizemultiplier' => $E['number'], + 'scriptminsize' => $E['length'], + 'infixlinebreakstyle' => 'Enum#before,after,duplicate', + 'decimalpoint' => $E['character'] + ); + + $this->addElement( + 'mstyle', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + array_merge( + $CCPAtt, + $E['mstyle.specificattributes'], + $E['mstyle.generalattributes'], + $E['mstyle.deprecatedattributes'] + ) + ); + + $this->addElement( + 'merror', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + $CCPAtt + ); + + $this->addElement( + 'mpadded', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + array_merge( + $CCPAtt, + array( + 'height' => $E['mpadded-length'], + 'depth' => $E['mpadded-length'], + 'width' => $E['mpadded-length'], + 'lspace' => $E['mpadded-length'], + 'voffset' => $E['mpadded-length'], + ) + ) + ); + + $this->addElement( + 'mphantom', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + $CCPAtt + ); + + $this->addElement( + 'mfenced', + $default_display, + 'Custom: (' . $E['MathExpression'] . ')*', + array(), + array_merge( + $CCPAtt, + array( + 'open' => 'CDATA', + 'close' => 'CDATA', + 'separators' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'menclose', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + array_merge( + $CCPAtt, + array('notation' => 'CDATA' ) + ) + ); + + $this->addElement( + 'msub', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + array_merge( + $CCPAtt, + array('subscriptshift' => $E['length']) + ) + ); + + $this->addElement( + 'msup', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + array_merge( + $CCPAtt, + array('superscriptshift' => $E['length']) + ) + ); + + $E['msubsup.attributes'] = array_merge( + $CCPAtt, + array( + 'subscriptshift' => $E['length'], + 'superscriptshift' => $E['length'] + ) + ); + + $this->addElement( + 'msubsup', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + $E['msubsup.attributes'] + ); + + $this->addElement( + 'munder', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + array_merge( + $CCPAtt, + array( + 'accentunder' => 'Enum#true,false', + 'align' => 'Enum#left,right,center' + ) + ) + ); + + $this->addElement( + 'mover', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + array_merge( + $CCPAtt, + array( + 'accent' => 'Enum#true,false', + 'align' => 'Enum#left,right,center' + ) + ) + ); + + $this->addElement( + 'munderover', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MathExpression'] . '),(' . + $E['MathExpression'] . '))', + array(), + array_merge( + $CCPAtt, + array( + 'accent' => 'Enum#true,false', + 'accentunder' => 'Enum#true,false', + 'align' => 'Enum#left,right,center' + ) + ) + ); + + $this->addElement( + 'mmultiscripts', + $default_display, + 'Custom: ((' . $E['MathExpression'] . '),(' . + $E['MultiscriptExpression'] . ')*,(mprescripts,(' . + $E['MultiscriptExpression'] . ')*)?)', + array(), + $E['msubsup.attributes'] + ); + + $this->addElement( + 'mtable', + $default_display, + 'Custom: (' . $E['TableRowExpression'] . ')*', + array(), + array_merge( + $CCPAtt, + array( + 'align' => 'CDATA', + 'rowalign' => 'CDATA', + 'columnalign' => 'CDATA', + 'groupalign' => 'CDATA', + 'alignmentscope' => 'CDATA', + 'columnwidth' => 'CDATA', + 'width' => 'CDATA', + 'rowspacing' => 'CDATA', + 'columnspacing' => 'CDATA', + 'rowlines' => 'CDATA', + 'columnlines' => 'CDATA', + 'frame' => $E['linestyle'], + 'framespacing' => 'CDATA', + 'equalrows' => 'Enum#true,false', + 'equalcolumns' => 'Enum#true,false', + 'displaystyle' => 'Enum#true,false', + 'side' => 'Enum#left,right,leftoverlap,rightoverlap', + 'minlabelspacing' => $E['length'] + ) + ) + ); + + $E['mtr.attributes'] = array_merge( + $CCPAtt, + array( + 'rowalign' => 'Enum#top,bottom,center,baseline,axis', + 'columnalign' => 'CDATA', + 'groupalign' => 'CDATA' + ) + ); + + $this->addElement( + 'mlabeledtr', + $default_display, + 'Custom: (' . $E['TableCellExpression'] . ')+', + array(), + $E['mtr.attributes'] + ); + + $this->addElement( + 'mtr', + $default_display, + 'Custom: (' . $E['TableCellExpression'] . ')+', + array(), + $E['mtr.attributes'] + ); + + $this->addElement( + 'mtd', + $default_display, + 'Custom: (' . $E['ImpliedMrow'] . ')', + array(), + array_merge( + $CCPAtt, + array( + 'rowspan' => $E['positive-integer'], + 'columnspan' => $E['positive-integer'], + 'rowalign' => 'Enum#top,bottom,center,baseline,axis', + 'columnalign' => $E['columnalignstyle'], + 'groupalign' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'mstack', + $default_display, + 'Custom: (' . $E['MstackExpression'] . ')*', + array(), + array_merge( + $CCPAtt, + array( + 'align' => 'CDATA', + 'stackalign' => 'Enum#left,center,right,decimalpoint', + 'charalign' => 'Enum#left,center,right', + 'charspacing' => 'CDATA' + ) + ) + ); + + $E['msgroup.attributes'] = array_merge( + $CCPAtt, + array( + 'position' => $E['integer'], + 'shift' => $E['integer'] + ) + ); + + $this->addElement( + 'mlongdiv', + $default_display, + 'Custom: ((' . $E['MstackExpression'] . '),(' . + $E['MstackExpression'] . '),(' . $E['MstackExpression'] . ')+)', + array(), + array_merge( + $E['msgroup.attributes'], + array('longdivstyle' => 'CDATA') + ) + ); + + $this->addElement( + 'msgroup', + $default_display, + 'Custom: (' . $E['MstackExpression'] . ')*', + array(), + $E['msgroup.attributes'] + ); + + $this->addElement( + 'msrow', + $default_display, + 'Custom: (' . $E['MsrowExpression'] . ')*', + array(), + array_merge( + $CCPAtt, + array('position' => $E['integer']) + ) + ); + + $this->addElement( + 'mscarries', + $default_display, + 'Custom: (' . $E['MsrowExpression'] . '|mscarry)*', + array(), + array_merge( + $CCPAtt, + array( + 'position' => $E['integer'], + 'location' => 'Enum#w,nw,n,ne,e,se,s,sw', + 'crossout' => 'CDATA', + 'scriptsizemultiplier' => $E['number'] + ) + ) + ); + + $this->addElement( + 'mscarry', + $default_display, + 'Custom: (' . $E['MsrowExpression'] . ')*', + array(), + array_merge( + $CCPAtt, + array( + 'location' => 'Enum#w,nw,n,ne,e,se,s,sw', + 'crossout' => 'CDATA' + ) + ) + ); + + $this->addElement( + 'maction', + $default_display, + 'Custom: (' . $E['MathExpression'] . ')+', + array(), + array_merge( + $CCPAtt, + array( + // Using 'actiontype*' removes maction element altogether + 'actiontype' => 'CDATA', + 'selection' => $E['positive-integer'], + ) + ) + ); + + $E['math.deprecatedattributes'] = array( + 'mode' => 'CDATA', + 'macros' => 'CDATA' + ); + + $this->addElement( + 'math', + // The specification allows math to be either inline or block + // according to the display parameter or infer it from context. + // We set it to Flow so that it can be inside both elements that + // allow inline, and elements that allow block + 'Flow', + 'Custom: (' . $E['MathExpression'] . ')*', + array(), + array_merge( + $E['CommonAtt'], + array( + 'display' => 'Enum#block,inline', + 'maxwidth' => $E['length'], + 'overflow' => 'Enum#linebreak,scroll,elide,truncate,scale', + 'altimg' => 'CDATA', + 'altimg-width' => $E['length'], + 'altimg-height' => $E['length'], + 'altimg-valign' => 'CDATA', + 'alttext' => 'CDATA', + 'cdgroup' => 'CDATA', + ), + $E['math.deprecatedattributes'], + $E['CommonPresAtt'], + $E['mstyle.specificattributes'], + $E['mstyle.generalattributes'] + ) + ); + + $E['annotation.attributes'] = array_merge( + $E['CommonAtt'], + array( + 'cd' => 'CDATA', + 'name' => 'CDATA' + ), + $E['DefEncAtt'], + array('src' => 'CDATA') + ); + + $this->addElement( + 'annotation', + $default_display, + // The * is not in the DTD but we add it to allow empty tag + 'Custom: (#PCDATA)*', + array(), + $E['annotation.attributes'] + ); + + $this->addElement( + 'annotation-xml', + $default_display, + 'Custom: ((' . $E['MathExpression'] . ')*)', + array(), + $E['annotation.attributes'] + ); + + $this->addElement( + 'semantics', + $default_display, + 'Custom: ((' . $E['MathExpression'] . + '),(annotation|annotation-xml)*)', + array(), + array_merge( + $CDEAtt, + array( + 'cd' => 'CDATA', + 'name' => 'CDATA' + ) + ) + ); + + } + +} \ No newline at end of file diff --git a/library/HTMLPurifier/HTMLModuleManager.php b/library/HTMLPurifier/HTMLModuleManager.php index 38c058fe2..52ad58621 100644 --- a/library/HTMLPurifier/HTMLModuleManager.php +++ b/library/HTMLPurifier/HTMLModuleManager.php @@ -279,6 +279,9 @@ public function setup($config) if ($config->get('HTML.TargetNoopener')) { $modules[] = 'TargetNoopener'; } + if ($config->get('HTML.MathML')) { + $modules[] = 'MathML'; + } // merge in custom modules $modules = array_merge($modules, $this->userModules); diff --git a/library/HTMLPurifier/Injector/MathMLSpaceNormalize.php b/library/HTMLPurifier/Injector/MathMLSpaceNormalize.php new file mode 100644 index 000000000..304cb509b --- /dev/null +++ b/library/HTMLPurifier/Injector/MathMLSpaceNormalize.php @@ -0,0 +1,40 @@ + and . + * @type array + */ + protected $tags = array('mi', 'mn', 'mo', 'ms', 'mtext', 'ci', 'cn', 'csymbol', 'annotation'); + + /** + * @param HTMLPurifier_Token $token + */ + public function handleText(&$token) + { + + // No parent tag => return to avoid error on following line + if (count($this->currentNesting) == 0) { + return; + } + + // Get the parent tag + $parent_token = $this->currentNesting[count($this->currentNesting) - 1]; + + // If we're not in a "token element" (specified in $tags above), return + if ($parent_token === null || !in_array($parent_token->name, $this->tags)) { + return; + } + + // Replace as per the MathML specification, section 2.1.7 + $token->data = preg_replace( + '/[ \t\n\r]+/', + ' ', + trim($token->data) // Using trim($token->data, ' \t\n\r') trims t,n,r + ); + } + +} diff --git a/library/HTMLPurifier/Length.php b/library/HTMLPurifier/Length.php index e70da55a9..4b5e2562f 100644 --- a/library/HTMLPurifier/Length.php +++ b/library/HTMLPurifier/Length.php @@ -81,7 +81,8 @@ protected function validate() if (!ctype_lower($this->unit)) { $this->unit = strtolower($this->unit); } - if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) { + if (!isset(static::$allowedUnits[$this->unit]) && + !(isset(static::$allowedUnits['']) && $this->unit === false)) { return false; } // Hack: diff --git a/library/HTMLPurifier/MathMLLength.php b/library/HTMLPurifier/MathMLLength.php new file mode 100644 index 000000000..ecdef7fc4 --- /dev/null +++ b/library/HTMLPurifier/MathMLLength.php @@ -0,0 +1,136 @@ + true, + 'verythinmathspace' => true, + 'thinmathspace' => true, + 'mediummathspace' => true, + 'thickmathspace' => true, + 'verythickmathspace' => true, + 'veryverythickmathspace' => true, + 'negativeveryverythinmathspace' => true, + 'negativeverythinmathspace' => true, + 'negativethinmathspace' => true, + 'negativemediummathspace' => true, + 'negativethickmathspace' => true, + 'negativeverythickmathspace' => true, + 'negativeveryverythickmathspace' => true + ); + + /** + * Array Lookup array of units recognized by MathML. + * @note This is a restriction of HTMLPurifier_Length's allowed units. + * @type array + */ + protected static $allowedUnits = array( + 'em' => true, 'ex' => true, 'px' => true, 'in' => true, + 'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true, + '%' => true, '' => true + ); + + /** + * @param string $n Magnitude + * @param bool|string $u Unit + */ + public function __construct($n = '0', $u = false, $namedspace = '') + { + if ($namedspace) { + $this->namedspace = strtolower($namedspace); + } else { + $this->n = (string) $n; + $this->unit = $u !== false ? (string) $u : false; + } + } + + /** + * @param string $s Unit string, like '2em' or '3.4in', or namedspace + * @return HTMLPurifier_MathMLLength + * @warning Does not perform validation. + */ + public static function make($s) + { + if ($s instanceof HTMLPurifier_MathMLLength) { + return $s; + } + if (isset(HTMLPurifier_MathMLLength::$allowedNamedspaces[trim($s)])) { + return new HTMLPurifier_MathMLLength('0', false, $s); + } + $length = HTMLPurifier_Length::make($s); + return new HTMLPurifier_MathMLLength($length->n, $length->unit); + } + + /** + * Validates the number and unit or namedspace. + * @return bool + */ + protected function validate() + { + if (isset(HTMLPurifier_MathMLLength::$allowedNamedspaces[$this->namedspace])) { + return true; + } + return parent::validate(); + } + + /** + * Returns string representation of number. + * @return string + */ + public function toString() + { + if (!$this->isValid()) { + return false; + } + if ($this->namedspace) { + return $this->namedspace; + } + return parent::toString(); + } + + /** + * Retrieves the namedspace. + * @return string + */ + public function getNamedspace() + { + return $this->namedspace; + } + + /** + * Compares two lengths, and returns 1 if greater, -1 if less, 0 if equal + * and null if not comparable. + * @param HTMLPurifier_Length $l + * @return int + * @warning If both values are too large or small, this calculation will + * not work properly + */ + public function compareTo($l) + { + if ($l === false) { + return false; + } + if ($this->namedspace || $l->namedspace) { + if ($this->namedspace === $l->namedspace) { + return 0; + } else { + return null; + } + } + return parent::compareTo($l); + } +} \ No newline at end of file diff --git a/tests/HTMLPurifier/HTMLModule/MathMLBasicTest.php b/tests/HTMLPurifier/HTMLModule/MathMLBasicTest.php new file mode 100644 index 000000000..887ddef81 --- /dev/null +++ b/tests/HTMLPurifier/HTMLModule/MathMLBasicTest.php @@ -0,0 +1,90 @@ + ErrorHandling folder + */ +class HTMLPurifier_HTMLModule_MathMLBasicTest extends HTMLPurifier_HTMLModuleHarness +{ + + public function setup() { + + parent::setup(); + $this->config->set('HTML.MathML', true); + + // We load each snippet and its purified version each into a + // separate XML document. This normalizes some self-closing + // tags which can be either or or into a + // common format to compare the strings properly. + $this->pre = new DOMDocument(); + $this->post = new DOMDocument(); + + } + + // Correctly formed MathML trees + public function testGood() + { + + foreach (glob('MathML/basic/good/*.mml') as $filename) { + + $snippet = file_get_contents($filename); + + $this->pre->loadXML($snippet); + $this->pre->normalizeDocument(); + + $this->post->loadXML($this->purifier->purify($snippet, $this->config)); + $this->post->normalizeDocument(); + + $this->assertIdentical($this->pre->saveXML(), $this->post->saveXML()); + + } + + } + + // Incorrectly formed MathML trees + public function testBad() { + + foreach (glob('MathML/basic/bad/*.mml') as $filename) { + + $snippet = file_get_contents($filename); + + $this->pre->loadXML($snippet); + $this->pre->normalizeDocument(); + + $this->post->loadXML($this->purifier->purify($snippet, $this->config)); + $this->post->normalizeDocument(); + + $this->assertFalse($this->pre->saveXML() == $this->post->saveXML()); + + } + + } + + // Incorrectly formed MathML trees that yield an error + public function testError() { + + $snippet = '52'; + + $this->expectError(); + + $this->pre->loadXML($snippet); + $this->pre->normalizeDocument(); + + $this->post->loadXML($this->purifier->purify($snippet, $this->config)); + $this->post->normalizeDocument(); + + $this->assertFalse($this->pre->saveXML() == $this->post->saveXML()); + + } + + + +} + +// vim: et sw=4 sts=4 diff --git a/tests/MathML/basic/bad/badAttribs2.mml b/tests/MathML/basic/bad/badAttribs2.mml new file mode 100644 index 000000000..56a2e8bc4 --- /dev/null +++ b/tests/MathML/basic/bad/badAttribs2.mml @@ -0,0 +1 @@ +25+x \ No newline at end of file diff --git a/tests/MathML/basic/bad/badBvar1.mml b/tests/MathML/basic/bad/badBvar1.mml new file mode 100644 index 000000000..ede1a81e8 --- /dev/null +++ b/tests/MathML/basic/bad/badBvar1.mml @@ -0,0 +1 @@ +correct:xcorrect w/ degreex2missing <ci>:missing <ci> w/ degree:22 <ci>sxy2 w/ degreexy2<mi/>usedx<mi/>used w/ degreex2missing <ci>, 2 degrees42 \ No newline at end of file diff --git a/tests/MathML/basic/bad/badCondContent1.mml b/tests/MathML/basic/bad/badCondContent1.mml new file mode 100644 index 000000000..28a52c016 --- /dev/null +++ b/tests/MathML/basic/bad/badCondContent1.mml @@ -0,0 +1 @@ +2222x2252xy2xy2252252252252525 \ No newline at end of file diff --git a/tests/MathML/basic/bad/badMoment1.mml b/tests/MathML/basic/bad/badMoment1.mml new file mode 100644 index 000000000..f41c9ec6d --- /dev/null +++ b/tests/MathML/basic/bad/badMoment1.mml @@ -0,0 +1 @@ +304X3x0X \ No newline at end of file diff --git a/tests/MathML/basic/bad/badPiecewise1.mml b/tests/MathML/basic/bad/badPiecewise1.mml new file mode 100644 index 000000000..6d9bc0b2e --- /dev/null +++ b/tests/MathML/basic/bad/badPiecewise1.mml @@ -0,0 +1 @@ +0x5xyx \ No newline at end of file diff --git a/tests/MathML/basic/bad/badTag1.mml b/tests/MathML/basic/bad/badTag1.mml new file mode 100644 index 000000000..e971ae34f --- /dev/null +++ b/tests/MathML/basic/bad/badTag1.mml @@ -0,0 +1 @@ +52+25+5+5+ \ No newline at end of file diff --git a/tests/MathML/basic/bad/badTagPhantom2.mml b/tests/MathML/basic/bad/badTagPhantom2.mml new file mode 100644 index 000000000..d95ed06a1 --- /dev/null +++ b/tests/MathML/basic/bad/badTagPhantom2.mml @@ -0,0 +1 @@ +2+14 \ No newline at end of file diff --git a/tests/MathML/basic/bad/deprecated-mtd1.mml b/tests/MathML/basic/bad/deprecated-mtd1.mml new file mode 100644 index 000000000..e4fda2114 --- /dev/null +++ b/tests/MathML/basic/bad/deprecated-mtd1.mml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/MathML/basic/bad/deprecated-mtd2.mml b/tests/MathML/basic/bad/deprecated-mtd2.mml new file mode 100644 index 000000000..28e63d51e --- /dev/null +++ b/tests/MathML/basic/bad/deprecated-mtd2.mml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/MathML/basic/bad/deprecated-test3.mml b/tests/MathML/basic/bad/deprecated-test3.mml new file mode 100644 index 000000000..a57a84733 --- /dev/null +++ b/tests/MathML/basic/bad/deprecated-test3.mml @@ -0,0 +1 @@ +254+3 \ No newline at end of file diff --git a/tests/MathML/basic/bad/mrootE2.mml b/tests/MathML/basic/bad/mrootE2.mml new file mode 100644 index 000000000..0d1a0983b --- /dev/null +++ b/tests/MathML/basic/bad/mrootE2.mml @@ -0,0 +1 @@ +3x23 \ No newline at end of file diff --git a/tests/MathML/basic/bad/mtable1.mml b/tests/MathML/basic/bad/mtable1.mml new file mode 100644 index 000000000..8e2580668 --- /dev/null +++ b/tests/MathML/basic/bad/mtable1.mml @@ -0,0 +1 @@ +1111.23000112300.201123 \ No newline at end of file diff --git a/tests/MathML/basic/bad/noChildContent.mml b/tests/MathML/basic/bad/noChildContent.mml new file mode 100644 index 000000000..ba98a7d76 --- /dev/null +++ b/tests/MathML/basic/bad/noChildContent.mml @@ -0,0 +1 @@ +applyrelnfnintervalconditiondeclarelambdadomainofapppiecewisepieceotherwiselowlimituplimitbvardegreesetlistmomentmomentaboutvectormatrixmatrixrowsemanticsannotation \ No newline at end of file diff --git a/tests/MathML/basic/bad/noChildPresentation.mml b/tests/MathML/basic/bad/noChildPresentation.mml new file mode 100644 index 000000000..cf73f48e9 --- /dev/null +++ b/tests/MathML/basic/bad/noChildPresentation.mml @@ -0,0 +1 @@ +mrowfracsqrtrootstyleerrorpaddedphantomfencedenclosesubsupsubsupunderoverunderovermultiscriptstabletable rowtable cell \ No newline at end of file diff --git a/tests/MathML/basic/bad/tooFewContentContainer.mml b/tests/MathML/basic/bad/tooFewContentContainer.mml new file mode 100644 index 000000000..d4b3b68a9 --- /dev/null +++ b/tests/MathML/basic/bad/tooFewContentContainer.mml @@ -0,0 +1 @@ +reln,ainterval2lambdax,xbvar2setx5listx5 \ No newline at end of file diff --git a/tests/MathML/basic/good/1.mml b/tests/MathML/basic/good/1.mml new file mode 100644 index 000000000..3b0d83439 --- /dev/null +++ b/tests/MathML/basic/good/1.mml @@ -0,0 +1 @@ +x2y2 \ No newline at end of file diff --git a/tests/MathML/basic/good/10.mml b/tests/MathML/basic/good/10.mml new file mode 100644 index 000000000..a26edff97 --- /dev/null +++ b/tests/MathML/basic/good/10.mml @@ -0,0 +1 @@ +∑0≤i≤m0<j<nP(i,j) \ No newline at end of file diff --git a/tests/MathML/basic/good/11.mml b/tests/MathML/basic/good/11.mml new file mode 100644 index 000000000..b7ca8e3c6 --- /dev/null +++ b/tests/MathML/basic/good/11.mml @@ -0,0 +1 @@ +x2y \ No newline at end of file diff --git a/tests/MathML/basic/good/12.mml b/tests/MathML/basic/good/12.mml new file mode 100644 index 000000000..be3c5b6cd --- /dev/null +++ b/tests/MathML/basic/good/12.mml @@ -0,0 +1 @@ +∑i=1p∑j=1q∑k=1raijbjkcki \ No newline at end of file diff --git a/tests/MathML/basic/good/13.mml b/tests/MathML/basic/good/13.mml new file mode 100644 index 000000000..fd9ce75eb --- /dev/null +++ b/tests/MathML/basic/good/13.mml @@ -0,0 +1 @@ +1+1+1+1+1+1+1+x \ No newline at end of file diff --git a/tests/MathML/basic/good/14.mml b/tests/MathML/basic/good/14.mml new file mode 100644 index 000000000..9424560fb --- /dev/null +++ b/tests/MathML/basic/good/14.mml @@ -0,0 +1 @@ +(2x2+2y2)|φ(x+iy)|2=0 \ No newline at end of file diff --git a/tests/MathML/basic/good/15.mml b/tests/MathML/basic/good/15.mml new file mode 100644 index 000000000..d991945a8 --- /dev/null +++ b/tests/MathML/basic/good/15.mml @@ -0,0 +1 @@ +222x \ No newline at end of file diff --git a/tests/MathML/basic/good/16.mml b/tests/MathML/basic/good/16.mml new file mode 100644 index 000000000..7f07919b0 --- /dev/null +++ b/tests/MathML/basic/good/16.mml @@ -0,0 +1 @@ +∫1xdtt \ No newline at end of file diff --git a/tests/MathML/basic/good/17.mml b/tests/MathML/basic/good/17.mml new file mode 100644 index 000000000..4df85ebb0 --- /dev/null +++ b/tests/MathML/basic/good/17.mml @@ -0,0 +1 @@ +Ddxdy \ No newline at end of file diff --git a/tests/MathML/basic/good/18.mml b/tests/MathML/basic/good/18.mml new file mode 100644 index 000000000..39aed2de5 --- /dev/null +++ b/tests/MathML/basic/good/18.mml @@ -0,0 +1 @@ +f(x)={1/3if 0≤x≤1;2/3if 3≤x≤4;0elsewhere. \ No newline at end of file diff --git a/tests/MathML/basic/good/19.mml b/tests/MathML/basic/good/19.mml new file mode 100644 index 000000000..b3a386998 --- /dev/null +++ b/tests/MathML/basic/good/19.mml @@ -0,0 +1 @@ +x+...+x⏞ktimes \ No newline at end of file diff --git a/tests/MathML/basic/good/2.mml b/tests/MathML/basic/good/2.mml new file mode 100644 index 000000000..613027a5f --- /dev/null +++ b/tests/MathML/basic/good/2.mml @@ -0,0 +1 @@ +F32 \ No newline at end of file diff --git a/tests/MathML/basic/good/20.mml b/tests/MathML/basic/good/20.mml new file mode 100644 index 000000000..da4936aa4 --- /dev/null +++ b/tests/MathML/basic/good/20.mml @@ -0,0 +1 @@ +yx2 \ No newline at end of file diff --git a/tests/MathML/basic/good/21.mml b/tests/MathML/basic/good/21.mml new file mode 100644 index 000000000..3b10159a9 --- /dev/null +++ b/tests/MathML/basic/good/21.mml @@ -0,0 +1 @@ +∑p primef(p)=∫t>1f(t)dπ(t) \ No newline at end of file diff --git a/tests/MathML/basic/good/22.mml b/tests/MathML/basic/good/22.mml new file mode 100644 index 000000000..79eaa4374 --- /dev/null +++ b/tests/MathML/basic/good/22.mml @@ -0,0 +1 @@ +{(a,...,a⏞k a\'s,(b,...,b⏞ℓ b\'s⏟k+ℓ elements} \ No newline at end of file diff --git a/tests/MathML/basic/good/23.mml b/tests/MathML/basic/good/23.mml new file mode 100644 index 000000000..3ed810e54 --- /dev/null +++ b/tests/MathML/basic/good/23.mml @@ -0,0 +1 @@ +((abcd)(efgh)0(ijkl)) \ No newline at end of file diff --git a/tests/MathML/basic/good/24.mml b/tests/MathML/basic/good/24.mml new file mode 100644 index 000000000..5a5449512 --- /dev/null +++ b/tests/MathML/basic/good/24.mml @@ -0,0 +1 @@ +det|c0c1c2…cnc1c2c3…cn+1c2c3c4…cn+2⋮⋮⋮⋮cncn+1cn+2…c2n|>0 \ No newline at end of file diff --git a/tests/MathML/basic/good/25.mml b/tests/MathML/basic/good/25.mml new file mode 100644 index 000000000..0e0a55eb8 --- /dev/null +++ b/tests/MathML/basic/good/25.mml @@ -0,0 +1 @@ +yx2 \ No newline at end of file diff --git a/tests/MathML/basic/good/26.mml b/tests/MathML/basic/good/26.mml new file mode 100644 index 000000000..33e4f28b9 --- /dev/null +++ b/tests/MathML/basic/good/26.mml @@ -0,0 +1 @@ +x9231415+π \ No newline at end of file diff --git a/tests/MathML/basic/good/27.mml b/tests/MathML/basic/good/27.mml new file mode 100644 index 000000000..193ec66df --- /dev/null +++ b/tests/MathML/basic/good/27.mml @@ -0,0 +1 @@ +xybazcd \ No newline at end of file diff --git a/tests/MathML/basic/good/28.mml b/tests/MathML/basic/good/28.mml new file mode 100644 index 000000000..9c1529019 --- /dev/null +++ b/tests/MathML/basic/good/28.mml @@ -0,0 +1 @@ +y3‴ \ No newline at end of file diff --git a/tests/MathML/basic/good/29.mml b/tests/MathML/basic/good/29.mml new file mode 100644 index 000000000..117ca8ce6 --- /dev/null +++ b/tests/MathML/basic/good/29.mml @@ -0,0 +1 @@ +limn+2πnn!(ne)n=1 \ No newline at end of file diff --git a/tests/MathML/basic/good/3.mml b/tests/MathML/basic/good/3.mml new file mode 100644 index 000000000..057034bff --- /dev/null +++ b/tests/MathML/basic/good/3.mml @@ -0,0 +1 @@ +x+y2k+1 \ No newline at end of file diff --git a/tests/MathML/basic/good/30.mml b/tests/MathML/basic/good/30.mml new file mode 100644 index 000000000..6d98a4374 --- /dev/null +++ b/tests/MathML/basic/good/30.mml @@ -0,0 +1 @@ +det(A)=σSnϵ(σ)i=1nai,σi \ No newline at end of file diff --git a/tests/MathML/basic/good/4.mml b/tests/MathML/basic/good/4.mml new file mode 100644 index 000000000..16f18ff9a --- /dev/null +++ b/tests/MathML/basic/good/4.mml @@ -0,0 +1 @@ +x+y2k+1 \ No newline at end of file diff --git a/tests/MathML/basic/good/5.mml b/tests/MathML/basic/good/5.mml new file mode 100644 index 000000000..48a2b3a5b --- /dev/null +++ b/tests/MathML/basic/good/5.mml @@ -0,0 +1 @@ +ab/2 \ No newline at end of file diff --git a/tests/MathML/basic/good/6.mml b/tests/MathML/basic/good/6.mml new file mode 100644 index 000000000..91146323c --- /dev/null +++ b/tests/MathML/basic/good/6.mml @@ -0,0 +1 @@ +a0+1a1+1a2+1a3+1a4 \ No newline at end of file diff --git a/tests/MathML/basic/good/7.mml b/tests/MathML/basic/good/7.mml new file mode 100644 index 000000000..4a9ee2513 --- /dev/null +++ b/tests/MathML/basic/good/7.mml @@ -0,0 +1 @@ +a0+1a1+1a2+1a3+1a4 \ No newline at end of file diff --git a/tests/MathML/basic/good/8.mml b/tests/MathML/basic/good/8.mml new file mode 100644 index 000000000..bf98a4fac --- /dev/null +++ b/tests/MathML/basic/good/8.mml @@ -0,0 +1 @@ +(nk/2) \ No newline at end of file diff --git a/tests/MathML/basic/good/9.mml b/tests/MathML/basic/good/9.mml new file mode 100644 index 000000000..737c1800b --- /dev/null +++ b/tests/MathML/basic/good/9.mml @@ -0,0 +1 @@ +(p2)x2yp-2-11-x11-x2 \ No newline at end of file