├── .WolframResources ├── .project ├── CSSTools ├── Documentation │ └── English │ │ ├── Guides │ │ └── CSSTools.nb │ │ ├── Index │ │ ├── _0.cfs │ │ ├── segments.gen │ │ └── segments_3 │ │ ├── ReferencePages │ │ └── Symbols │ │ │ ├── CSSCascade.nb │ │ │ ├── CSSInheritance.nb │ │ │ ├── CSSLinearGradientImage.nb │ │ │ ├── CSSRadialGradientImage.nb │ │ │ ├── CSSSelector.nb │ │ │ ├── CSSSelectorQ.nb │ │ │ ├── CSSSubjectQ.nb │ │ │ ├── CSSSubjects.nb │ │ │ └── ExtractCSSFromXML.nb │ │ ├── SearchIndex │ │ └── 3 │ │ │ ├── _0.cfe │ │ │ ├── _0.cfs │ │ │ ├── _0.si │ │ │ ├── fields.wl │ │ │ ├── indexMetadata.wl │ │ │ ├── segments_2 │ │ │ └── write.lock │ │ ├── SpellIndex │ │ ├── _9.cfs │ │ ├── segments.gen │ │ └── segments_l │ │ └── Tutorials │ │ └── CSSTools.nb ├── Examples │ ├── BareNotebook.nb │ ├── CustomStylesheet.nb │ ├── Example2.xml │ ├── html-background-png-7.png │ ├── index.html │ ├── mystyle1.css │ ├── mystyle2.css │ ├── simple.css │ ├── test.css │ └── test2.css ├── Kernel │ ├── CSSColors4.wl │ ├── CSSCustomProperties1.wl │ ├── CSSImages3.wl │ ├── CSSMediaQueries4.wl │ ├── CSSPagedMedia3.wl │ ├── CSSPropertyInterpreter.wl │ ├── CSSSelectors3.wl │ ├── CSSStyleSheetInterpreter.wl │ ├── CSSTokenizer.wl │ ├── CSSTools.m │ ├── CSSValuesAndUnits3.wl │ └── SVG11.wl └── PacletInfo.m ├── README.md ├── ReadMeFiles ├── CONTRIBUTING.md ├── COPYING.md ├── ForDevelopers.md └── HowToBuild.md ├── Testing ├── ANB.wl ├── CSSTools.nb ├── CalcTests.wl ├── GeneralColors.wl ├── GenerateTests.wl ├── Gradients.wl ├── HSLColors.wl ├── NamedColors.wl ├── RegularExpressions.wl ├── RunTests.wl └── Tokenizer.wl ├── WLDocumentationTemplates └── English │ ├── Guides │ └── CSSTools.nb │ ├── ReferencePages │ └── Symbols │ │ ├── CSSCascade.nb │ │ ├── CSSInheritance.nb │ │ ├── CSSLinearGradientImage.nb │ │ ├── CSSRadialGradientImage.nb │ │ ├── CSSSelector.nb │ │ ├── CSSSelectorQ.nb │ │ ├── CSSSubjectQ.nb │ │ ├── CSSSubjects.nb │ │ └── ExtractCSSFromXML.nb │ └── Tutorials │ └── CSSTools.nb └── docbuild.xml /.WolframResources: -------------------------------------------------------------------------------- 1 | Resources[ 2 | Version[1], 3 | Sources[ 4 | Directory["~"] 5 | ], 6 | ExecutionBuildCommand["< 2 | 3 | CSSTools 4 | 5 | 6 | 7 | 8 | 9 | com.wolfram.eclipse.MEET.MathematicaProjectBuilder 10 | 11 | 12 | 13 | 14 | 15 | com.wolfram.eclipse.MEET.SimpleMathematicaNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /CSSTools/Documentation/English/Guides/CSSTools.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 12.1' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 158, 7] 13 | NotebookDataLength[ 14591, 424] 14 | NotebookOptionsPosition[ 9977, 330] 15 | NotebookOutlinePosition[ 11780, 372] 16 | CellTagsIndexPosition[ 11737, 369] 17 | WindowTitle->CSSTools 18 | WindowFrame->Normal*) 19 | 20 | (* Beginning of Notebook Content *) 21 | Notebook[{ 22 | Cell[BoxData[GridBox[{ 23 | {Cell["C S S TOOLS GUIDE", "PacletNameCell"], Cell[TextData[{ 24 | Cell[BoxData[ 25 | ActionMenuBox[ 26 | FrameBox[ 27 | InterpretationBox[Cell[TextData[{ 28 | "Functions", 29 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 30 | StripOnInput->False] 31 | }]], 32 | TextCell[ 33 | Row[{"Functions", 34 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 35 | StripOnInput->False], {"\<\"CSSCascade\"\>":>Documentation`HelpLookup[ 36 | "paclet:CSSTools/ref/CSSCascade"], "\<\"CSSInheritance\"\>":> 37 | Documentation`HelpLookup[ 38 | "paclet:CSSTools/ref/CSSInheritance"], \ 39 | "\<\"CSSLinearGradientImage\"\>":>Documentation`HelpLookup[ 40 | "paclet:CSSTools/ref/CSSLinearGradientImage"], \ 41 | "\<\"CSSRadialGradientImage\"\>":>Documentation`HelpLookup[ 42 | "paclet:CSSTools/ref/CSSRadialGradientImage"], "\<\"CSSSelector\"\>":> 43 | Documentation`HelpLookup[ 44 | "paclet:CSSTools/ref/CSSSelector"], "\<\"CSSSelectorQ\"\>":> 45 | Documentation`HelpLookup[ 46 | "paclet:CSSTools/ref/CSSSelectorQ"], "\<\"CSSSubjectQ\"\>":> 47 | Documentation`HelpLookup[ 48 | "paclet:CSSTools/ref/CSSSubjectQ"], "\<\"CSSSubjects\"\>":> 49 | Documentation`HelpLookup[ 50 | "paclet:CSSTools/ref/CSSSubjects"], "\<\"ExtractCSSFromXML\"\>":> 51 | Documentation`HelpLookup[ 52 | "paclet:CSSTools/ref/ExtractCSSFromXML"], "\<\"Import\"\>":> 53 | Documentation`HelpLookup["paclet:ref/Import"]}, 54 | Appearance->None, 55 | MenuAppearance->Automatic, 56 | MenuStyle->"GuideFunction"]], 57 | LineSpacing->{1.4, 0}], 58 | "\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\ 59 | \[ThickSpace]", 60 | Cell[BoxData[ 61 | ActionMenuBox[ 62 | FrameBox[ 63 | InterpretationBox[Cell[TextData[{ 64 | "Tutorials", 65 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 66 | StripOnInput->False] 67 | }]], 68 | TextCell[ 69 | Row[{"Tutorials", 70 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 71 | StripOnInput->False], {"\<\"CSSTools\"\>":>Documentation`HelpLookup[ 72 | "paclet:CSSTools/tutorial/CSSTools"]}, 73 | Appearance->None, 74 | MenuAppearance->Automatic, 75 | MenuStyle->"GuideTutorial"]], 76 | LineSpacing->{1.4, 0}], 77 | "\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\ 78 | \[ThickSpace]", 79 | Cell[BoxData[ 80 | ActionMenuBox[ 81 | FrameBox[ 82 | InterpretationBox[Cell[TextData[{ 83 | "URL", 84 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 85 | StripOnInput->False] 86 | }]], 87 | TextCell[ 88 | Row[{"URL", 89 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 90 | StripOnInput->False], {"\<\"CSSTools/guide/CSSTools\"\>":> 91 | None, "\<\"Copy Wolfram Documentation Center URL\"\>":> 92 | Module[{DocumentationSearch`Private`nb$}, 93 | DocumentationSearch`Private`nb$ = NotebookPut[ 94 | Notebook[{ 95 | Cell["CSSTools/guide/CSSTools"]}, Visible -> False]]; 96 | SelectionMove[DocumentationSearch`Private`nb$, All, Notebook]; 97 | FrontEndTokenExecute[DocumentationSearch`Private`nb$, "Copy"]; 98 | NotebookClose[DocumentationSearch`Private`nb$]; Null], 99 | Delimiter, "\<\"Copy web URL\"\>":> 100 | Module[{DocumentationSearch`Private`nb$}, 101 | DocumentationSearch`Private`nb$ = NotebookPut[ 102 | Notebook[{ 103 | Cell[ 104 | BoxData[ 105 | MakeBoxes[ 106 | Hyperlink[ 107 | "http://reference.wolfram.com/language/CSSTools/guide/\ 108 | CSSTools.html"], StandardForm]], "Input", TextClipboardType -> "PlainText"]}, 109 | Visible -> False]]; 110 | SelectionMove[DocumentationSearch`Private`nb$, All, Notebook]; 111 | FrontEndTokenExecute[DocumentationSearch`Private`nb$, "Copy"]; 112 | NotebookClose[DocumentationSearch`Private`nb$]; 113 | Null], "\<\"Go to web URL\"\>":>FrontEndExecute[{ 114 | NotebookLocate[{ 115 | URL[ 116 | StringJoin[ 117 | If[ 118 | TrueQ[DocumentationBuild`Make`Private`wsmlinkQ$6756], 119 | "http://reference.wolfram.com/system-modeler/", 120 | "http://reference.wolfram.com/language/"], 121 | "CSSTools/guide/CSSTools", ".html"]], None}]}]}, 122 | Appearance->None, 123 | MenuAppearance->Automatic, 124 | MenuStyle->"URLMenu"]], 125 | LineSpacing->{1.4, 0}] 126 | }], "AnchorBar"]} 127 | }]], "AnchorBarGrid", 128 | CellID->1], 129 | 130 | Cell[CellGroupData[{ 131 | 132 | Cell["CSSTools", "GuideTitle", 133 | CellID->942062912], 134 | 135 | Cell["\<\ 136 | Cascading Style Sheets (CSS) is a stylesheet language used for describing the \ 137 | presentation of a document written in markup language like HTML and XML. \ 138 | Wolfram Desktop also uses stylesheets though the specifications differ. This \ 139 | package provides tools for importing and processing CSS to be used within \ 140 | Wolfram Desktop's stylesheet system.\ 141 | \>", "GuideAbstract", 142 | CellID->2001916300] 143 | }, Open ]], 144 | 145 | Cell[CellGroupData[{ 146 | 147 | Cell[TextData[{ 148 | Cell[BoxData[ 149 | TemplateBox[{6}, 150 | "Spacer1"]]], 151 | "Reference" 152 | }], "GuideReferenceSection", 153 | WholeCellGroupOpener->True], 154 | 155 | Cell["", "SectionHeaderSpacer"], 156 | 157 | Cell[CellGroupData[{ 158 | 159 | Cell["Importing CSS", "GuideFunctionsSubsection", 160 | CellID->811494718], 161 | 162 | Cell[TextData[{ 163 | Cell[BoxData[ 164 | TemplateBox[{ 165 | Cell[ 166 | TextData["Import"]], "paclet:ref/Import"}, 167 | "RefLink", 168 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 169 | " ", 170 | StyleBox["\[LongDash]", "GuideEmDash"], 171 | " Supports the \"CSS\" file type: Import[", 172 | Cell[BoxData[ 173 | StyleBox["path", "TI"]], "InlineFormula"], 174 | ", \"CSS\"]" 175 | }], "GuideText", 176 | CellID->100541697], 177 | 178 | Cell[TextData[{ 179 | Cell[BoxData[ 180 | TemplateBox[{ 181 | Cell[ 182 | TextData["ExtractCSSFromXML"]], "paclet:CSSTools/ref/ExtractCSSFromXML"}, 183 | 184 | "RefLink", 185 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 186 | " ", 187 | StyleBox["\[LongDash]", "GuideEmDash"], 188 | " imports the CSS declarations within an XMLObject" 189 | }], "GuideText", 190 | CellID->203374175] 191 | }, Open ]], 192 | 193 | Cell["\t", "GuideDelimiterSubsection", 194 | CellID->622275174], 195 | 196 | Cell[CellGroupData[{ 197 | 198 | Cell["Processing CSS", "GuideFunctionsSubsection", 199 | CellID->91319310], 200 | 201 | Cell[TextData[{ 202 | Cell[BoxData[ 203 | TemplateBox[{ 204 | Cell[ 205 | TextData["CSSCascade"]], "paclet:CSSTools/ref/CSSCascade"}, 206 | "RefLink", 207 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 208 | " ", 209 | StyleBox["\[LongDash]", "GuideEmDash"], 210 | " follows the CSS cascade algorithm and converts interpreted CSS styles to \ 211 | Notebook, Cell, or Box options" 212 | }], "GuideText", 213 | CellID->47789317], 214 | 215 | Cell[TextData[{ 216 | Cell[BoxData[ 217 | TemplateBox[{ 218 | Cell[ 219 | TextData["CSSInheritance"]], "paclet:CSSTools/ref/CSSInheritance"}, 220 | "RefLink", 221 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 222 | " ", 223 | StyleBox["\[LongDash]", "GuideEmDash"], 224 | " for CSS generated from an XMLObject" 225 | }], "GuideText", 226 | CellID->348206879] 227 | }, Open ]], 228 | 229 | Cell["\t", "GuideDelimiterSubsection", 230 | CellID->71783130], 231 | 232 | Cell[CellGroupData[{ 233 | 234 | Cell["Searching SymbolicXML", "GuideFunctionsSubsection", 235 | CellID->159396722], 236 | 237 | Cell[TextData[{ 238 | Cell[BoxData[ 239 | TemplateBox[{ 240 | Cell[ 241 | TextData["CSSSelector"]], "paclet:CSSTools/ref/CSSSelector"}, 242 | "RefLink", 243 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 244 | " ", 245 | StyleBox["\[LongDash]", "GuideEmDash"], 246 | " creates a CSS selector object" 247 | }], "GuideText", 248 | CellID->41288703], 249 | 250 | Cell[TextData[{ 251 | Cell[BoxData[ 252 | TemplateBox[{ 253 | Cell[ 254 | TextData["CSSSelectorQ"]], "paclet:CSSTools/ref/CSSSelectorQ"}, 255 | "RefLink", 256 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 257 | " ", 258 | StyleBox["\[LongDash]", "GuideEmDash"], 259 | " returns True if expression is a CSS selector object" 260 | }], "GuideText", 261 | CellID->46073956], 262 | 263 | Cell[TextData[{ 264 | Cell[BoxData[ 265 | TemplateBox[{ 266 | Cell[ 267 | TextData["CSSSubjects"]], "paclet:CSSTools/ref/CSSSubjects"}, 268 | "RefLink", 269 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 270 | " ", 271 | StyleBox["\[LongDash]", "GuideEmDash"], 272 | " applies a CSS selector to an XMLObject or CSS dataset, returning selector \ 273 | subject information" 274 | }], "GuideText", 275 | CellID->2444546], 276 | 277 | Cell[TextData[{ 278 | Cell[BoxData[ 279 | TemplateBox[{ 280 | Cell[ 281 | TextData["CSSSubjectQ"]], "paclet:CSSTools/ref/CSSSubjectQ"}, 282 | "RefLink", 283 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 284 | " ", 285 | StyleBox["\[LongDash]", "GuideEmDash"], 286 | " returns True if expression is a CSSSubject object" 287 | }], "GuideText", 288 | CellID->399786665] 289 | }, Open ]], 290 | 291 | Cell["\t", "GuideDelimiterSubsection", 292 | CellID->294180157], 293 | 294 | Cell[CellGroupData[{ 295 | 296 | Cell["Images Module", "GuideFunctionsSubsection", 297 | CellID->262714310], 298 | 299 | Cell[TextData[{ 300 | Cell[BoxData[ 301 | TemplateBox[{ 302 | Cell[ 303 | TextData["CSSLinearGradientImage"]], 304 | "paclet:CSSTools/ref/CSSLinearGradientImage"}, 305 | "RefLink", 306 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 307 | " ", 308 | StyleBox["\[LongDash]", "GuideEmDash"], 309 | " create a linear gradient following the CSS specification" 310 | }], "GuideText", 311 | CellID->213621991], 312 | 313 | Cell[TextData[{ 314 | Cell[BoxData[ 315 | TemplateBox[{ 316 | Cell[ 317 | TextData["CSSRadialGradientImage"]], 318 | "paclet:CSSTools/ref/CSSRadialGradientImage"}, 319 | "RefLink", 320 | BaseStyle->"InlineFunctionSans"]], "InlineFunctionSans"], 321 | " ", 322 | StyleBox["\[LongDash]", "GuideEmDash"], 323 | " create a radial gradient following the CSS specification" 324 | }], "GuideText", 325 | CellID->10494712] 326 | }, Open ]] 327 | }, Open ]], 328 | 329 | Cell[" ", "FooterCell"] 330 | }, 331 | Saveable->False, 332 | ScreenStyleEnvironment->"Working", 333 | WindowSize->{725, 750}, 334 | WindowMargins->{{0, Automatic}, {Automatic, 0}}, 335 | WindowTitle->"CSSTools", 336 | TaggingRules->{ 337 | "ModificationHighlight" -> False, "ColorType" -> "GuideColor", "LinkTrails" -> 338 | GridBox[{{ 339 | RowBox[{ 340 | ButtonBox[ 341 | "Wolfram Language", ButtonData -> "paclet:guide/WolframRoot", 342 | BaseStyle -> {"Link", "DockedLinkTrail"}]}]}}, ColumnAlignments -> 343 | Left], "ExampleCounter" -> 1, "NeedPlatMsgIn" -> None, "RootCaptions" -> 344 | "", "Metadata" -> { 345 | "built" -> "{2020, 7, 17, 8, 6, 57.8742549}", 346 | "history" -> {"0.0", "", "", ""}, "context" -> "CSSTools`", 347 | "keywords" -> {}, "specialkeywords" -> {}, 348 | "tutorialcollectionlinks" -> {}, "index" -> True, "label" -> 349 | "C S S Tools Guide", "language" -> "en", "paclet" -> "CSSTools", "status" -> 350 | "None", "summary" -> 351 | "Cascading Style Sheets (CSS) is a stylesheet language used for \ 352 | describing the presentation of a document written in markup language like \ 353 | HTML and XML. Wolfram Desktop also uses stylesheets though the specifications \ 354 | differ. This package provides tools for importing and processing CSS to be \ 355 | used within Wolfram Desktop's stylesheet system.", "synonyms" -> {}, 356 | "tabletags" -> DocumentationBuild`Make`Private`tabletaggingrules$6661, 357 | "title" -> "CSSTools", "titlemodifier" -> "", "windowtitle" -> "CSSTools", 358 | "type" -> "Guide", "uri" -> "CSSTools/guide/CSSTools"}}, 359 | FrontEndVersion->"12.1 for Microsoft Windows (64-bit) (June 19, 2020)", 360 | StyleDefinitions->FrontEnd`FileName[{"Wolfram"}, "Reference.nb", 361 | CharacterEncoding -> "UTF-8"] 362 | ] 363 | (* End of Notebook Content *) 364 | 365 | (* Internal cache information *) 366 | (*CellTagsOutline 367 | CellTagsIndex->{} 368 | *) 369 | (*CellTagsIndex 370 | CellTagsIndex->{} 371 | *) 372 | (*NotebookFileOutline 373 | Notebook[{ 374 | Cell[580, 21, 4466, 106, 70, "AnchorBarGrid",ExpressionUUID->"b51ddbc2-e990-449d-8b75-cd6fbbb43e18", 375 | CellID->1], 376 | Cell[CellGroupData[{ 377 | Cell[5071, 131, 50, 1, 70, "GuideTitle",ExpressionUUID->"a2dfbf4b-a400-497d-b964-cad8f8e0772e", 378 | CellID->942062912], 379 | Cell[5124, 134, 400, 7, 70, "GuideAbstract",ExpressionUUID->"b9255c52-39e9-48e0-bedb-b4fa7ec2beba", 380 | CellID->2001916300] 381 | }, Open ]], 382 | Cell[CellGroupData[{ 383 | Cell[5561, 146, 137, 6, 70, "GuideReferenceSection",ExpressionUUID->"3bdf4d58-3051-465d-a2a6-aab5b3d989cc"], 384 | Cell[5701, 154, 31, 0, 70, "SectionHeaderSpacer",ExpressionUUID->"3540bc83-a4e4-4c50-aca5-3a99124f78aa"], 385 | Cell[CellGroupData[{ 386 | Cell[5757, 158, 69, 1, 70, "GuideFunctionsSubsection",ExpressionUUID->"8d817216-d113-4b36-bc3d-a0f25f4d05de", 387 | CellID->811494718], 388 | Cell[5829, 161, 382, 14, 70, "GuideText",ExpressionUUID->"dee08810-36bd-4ef8-b550-71bf497466fd", 389 | CellID->100541697], 390 | Cell[6214, 177, 351, 12, 70, "GuideText",ExpressionUUID->"fa3304e9-15e7-4c88-80b5-5c41585afd56", 391 | CellID->203374175] 392 | }, Open ]], 393 | Cell[6580, 192, 58, 1, 70, "GuideDelimiterSubsection",ExpressionUUID->"92df8e96-2df7-4fb0-b6b7-28dfc06ca57c", 394 | CellID->622275174], 395 | Cell[CellGroupData[{ 396 | Cell[6663, 197, 69, 1, 70, "GuideFunctionsSubsection",ExpressionUUID->"5f8eaa5a-bc2f-4fac-88db-96866e681ff0", 397 | CellID->91319310], 398 | Cell[6735, 200, 389, 12, 70, "GuideText",ExpressionUUID->"22c8ab8e-8da0-47ea-8af6-3ed63aad5b8a", 399 | CellID->47789317], 400 | Cell[7127, 214, 328, 11, 70, "GuideText",ExpressionUUID->"9fff43cf-59ce-41dc-a1cd-c525790c844f", 401 | CellID->348206879] 402 | }, Open ]], 403 | Cell[7470, 228, 57, 1, 70, "GuideDelimiterSubsection",ExpressionUUID->"97bc2ebf-8ed5-4a50-830d-bcb39efb1d4e", 404 | CellID->71783130], 405 | Cell[CellGroupData[{ 406 | Cell[7552, 233, 77, 1, 70, "GuideFunctionsSubsection",ExpressionUUID->"3f2d20fc-7cdc-4adb-8fc5-a03b4a0fdbf4", 407 | CellID->159396722], 408 | Cell[7632, 236, 315, 11, 70, "GuideText",ExpressionUUID->"76b7ff53-5475-4aac-af5f-dfa262a0aec6", 409 | CellID->41288703], 410 | Cell[7950, 249, 339, 11, 70, "GuideText",ExpressionUUID->"a2cd85ab-f27a-4852-9806-a0247ac5cce9", 411 | CellID->46073956], 412 | Cell[8292, 262, 380, 12, 70, "GuideText",ExpressionUUID->"3d3dc613-bae0-45a3-970e-a82dcf688d97", 413 | CellID->2444546], 414 | Cell[8675, 276, 336, 11, 70, "GuideText",ExpressionUUID->"6ef07e31-cc99-4c06-84f5-6ec15c87c6b7", 415 | CellID->399786665] 416 | }, Open ]], 417 | Cell[9026, 290, 58, 1, 70, "GuideDelimiterSubsection",ExpressionUUID->"bd8319f4-05f5-4ea8-af26-0dfcea2bc15f", 418 | CellID->294180157], 419 | Cell[CellGroupData[{ 420 | Cell[9109, 295, 69, 1, 70, "GuideFunctionsSubsection",ExpressionUUID->"4fb25de5-3a55-44c3-ac83-960ebfc02839", 421 | CellID->262714310], 422 | Cell[9181, 298, 370, 12, 70, "GuideText",ExpressionUUID->"06fc4090-62d9-461f-88f5-ac3889552ddc", 423 | CellID->213621991], 424 | Cell[9554, 312, 369, 12, 70, "GuideText",ExpressionUUID->"a717bb5b-d598-4684-a4d2-2325577685ac", 425 | CellID->10494712] 426 | }, Open ]] 427 | }, Open ]], 428 | Cell[9950, 328, 23, 0, 70, "FooterCell",ExpressionUUID->"3bde262e-7110-4fa6-aa52-e51a971134e8"] 429 | } 430 | ] 431 | *) 432 | 433 | (* End of internal cache information *) 434 | -------------------------------------------------------------------------------- /CSSTools/Documentation/English/Index/_0.cfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/Index/_0.cfs -------------------------------------------------------------------------------- /CSSTools/Documentation/English/Index/segments.gen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/Index/segments.gen -------------------------------------------------------------------------------- /CSSTools/Documentation/English/Index/segments_3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/Index/segments_3 -------------------------------------------------------------------------------- /CSSTools/Documentation/English/ReferencePages/Symbols/CSSSelectorQ.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 12.1' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 158, 7] 13 | NotebookDataLength[ 25461, 689] 14 | NotebookOptionsPosition[ 19053, 549] 15 | NotebookOutlinePosition[ 21333, 608] 16 | CellTagsIndexPosition[ 21248, 603] 17 | WindowTitle->CSSSelectorQ 18 | WindowFrame->Normal*) 19 | 20 | (* Beginning of Notebook Content *) 21 | Notebook[{ 22 | Cell[BoxData[GridBox[{ 23 | {Cell["C S S TOOLS SYMBOL", "PacletNameCell",ExpressionUUID-> 24 | "bf99bd35-9c1d-4534-b12e-3e8bb3316118"], Cell[TextData[{ 25 | Cell[BoxData[ 26 | ActionMenuBox[ 27 | FrameBox[ 28 | InterpretationBox[Cell[TextData[{ 29 | "Tutorials", 30 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 31 | StripOnInput->False] 32 | }],ExpressionUUID->"c1b9bc2c-b007-4809-8b30-cd1d1115ad6d"], 33 | TextCell[ 34 | Row[{"Tutorials", 35 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 36 | StripOnInput->False], {"\<\"CSSTools\"\>":>Documentation`HelpLookup[ 37 | "paclet:CSSTools/tutorial/CSSTools"]}, 38 | Appearance->None, 39 | MenuAppearance->Automatic, 40 | MenuStyle->"Tutorials"]], 41 | LineSpacing->{1.4, 0},ExpressionUUID-> 42 | "1f654608-d645-4c08-bee1-79649709b3e6"], 43 | "\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\ 44 | \[ThickSpace]", 45 | Cell[BoxData[ 46 | ActionMenuBox[ 47 | FrameBox[ 48 | InterpretationBox[Cell[TextData[{ 49 | "See Also", 50 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 51 | StripOnInput->False] 52 | }],ExpressionUUID->"54feb012-1747-47a2-a6c9-81764877ff5a"], 53 | TextCell[ 54 | Row[{"See Also", 55 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 56 | StripOnInput->False], {"\<\"CSSSelector\"\>":> 57 | Documentation`HelpLookup[ 58 | "paclet:CSSTools/ref/CSSSelector"], "\<\"CSSSubjects\"\>":> 59 | Documentation`HelpLookup[ 60 | "paclet:CSSTools/ref/CSSSubjects"], "\<\"CSSSubjectQ\"\>":> 61 | Documentation`HelpLookup[ 62 | "paclet:CSSTools/ref/CSSSubjectQ"], "\<\"ExtractCSSFromXML\"\>":> 63 | Documentation`HelpLookup[ 64 | "paclet:CSSTools/ref/ExtractCSSFromXML"], "\<\"CSSCascade\"\>":> 65 | Documentation`HelpLookup[ 66 | "paclet:CSSTools/ref/CSSCascade"], "\<\"CSSInheritance\"\>":> 67 | Documentation`HelpLookup["paclet:CSSTools/ref/CSSInheritance"]}, 68 | Appearance->None, 69 | MenuAppearance->Automatic, 70 | MenuStyle->"SeeAlso"]], 71 | LineSpacing->{1.4, 0},ExpressionUUID-> 72 | "9a5b59c6-2ca2-4b66-9064-eb9725767a30"], 73 | "\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\ 74 | \[ThickSpace]", 75 | Cell[BoxData[ 76 | ActionMenuBox[ 77 | FrameBox[ 78 | InterpretationBox[Cell[TextData[{ 79 | "Related Guides", 80 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 81 | StripOnInput->False] 82 | }],ExpressionUUID->"65e12c4d-91d5-4c48-8278-63cf6fa37622"], 83 | TextCell[ 84 | Row[{"Related Guides", 85 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 86 | StripOnInput->False], {"\<\"CSSTools\"\>":>Documentation`HelpLookup[ 87 | "paclet:CSSTools/guide/CSSTools"]}, 88 | Appearance->None, 89 | MenuAppearance->Automatic, 90 | MenuStyle->"MoreAbout"]], 91 | LineSpacing->{1.4, 0},ExpressionUUID-> 92 | "632f98e0-f551-44a5-bca1-a2e03e59db21"], 93 | "\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\[ThickSpace]\ 94 | \[ThickSpace]", 95 | Cell[BoxData[ 96 | ActionMenuBox[ 97 | FrameBox[ 98 | InterpretationBox[Cell[TextData[{ 99 | "URL", 100 | StyleBox[" \[FilledDownTriangle]", "AnchorBarArrow", 101 | StripOnInput->False] 102 | }],ExpressionUUID->"49d64608-9f7f-4b2c-a8fb-01e121899510"], 103 | TextCell[ 104 | Row[{"URL", 105 | Style[" \[FilledDownTriangle]", "AnchorBarArrow"]}]]], 106 | StripOnInput->False], {"\<\"CSSTools/ref/CSSSelectorQ\"\>":> 107 | None, "\<\"Copy Wolfram Documentation Center URL\"\>":> 108 | Module[{DocumentationSearch`Private`nb$}, 109 | DocumentationSearch`Private`nb$ = NotebookPut[ 110 | Notebook[{ 111 | Cell["CSSTools/ref/CSSSelectorQ"]}, Visible -> False]]; 112 | SelectionMove[DocumentationSearch`Private`nb$, All, Notebook]; 113 | FrontEndTokenExecute[DocumentationSearch`Private`nb$, "Copy"]; 114 | NotebookClose[DocumentationSearch`Private`nb$]; Null], 115 | Delimiter, "\<\"Copy web URL\"\>":> 116 | Module[{DocumentationSearch`Private`nb$}, 117 | DocumentationSearch`Private`nb$ = NotebookPut[ 118 | Notebook[{ 119 | Cell[ 120 | BoxData[ 121 | MakeBoxes[ 122 | Hyperlink[ 123 | "http://reference.wolfram.com/language/CSSTools/ref/\ 124 | CSSSelectorQ.html"], StandardForm]], "Input", TextClipboardType -> 125 | "PlainText"]}, Visible -> False]]; 126 | SelectionMove[DocumentationSearch`Private`nb$, All, Notebook]; 127 | FrontEndTokenExecute[DocumentationSearch`Private`nb$, "Copy"]; 128 | NotebookClose[DocumentationSearch`Private`nb$]; 129 | Null], "\<\"Go to web URL\"\>":>FrontEndExecute[{ 130 | NotebookLocate[{ 131 | URL[ 132 | StringJoin[ 133 | If[ 134 | TrueQ[DocumentationBuild`Make`Private`wsmlinkQ$12188], 135 | "http://reference.wolfram.com/system-modeler/", 136 | "http://reference.wolfram.com/language/"], 137 | "CSSTools/ref/CSSSelectorQ", ".html"]], None}]}]}, 138 | Appearance->None, 139 | MenuAppearance->Automatic, 140 | MenuStyle->"URLMenu"]], 141 | LineSpacing->{1.4, 0},ExpressionUUID-> 142 | "5932dbca-f28b-4cbf-82af-6577ec8d110c"] 143 | }], "AnchorBar",ExpressionUUID->"edfa00ac-1710-4200-bcc0-78cfc9fc4666"]} 144 | }]], "AnchorBarGrid", 145 | CellID->1,ExpressionUUID->"10172e8a-40a9-4748-8c2d-54bef34a6c29"], 146 | 147 | Cell[CellGroupData[{ 148 | 149 | Cell[TextData[{ 150 | Cell["CSSSelectorQ", "ObjectName",ExpressionUUID-> 151 | "b6056298-97a4-4650-b463-7f16cd86c2ec"], 152 | Cell[BoxData[ 153 | TemplateBox[{8}, 154 | "Spacer1"]],ExpressionUUID->"a86d17f0-f689-448c-97f4-80dedba30d16"], 155 | Cell[BoxData[ 156 | ""], "ObjectNameTranslation",ExpressionUUID-> 157 | "0eca9c61-8674-4b87-96ad-e67831f49045"] 158 | }], "ObjectNameGrid",ExpressionUUID->"abcf58a9-31d7-4e97-8e58-722b31e4593c"], 159 | 160 | Cell[BoxData[GridBox[{ 161 | {"", Cell[TextData[{ 162 | Cell[BoxData[ 163 | RowBox[{"CSSSelectorQ", "[", 164 | StyleBox["expr", "TI"], "]"}]], "InlineFormula",ExpressionUUID-> 165 | "4ea828fc-ea52-4a05-8b83-6b3084ac3263"], 166 | " \[LineSeparator]returns ", 167 | Cell[BoxData[ 168 | TemplateBox[{ 169 | Cell[ 170 | TextData["True"]], "paclet:ref/True"}, 171 | "RefLink", 172 | BaseStyle->{"InlineFormula"}]], "InlineFormula",ExpressionUUID-> 173 | "e68719eb-af31-4959-b73f-8bb1b18affd1"], 174 | " if ", 175 | StyleBox["expr", "TI"], 176 | " is a valid ", 177 | Cell[BoxData[ 178 | TemplateBox[{ 179 | Cell[ 180 | TextData["CSSSelector"]], "paclet:CSSTools/ref/CSSSelector"}, 181 | "RefLink", 182 | BaseStyle->{"InlineFormula"}]], "InlineFormula",ExpressionUUID-> 183 | "b3eee294-631e-44a9-ae0b-6cbb5bea1814"], 184 | " object, and ", 185 | Cell[BoxData[ 186 | TemplateBox[{ 187 | Cell[ 188 | TextData["False"]], "paclet:ref/False"}, 189 | "RefLink", 190 | BaseStyle->{"InlineFormula"}]], "InlineFormula",ExpressionUUID-> 191 | "c670c888-c730-4bb1-8cb9-5f3273093b11"], 192 | " otherwise." 193 | }],ExpressionUUID->"6e7cb63d-419b-49f5-b041-842353aff38f"]} 194 | }]], "Usage", 195 | GridBoxOptions->{ 196 | GridBoxBackground->{"Columns" -> {{None}}, "Rows" -> {{None}}}}, 197 | CellID->982511436,ExpressionUUID->"b124090a-fe0e-4eff-bb4e-f73a6a48114a"] 198 | }, Open ]], 199 | 200 | Cell[CellGroupData[{ 201 | 202 | Cell[TextData[Cell[BoxData[ 203 | ButtonBox[Cell[TextData[{ 204 | Cell[BoxData[ 205 | TemplateBox[{6}, 206 | "Spacer1"]],ExpressionUUID->"d975a560-7e10-4037-97e3-69eab7c314fd"], 207 | "Details" 208 | }], "NotesFrameText",ExpressionUUID->"f193e466-ef8c-487f-adeb-cf57a84aaaf5"], 209 | Appearance->{Automatic, None, "Normal", Automatic}, 210 | BaseStyle->None, 211 | ButtonFunction:>(FrontEndExecute[{ 212 | FrontEnd`SelectionMove[ 213 | FrontEnd`SelectedNotebook[], All, ButtonCell], 214 | FrontEndToken["OpenCloseGroup"], 215 | FrontEnd`SelectionMove[ 216 | FrontEnd`SelectedNotebook[], After, CellContents]}]& ), 217 | Evaluator->None, 218 | Method-> 219 | "Preemptive"]],ExpressionUUID->"8136797a-860d-4469-af7a-3bc5eb16e466"]], \ 220 | "NotesSection", 221 | WholeCellGroupOpener->True, 222 | CellGroupingRules->{"SectionGrouping", 50}, 223 | CellID->518557591,ExpressionUUID->"1ce28873-b097-4136-b1e1-be88963046c4"], 224 | 225 | Cell["", "SectionHeaderSpacer",ExpressionUUID->"4640635c-c0b8-4930-b67b-9fef4dd11eaa"], 226 | 227 | Cell["\<\ 228 | A CSS selector object consists of the raw CSS selector string, the parsed \ 229 | sequence of selectors and combinators, and the specificity. All of these \ 230 | properties exist independently of the CSS rule and its declarations.\ 231 | \>", "Notes", 232 | CellID->1067943069,ExpressionUUID->"9915ee57-d8c4-4117-a98b-0118966efd02"], 233 | 234 | Cell["", "SectionFooterSpacer",ExpressionUUID->"c3545927-f4ee-4818-8f65-a71bed43063c"] 235 | }, Closed]], 236 | 237 | Cell[CellGroupData[{ 238 | 239 | Cell[TextData[{ 240 | Cell[BoxData[ 241 | TemplateBox[{6}, 242 | "Spacer1"]],ExpressionUUID->"01a15190-0ebe-4317-834e-9dcdb1efc1af"], 243 | "Examples", 244 | "\[NonBreakingSpace]\[NonBreakingSpace]", 245 | Cell["(2)", "ExampleCount",ExpressionUUID-> 246 | "fd7756da-bb66-427f-9d81-d50e3742fb24"] 247 | }], "PrimaryExamplesSection", 248 | WholeCellGroupOpener->True, 249 | CellTags->"PrimaryExamplesSection", 250 | CellID->218286076,ExpressionUUID->"a7e4e334-12a8-4f55-9c1f-4f09a807a8b0"], 251 | 252 | Cell[CellGroupData[{ 253 | 254 | Cell[TextData[{ 255 | "Basic Examples", 256 | "\[NonBreakingSpace]\[NonBreakingSpace]", 257 | Cell["(1)", "ExampleCount",ExpressionUUID-> 258 | "a7cf10c8-605e-46f4-ab27-7178668e2157"] 259 | }], "ExampleSection", "ExampleSection", 260 | WholeCellGroupOpener->True, 261 | CellID->43318398,ExpressionUUID->"29fd1fc4-6013-4cbc-bf71-4eecf09dfa5d"], 262 | 263 | Cell[BoxData[ 264 | RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", 265 | CellLabel->"In[1]:=", 266 | CellID->158635880,ExpressionUUID->"f2a39e7c-c45c-402b-b86b-70bd09dc7e72"], 267 | 268 | Cell[TextData[{ 269 | Cell[BoxData[ 270 | TemplateBox[{ 271 | Cell[ 272 | TextData["CSSSelectorQ"]], "paclet:CSSTools/ref/CSSSelectorQ"}, 273 | "RefLink", 274 | BaseStyle->{"InlineFormula"}]], "InlineFormula",ExpressionUUID-> 275 | "81462696-bc1b-4fa6-ad7d-f7ddadf9dc27"], 276 | " tests whether an object is a parsed CSS selector object:" 277 | }], "ExampleText", 278 | CellID->32838738,ExpressionUUID->"3f18e63e-72f8-48d8-b70a-47ac4a9896a0"], 279 | 280 | Cell[CellGroupData[{ 281 | 282 | Cell[BoxData[ 283 | RowBox[{"expr", "=", 284 | RowBox[{"CSSSelector", "[", "\"\\"", "]"}]}]], "Input", 285 | CellLabel->"In[2]:=", 286 | CellID->95771059,ExpressionUUID->"2aabe099-db4e-4974-8586-53d96e2183d6"], 287 | 288 | Cell[BoxData[ 289 | InterpretationBox[ 290 | StyleBox[ 291 | FrameBox[ 292 | TemplateBox[{ 293 | StyleBox["\"#CSS \"", 294 | RGBColor[0, 0.5, 1], Selectable -> False, StripOnInput -> False], 295 | StyleBox["\"h1\"", Selectable -> True, StripOnInput -> False]}, 296 | "RowDefault"], 297 | Background->RGBColor[0.92, 0.98, 1], 298 | BaseStyle->{FontFamily -> Dynamic[ 299 | CurrentValue[{StyleHints, "CodeFont"}]], FontWeight -> Bold, 300 | FontColor -> GrayLevel[0.2]}, 301 | FrameMargins->{{5, 5}, {2, 2}}, 302 | FrameStyle->Directive[ 303 | RGBColor[0, 0.5, 1], 304 | AbsoluteThickness[1]], 305 | ImageMargins->2, 306 | RoundingRadius->4, 307 | StripOnInput->False], 308 | Editable->False, 309 | StripOnInput->False, 310 | ShowStringCharacters->False], 311 | CSSTools`CSSSelector[ 312 | Association[ 313 | "String" -> "h1", 314 | "Sequence" -> { 315 | "SimpleSelectorSequence" -> { 316 | "Type" -> Association[ 317 | "Namespace" -> Missing["NotFound"], "Name" -> "h1"]}}, 318 | "Specificity" -> {0, 0, 0, 1}]]]], "Output", 319 | CellLabel->"Out[2]=", 320 | CellID->330514465,ExpressionUUID->"e99d124b-ec76-421a-9f3a-ba2b1e5f7691"] 321 | }, Open ]], 322 | 323 | Cell[CellGroupData[{ 324 | 325 | Cell[BoxData[ 326 | RowBox[{"CSSSelectorQ", "[", "expr", "]"}]], "Input", 327 | CellLabel->"In[3]:=", 328 | CellID->261130256,ExpressionUUID->"a6430b22-325f-4f58-954f-14196a84cfea"], 329 | 330 | Cell[BoxData["True"], "Output", 331 | CellLabel->"Out[3]=", 332 | CellID->787859480,ExpressionUUID->"0fdb16fc-0092-480e-a50c-a01b2619cdfb"] 333 | }, Open ]] 334 | }, Open ]], 335 | 336 | Cell[CellGroupData[{ 337 | 338 | Cell[TextData[{ 339 | "Properties & Relations", 340 | "\[NonBreakingSpace]\[NonBreakingSpace]", 341 | Cell["(1)", "ExampleCount",ExpressionUUID-> 342 | "4a5bbb8f-095c-4879-bbef-f8fa2d69d92e"] 343 | }], "ExampleSection", "ExampleSection", 344 | WholeCellGroupOpener->True, 345 | CellID->2123667759,ExpressionUUID->"335cfff7-797a-4e23-aa5a-de3958a8c581"], 346 | 347 | Cell[BoxData[ 348 | RowBox[{"Needs", "[", "\"\\"", "]"}]], "Input", 349 | CellLabel->"In[1]:=", 350 | CellID->349318125,ExpressionUUID->"b457a537-b1cc-4f25-b089-f00fd1a6c3fc"], 351 | 352 | Cell[TextData[{ 353 | "A parsed CSS selector object has the head ", 354 | Cell[BoxData[ 355 | TemplateBox[{ 356 | Cell[ 357 | TextData["CSSSelector"]], "paclet:CSSTools/ref/CSSSelector"}, 358 | "RefLink", 359 | BaseStyle->{"InlineFormula"}]], "InlineFormula",ExpressionUUID-> 360 | "aa6e70c5-5fa5-4e10-a66d-856e2c36d09d"], 361 | " and contains an association with three keys: ", 362 | Cell[BoxData[ 363 | "\"\\""], "InlineFormula",ExpressionUUID-> 364 | "cadc8bcd-eb71-4296-acfa-ec04d706939c"], 365 | ", ", 366 | Cell[BoxData[ 367 | "\"\\""], "InlineFormula",ExpressionUUID-> 368 | "7f85f453-ecac-470b-9fd4-d22775337135"], 369 | " and ", 370 | Cell[BoxData[ 371 | "\"\\""], "InlineFormula",ExpressionUUID-> 372 | "6fcc1a69-34ca-469e-a4c3-33ed3c38dfd4"], 373 | ". ", 374 | Cell[BoxData[ 375 | TemplateBox[{ 376 | Cell[ 377 | TextData["CSSSelectorQ"]], "paclet:CSSTools/ref/CSSSelectorQ"}, 378 | "RefLink", 379 | BaseStyle->{"InlineFormula"}]], "InlineFormula",ExpressionUUID-> 380 | "0d43f94d-3432-4193-a315-72eb889e8ded"], 381 | " checks for this format:" 382 | }], "ExampleText", 383 | CellID->21517216,ExpressionUUID->"a0b167cd-71a8-4cc6-bc5d-7268f58daf79"], 384 | 385 | Cell[CellGroupData[{ 386 | 387 | Cell[BoxData[ 388 | RowBox[{"InputForm", "[", 389 | RowBox[{"CSSSelector", "[", "\"\<.class type\>\"", "]"}], "]"}]], "Input", 390 | CellLabel->"In[2]:=", 391 | CellID->30143501,ExpressionUUID->"807b9ce6-90c3-4274-91e6-f9219cc50fdf"], 392 | 393 | Cell["\<\ 394 | CSSSelector[<|\"String\" -> \".class type\", 395 | \"Sequence\" -> {\"SimpleSelectorSequence\" -> {\"Class\" -> \ 396 | <|\"Namespace\" -> None, \"Name\" -> \"class\", \"Match\" -> \"Include\", \ 397 | \"Value\" -> \"class\"|>}, 398 | \"Combinator\" -> <|\"Type\" -> \"Descendant\"|>, \ 399 | \"SimpleSelectorSequence\" -> {\"Type\" -> <|\"Namespace\" -> \ 400 | Missing[\"NotFound\"], \"Name\" -> \"type\"|>}}, 401 | \"Specificity\" -> {0, 0, 1, 1}|>]\ 402 | \>", "Output", 403 | CellLabel->"Out[2]//InputForm=", 404 | CellID->119680640,ExpressionUUID->"fbb351f6-e7d1-46e2-b507-5b8c31a477d7"] 405 | }, Open ]], 406 | 407 | Cell[CellGroupData[{ 408 | 409 | Cell[BoxData[ 410 | RowBox[{"CSSSelectorQ", "[", 411 | RowBox[{"CSSSelector", "[", "\"\<.class type\>\"", "]"}], "]"}]], "Input", 412 | CellLabel->"In[3]:=", 413 | CellID->453582021,ExpressionUUID->"b3401fc5-71a1-45bd-a6dc-f18bcade181b"], 414 | 415 | Cell[BoxData["True"], "Output", 416 | CellLabel->"Out[3]=", 417 | CellID->56563325,ExpressionUUID->"25e3075a-7974-4985-964d-ad744dd39e02"] 418 | }, Open ]] 419 | }, Closed]], 420 | 421 | Cell["", "SectionFooterSpacer",ExpressionUUID->"375a5b3c-8c21-4286-a722-cf44f6f11e1d"] 422 | }, Open ]], 423 | 424 | Cell[CellGroupData[{ 425 | 426 | Cell[TextData[{ 427 | Cell[BoxData[ 428 | TemplateBox[{6}, 429 | "Spacer1"]],ExpressionUUID->"0a12c4ae-6fe3-4e7e-ba4b-54ce10a9da71"], 430 | "See Also" 431 | }], "SeeAlsoSection", 432 | WholeCellGroupOpener->True, 433 | CellID->1255426704,ExpressionUUID->"44ce44d9-3292-419b-a6d7-ff81108e20c1"], 434 | 435 | Cell[TextData[{ 436 | Cell[BoxData[ 437 | TemplateBox[{ 438 | Cell[ 439 | TextData["CSSSelector"]], "paclet:CSSTools/ref/CSSSelector"}, 440 | "RefLink", 441 | BaseStyle->{"InlineFormula", FontFamily -> "Verdana"}]], "InlineFormula", 442 | ExpressionUUID->"29028635-a657-4fc6-8575-a239706d8c50"], 443 | "\[NonBreakingSpace]", 444 | StyleBox["\[MediumSpace]\[FilledVerySmallSquare]\[MediumSpace]", 445 | "InlineSeparator"], 446 | " ", 447 | Cell[BoxData[ 448 | TemplateBox[{ 449 | Cell[ 450 | TextData["CSSSubjects"]], "paclet:CSSTools/ref/CSSSubjects"}, 451 | "RefLink", 452 | BaseStyle->{"InlineFormula", FontFamily -> "Verdana"}]], "InlineFormula", 453 | ExpressionUUID->"34296b93-6f22-4d42-ac9d-b5ad728c9b0e"], 454 | "\[NonBreakingSpace]", 455 | StyleBox["\[MediumSpace]\[FilledVerySmallSquare]\[MediumSpace]", 456 | "InlineSeparator"], 457 | " ", 458 | Cell[BoxData[ 459 | TemplateBox[{ 460 | Cell[ 461 | TextData["CSSSubjectQ"]], "paclet:CSSTools/ref/CSSSubjectQ"}, 462 | "RefLink", 463 | BaseStyle->{"InlineFormula", FontFamily -> "Verdana"}]], "InlineFormula", 464 | ExpressionUUID->"6688b447-63f6-4d43-a58b-b902b146f366"], 465 | "\[NonBreakingSpace]", 466 | StyleBox["\[MediumSpace]\[FilledVerySmallSquare]\[MediumSpace]", 467 | "InlineSeparator"], 468 | " ", 469 | Cell[BoxData[ 470 | TemplateBox[{ 471 | Cell[ 472 | TextData["ExtractCSSFromXML"]], "paclet:CSSTools/ref/ExtractCSSFromXML"}, 473 | "RefLink", 474 | BaseStyle->{"InlineFormula", FontFamily -> "Verdana"}]], "InlineFormula", 475 | ExpressionUUID->"38c81da5-3698-4090-8295-3644a8f3ee32"], 476 | "\[NonBreakingSpace]", 477 | StyleBox["\[MediumSpace]\[FilledVerySmallSquare]\[MediumSpace]", 478 | "InlineSeparator"], 479 | " ", 480 | Cell[BoxData[ 481 | TemplateBox[{ 482 | Cell[ 483 | TextData["CSSCascade"]], "paclet:CSSTools/ref/CSSCascade"}, 484 | "RefLink", 485 | BaseStyle->{"InlineFormula", FontFamily -> "Verdana"}]], "InlineFormula", 486 | ExpressionUUID->"26488917-54a7-4162-bf3a-de5c34d90e09"], 487 | "\[NonBreakingSpace]", 488 | StyleBox["\[MediumSpace]\[FilledVerySmallSquare]\[MediumSpace]", 489 | "InlineSeparator"], 490 | " ", 491 | Cell[BoxData[ 492 | TemplateBox[{ 493 | Cell[ 494 | TextData["CSSInheritance"]], "paclet:CSSTools/ref/CSSInheritance"}, 495 | "RefLink", 496 | BaseStyle->{"InlineFormula", FontFamily -> "Verdana"}]], "InlineFormula", 497 | ExpressionUUID->"f32ca149-76e1-47a7-a145-8f5d074ed614"] 498 | }], "SeeAlso", 499 | CellID->929782353,ExpressionUUID->"ac6a223e-8112-43f7-8470-59e16479bdac"] 500 | }, Open ]], 501 | 502 | Cell[CellGroupData[{ 503 | 504 | Cell[TextData[{ 505 | Cell[BoxData[ 506 | TemplateBox[{6}, 507 | "Spacer1"]],ExpressionUUID->"8ab348dc-d1b0-4f4f-94bf-b538390355aa"], 508 | "Tutorials" 509 | }], "TutorialsSection", 510 | WholeCellGroupOpener->True, 511 | CellID->250839057,ExpressionUUID->"0d480bea-ab5e-42c5-aa7b-ec342d044b0e"], 512 | 513 | Cell["", "SectionHeaderSpacer",ExpressionUUID->"f821d88b-0c28-4323-b642-dc3b7ff37f71"], 514 | 515 | Cell[BoxData[ 516 | TemplateBox[{ 517 | Cell[ 518 | TextData["CSSTools"]], "paclet:CSSTools/tutorial/CSSTools"}, 519 | "RefLink", 520 | BaseStyle->"Tutorials"]], "Tutorials", 521 | CellID->341631938,ExpressionUUID->"8306f1d5-45f6-4529-9ff1-51e3aac27830"], 522 | 523 | Cell["", "SectionFooterSpacer",ExpressionUUID->"63639ee7-35c3-4dc8-8597-330fec2575e8"] 524 | }, Open ]], 525 | 526 | Cell[CellGroupData[{ 527 | 528 | Cell[TextData[{ 529 | Cell[BoxData[ 530 | TemplateBox[{6}, 531 | "Spacer1"]],ExpressionUUID->"23575616-5aec-4df3-a57b-9db17bb298e6"], 532 | "Related Guides" 533 | }], "MoreAboutSection", 534 | WholeCellGroupOpener->True, 535 | CellID->38303248,ExpressionUUID->"73fac190-38a6-4a03-bb84-1974187e44af"], 536 | 537 | Cell["", "SectionHeaderSpacer",ExpressionUUID->"baed0dc6-e4fb-4b50-ba03-dea1bf18a9ea"], 538 | 539 | Cell[BoxData[ 540 | TemplateBox[{ 541 | Cell[ 542 | TextData["CSSTools"]], "paclet:CSSTools/guide/CSSTools"}, 543 | "RefLink", 544 | BaseStyle->"MoreAbout"]], "MoreAbout", 545 | CellID->636028966,ExpressionUUID->"2ab2eec3-146f-4893-a0f4-818c4fc8ec4c"] 546 | }, Open ]], 547 | 548 | Cell[" ", "FooterCell",ExpressionUUID->"aa5cde5b-ed0e-4eb1-96b3-0813f3d50356"] 549 | }, 550 | Saveable->False, 551 | ScreenStyleEnvironment->"Working", 552 | WindowSize->{724.5, 750.}, 553 | WindowMargins->{{0, Automatic}, {Automatic, 0}}, 554 | WindowTitle->"CSSSelectorQ", 555 | TaggingRules->{ 556 | "ModificationHighlight" -> False, "ColorType" -> "SymbolColor", "LinkTrails" -> 557 | GridBox[{{ 558 | RowBox[{ 559 | ButtonBox[ 560 | "CSSTools", ButtonData -> "paclet:CSSTools/guide/CSSTools", 561 | BaseStyle -> {"Link", "DockedLinkTrail"}]}]}}, ColumnAlignments -> 562 | Left], "HasOptions" -> False, "ExampleCounter" -> 1, "NeedPlatMsgIn" -> 563 | None, "RootCaptions" -> "", 564 | "Metadata" -> { 565 | "built" -> "{2020, 7, 17, 8, 7, 16.1603336}", 566 | "history" -> {"0.0", "", "", ""}, "context" -> "CSSTools`", 567 | "keywords" -> {}, "specialkeywords" -> {}, 568 | "tutorialcollectionlinks" -> {}, "index" -> True, "label" -> 569 | "C S S Tools Symbol", "language" -> "en", "paclet" -> "CSSTools", 570 | "status" -> "None", "summary" -> 571 | "CSSSelectorQ[expr] returns True if expr is a valid CSSSelector object, \ 572 | and False otherwise.", "synonyms" -> {}, "tabletags" -> {}, "title" -> 573 | "CSSSelectorQ", "titlemodifier" -> "", "windowtitle" -> "CSSSelectorQ", 574 | "type" -> "Symbol", "uri" -> "CSSTools/ref/CSSSelectorQ", 575 | "WorkflowDockedCell" -> ""}, "SearchTextTranslated" -> "", "NewStyles" -> 576 | False}, 577 | CellContext->"Global`", 578 | FrontEndVersion->"12.1 for Microsoft Windows (64-bit) (June 19, 2020)", 579 | StyleDefinitions->Notebook[{ 580 | Cell[ 581 | StyleData[ 582 | StyleDefinitions -> FrontEnd`FileName[{"Wolfram"}, "Reference.nb"]]], 583 | Cell[ 584 | StyleData["Input"], CellContext -> "Global`"], 585 | Cell[ 586 | StyleData["Output"], CellContext -> "Global`"]}, Visible -> False, 587 | TaggingRules -> {"NewStyles" -> False}, FrontEndVersion -> 588 | "12.1 for Microsoft Windows (64-bit) (June 19, 2020)", StyleDefinitions -> 589 | "Default.nb"], 590 | ExpressionUUID->"658f11b1-4373-4e80-9ff0-44cf97de470c" 591 | ] 592 | (* End of Notebook Content *) 593 | 594 | (* Internal cache information *) 595 | (*CellTagsOutline 596 | CellTagsIndex->{ 597 | "PrimaryExamplesSection"->{ 598 | Cell[9161, 238, 435, 11, 26, "PrimaryExamplesSection",ExpressionUUID->"a7e4e334-12a8-4f55-9c1f-4f09a807a8b0", 599 | CellTags->"PrimaryExamplesSection", 600 | CellID->218286076]} 601 | } 602 | *) 603 | (*CellTagsIndex 604 | CellTagsIndex->{ 605 | {"PrimaryExamplesSection", 21050, 596} 606 | } 607 | *) 608 | (*NotebookFileOutline 609 | Notebook[{ 610 | Cell[584, 21, 5385, 123, 43, "AnchorBarGrid",ExpressionUUID->"10172e8a-40a9-4748-8c2d-54bef34a6c29", 611 | CellID->1], 612 | Cell[CellGroupData[{ 613 | Cell[5994, 148, 397, 9, 39, "ObjectNameGrid",ExpressionUUID->"abcf58a9-31d7-4e97-8e58-722b31e4593c"], 614 | Cell[6394, 159, 1337, 37, 86, "Usage",ExpressionUUID->"b124090a-fe0e-4eff-bb4e-f73a6a48114a", 615 | CellID->982511436] 616 | }, Open ]], 617 | Cell[CellGroupData[{ 618 | Cell[7768, 201, 855, 21, 28, "NotesSection",ExpressionUUID->"1ce28873-b097-4136-b1e1-be88963046c4", 619 | CellGroupingRules->{"SectionGrouping", 50}, 620 | CellID->518557591], 621 | Cell[8626, 224, 86, 0, 70, "SectionHeaderSpacer",ExpressionUUID->"4640635c-c0b8-4930-b67b-9fef4dd11eaa"], 622 | Cell[8715, 226, 320, 5, 70, "Notes",ExpressionUUID->"9915ee57-d8c4-4117-a98b-0118966efd02", 623 | CellID->1067943069], 624 | Cell[9038, 233, 86, 0, 70, "SectionFooterSpacer",ExpressionUUID->"c3545927-f4ee-4818-8f65-a71bed43063c"] 625 | }, Closed]], 626 | Cell[CellGroupData[{ 627 | Cell[9161, 238, 435, 11, 26, "PrimaryExamplesSection",ExpressionUUID->"a7e4e334-12a8-4f55-9c1f-4f09a807a8b0", 628 | CellTags->"PrimaryExamplesSection", 629 | CellID->218286076], 630 | Cell[CellGroupData[{ 631 | Cell[9621, 253, 307, 7, 22, "ExampleSection",ExpressionUUID->"29fd1fc4-6013-4cbc-bf71-4eecf09dfa5d", 632 | CellID->43318398], 633 | Cell[9931, 262, 172, 3, 21, "Input",ExpressionUUID->"f2a39e7c-c45c-402b-b86b-70bd09dc7e72", 634 | CellID->158635880], 635 | Cell[10106, 267, 404, 10, 30, "ExampleText",ExpressionUUID->"3f18e63e-72f8-48d8-b70a-47ac4a9896a0", 636 | CellID->32838738], 637 | Cell[CellGroupData[{ 638 | Cell[10535, 281, 196, 4, 21, "Input",ExpressionUUID->"2aabe099-db4e-4974-8586-53d96e2183d6", 639 | CellID->95771059], 640 | Cell[10734, 287, 1081, 32, 37, "Output",ExpressionUUID->"e99d124b-ec76-421a-9f3a-ba2b1e5f7691", 641 | CellID->330514465] 642 | }, Open ]], 643 | Cell[CellGroupData[{ 644 | Cell[11852, 324, 166, 3, 21, "Input",ExpressionUUID->"a6430b22-325f-4f58-954f-14196a84cfea", 645 | CellID->261130256], 646 | Cell[12021, 329, 129, 2, 27, "Output",ExpressionUUID->"0fdb16fc-0092-480e-a50c-a01b2619cdfb", 647 | CellID->787859480] 648 | }, Open ]] 649 | }, Open ]], 650 | Cell[CellGroupData[{ 651 | Cell[12199, 337, 317, 7, 22, "ExampleSection",ExpressionUUID->"335cfff7-797a-4e23-aa5a-de3958a8c581", 652 | CellID->2123667759], 653 | Cell[12519, 346, 172, 3, 70, "Input",ExpressionUUID->"b457a537-b1cc-4f25-b089-f00fd1a6c3fc", 654 | CellID->349318125], 655 | Cell[12694, 351, 1066, 31, 70, "ExampleText",ExpressionUUID->"a0b167cd-71a8-4cc6-bc5d-7268f58daf79", 656 | CellID->21517216], 657 | Cell[CellGroupData[{ 658 | Cell[13785, 386, 215, 4, 70, "Input",ExpressionUUID->"807b9ce6-90c3-4274-91e6-f9219cc50fdf", 659 | CellID->30143501], 660 | Cell[14003, 392, 556, 11, 66, "Output",ExpressionUUID->"fbb351f6-e7d1-46e2-b507-5b8c31a477d7", 661 | CellID->119680640] 662 | }, Open ]], 663 | Cell[CellGroupData[{ 664 | Cell[14596, 408, 219, 4, 70, "Input",ExpressionUUID->"b3401fc5-71a1-45bd-a6dc-f18bcade181b", 665 | CellID->453582021], 666 | Cell[14818, 414, 128, 2, 27, "Output",ExpressionUUID->"25e3075a-7974-4985-964d-ad744dd39e02", 667 | CellID->56563325] 668 | }, Open ]] 669 | }, Closed]], 670 | Cell[14973, 420, 86, 0, 24, "SectionFooterSpacer",ExpressionUUID->"375a5b3c-8c21-4286-a722-cf44f6f11e1d"] 671 | }, Open ]], 672 | Cell[CellGroupData[{ 673 | Cell[15096, 425, 260, 7, 54, "SeeAlsoSection",ExpressionUUID->"44ce44d9-3292-419b-a6d7-ff81108e20c1", 674 | CellID->1255426704], 675 | Cell[15359, 434, 2263, 64, 19, "SeeAlso",ExpressionUUID->"ac6a223e-8112-43f7-8470-59e16479bdac", 676 | CellID->929782353] 677 | }, Open ]], 678 | Cell[CellGroupData[{ 679 | Cell[17659, 503, 262, 7, 54, "TutorialsSection",ExpressionUUID->"0d480bea-ab5e-42c5-aa7b-ec342d044b0e", 680 | CellID->250839057], 681 | Cell[17924, 512, 86, 0, 13, "SectionHeaderSpacer",ExpressionUUID->"f821d88b-0c28-4323-b642-dc3b7ff37f71"], 682 | Cell[18013, 514, 231, 6, 18, "Tutorials",ExpressionUUID->"8306f1d5-45f6-4529-9ff1-51e3aac27830", 683 | CellID->341631938], 684 | Cell[18247, 522, 86, 0, 24, "SectionFooterSpacer",ExpressionUUID->"63639ee7-35c3-4dc8-8597-330fec2575e8"] 685 | }, Open ]], 686 | Cell[CellGroupData[{ 687 | Cell[18370, 527, 266, 7, 54, "MoreAboutSection",ExpressionUUID->"73fac190-38a6-4a03-bb84-1974187e44af", 688 | CellID->38303248], 689 | Cell[18639, 536, 86, 0, 13, "SectionHeaderSpacer",ExpressionUUID->"baed0dc6-e4fb-4b50-ba03-dea1bf18a9ea"], 690 | Cell[18728, 538, 228, 6, 18, "MoreAbout",ExpressionUUID->"2ab2eec3-146f-4893-a0f4-818c4fc8ec4c", 691 | CellID->636028966] 692 | }, Open ]], 693 | Cell[18971, 547, 78, 0, 70, "FooterCell",ExpressionUUID->"aa5cde5b-ed0e-4eb1-96b3-0813f3d50356"] 694 | } 695 | ] 696 | *) 697 | 698 | (* End of internal cache information *) 699 | 700 | -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/_0.cfe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SearchIndex/3/_0.cfe -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/_0.cfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SearchIndex/3/_0.cfs -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/_0.si: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SearchIndex/3/_0.si -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/fields.wl: -------------------------------------------------------------------------------- 1 | { 2 | <| 3 | "Name" -> "Usage", 4 | "Type" -> "Text", 5 | "Weight" -> 1.5, 6 | "Tokenized" -> True, 7 | "Stored" -> False, 8 | "Searchable" -> True, 9 | "Language" -> "English", 10 | "IgnoreCase" -> True, 11 | "StemmingMethod" -> Automatic, 12 | "CamelCaseMatching" -> True, 13 | "DeleteStopWords" -> True, 14 | "StoreTermVectors" -> False, 15 | "BulkRetrievalOptimized" -> False 16 | |>, 17 | <| 18 | "Name" -> "Text", 19 | "Type" -> "Text", 20 | "Tokenized" -> True, 21 | "Stored" -> False, 22 | "Weight" -> 1, 23 | "Searchable" -> True, 24 | "Language" -> "English", 25 | "IgnoreCase" -> True, 26 | "StemmingMethod" -> Automatic, 27 | "CamelCaseMatching" -> True, 28 | "DeleteStopWords" -> True, 29 | "StoreTermVectors" -> False, 30 | "BulkRetrievalOptimized" -> False 31 | |>, 32 | <| 33 | "Name" -> "TableText", 34 | "Type" -> "Text", 35 | "Tokenized" -> True, 36 | "Stored" -> False, 37 | "Weight" -> 1, 38 | "Searchable" -> True, 39 | "Language" -> "English", 40 | "IgnoreCase" -> True, 41 | "StemmingMethod" -> Automatic, 42 | "CamelCaseMatching" -> True, 43 | "DeleteStopWords" -> True, 44 | "StoreTermVectors" -> False, 45 | "BulkRetrievalOptimized" -> False 46 | |>, 47 | <| 48 | "Name" -> "ExampleText", 49 | "Type" -> "Text", 50 | "Weight" -> 0.05, 51 | "Tokenized" -> True, 52 | "Stored" -> False, 53 | "Searchable" -> True, 54 | "Language" -> "English", 55 | "IgnoreCase" -> True, 56 | "StemmingMethod" -> Automatic, 57 | "CamelCaseMatching" -> True, 58 | "DeleteStopWords" -> True, 59 | "StoreTermVectors" -> False, 60 | "BulkRetrievalOptimized" -> False 61 | |>, 62 | <| 63 | "Name" -> "SeeAlso", 64 | "Type" -> "Text", 65 | "LengthWeighted" -> False, 66 | "Tokenized" -> True, 67 | "Stored" -> False, 68 | "Weight" -> 1, 69 | "Searchable" -> True, 70 | "Language" -> "English", 71 | "IgnoreCase" -> True, 72 | "StemmingMethod" -> Automatic, 73 | "CamelCaseMatching" -> True, 74 | "DeleteStopWords" -> True, 75 | "StoreTermVectors" -> False, 76 | "BulkRetrievalOptimized" -> False 77 | |>, 78 | <| 79 | "Name" -> "ExactTitle", 80 | "Type" -> "Text", 81 | "Stored" -> True, 82 | "Tokenized" -> False, 83 | "LengthWeighted" -> False, 84 | "Weight" -> 1, 85 | "Searchable" -> True, 86 | "Language" -> "English", 87 | "IgnoreCase" -> True, 88 | "StemmingMethod" -> Automatic, 89 | "CamelCaseMatching" -> True, 90 | "DeleteStopWords" -> True, 91 | "StoreTermVectors" -> False, 92 | "BulkRetrievalOptimized" -> False 93 | |>, 94 | <| 95 | "Name" -> "Description", 96 | "Type" -> "Text", 97 | "Stored" -> True, 98 | "Searchable" -> False, 99 | "Tokenized" -> False, 100 | "Weight" -> 1, 101 | "Language" -> "English", 102 | "IgnoreCase" -> True, 103 | "StemmingMethod" -> Automatic, 104 | "CamelCaseMatching" -> True, 105 | "DeleteStopWords" -> True, 106 | "StoreTermVectors" -> False, 107 | "BulkRetrievalOptimized" -> False 108 | |>, 109 | <| 110 | "Name" -> "DisplayedCategory", 111 | "Type" -> "Text", 112 | "Stored" -> True, 113 | "Searchable" -> False, 114 | "Tokenized" -> False, 115 | "Weight" -> 1, 116 | "Language" -> "English", 117 | "IgnoreCase" -> True, 118 | "StemmingMethod" -> Automatic, 119 | "CamelCaseMatching" -> True, 120 | "DeleteStopWords" -> True, 121 | "StoreTermVectors" -> False, 122 | "BulkRetrievalOptimized" -> False 123 | |>, 124 | <| 125 | "Name" -> "URI", 126 | "Type" -> "Text", 127 | "Stored" -> True, 128 | "Tokenized" -> False, 129 | "LengthWeighted" -> False, 130 | "Weight" -> 1, 131 | "Searchable" -> True, 132 | "Language" -> "English", 133 | "IgnoreCase" -> True, 134 | "StemmingMethod" -> Automatic, 135 | "CamelCaseMatching" -> True, 136 | "DeleteStopWords" -> True, 137 | "StoreTermVectors" -> False, 138 | "BulkRetrievalOptimized" -> False 139 | |>, 140 | <| 141 | "Name" -> "NotebookType", 142 | "Type" -> "Text", 143 | "Stored" -> True, 144 | "Tokenized" -> False, 145 | "BulkRetrievalOptimized" -> True, 146 | "LengthWeighted" -> False, 147 | "Weight" -> 1, 148 | "Searchable" -> True, 149 | "Language" -> "English", 150 | "IgnoreCase" -> True, 151 | "StemmingMethod" -> Automatic, 152 | "CamelCaseMatching" -> True, 153 | "DeleteStopWords" -> True, 154 | "StoreTermVectors" -> False 155 | |>, 156 | <| 157 | "Name" -> "Context", 158 | "Type" -> "Text", 159 | "Stored" -> True, 160 | "Searchable" -> False, 161 | "Tokenized" -> False, 162 | "Weight" -> 1, 163 | "Language" -> "English", 164 | "IgnoreCase" -> True, 165 | "StemmingMethod" -> Automatic, 166 | "CamelCaseMatching" -> True, 167 | "DeleteStopWords" -> True, 168 | "StoreTermVectors" -> False, 169 | "BulkRetrievalOptimized" -> False 170 | |>, 171 | <| 172 | "Name" -> "NotebookStatus", 173 | "Type" -> "Text", 174 | "Stored" -> True, 175 | "Searchable" -> False, 176 | "Tokenized" -> False, 177 | "BulkRetrievalOptimized" -> True, 178 | "Weight" -> 1, 179 | "Language" -> "English", 180 | "IgnoreCase" -> True, 181 | "StemmingMethod" -> Automatic, 182 | "CamelCaseMatching" -> True, 183 | "DeleteStopWords" -> True, 184 | "StoreTermVectors" -> False 185 | |>, 186 | <| 187 | "Name" -> "PacletName", 188 | "Type" -> "Text", 189 | "Stored" -> True, 190 | "Searchable" -> False, 191 | "Tokenized" -> False, 192 | "Weight" -> 1, 193 | "Language" -> "English", 194 | "IgnoreCase" -> True, 195 | "StemmingMethod" -> Automatic, 196 | "CamelCaseMatching" -> True, 197 | "DeleteStopWords" -> True, 198 | "StoreTermVectors" -> False, 199 | "BulkRetrievalOptimized" -> False 200 | |>, 201 | <| 202 | "Name" -> "Language", 203 | "Type" -> "Text", 204 | "Stored" -> True, 205 | "Searchable" -> False, 206 | "Tokenized" -> False, 207 | "Weight" -> 1, 208 | "Language" -> "English", 209 | "IgnoreCase" -> True, 210 | "StemmingMethod" -> Automatic, 211 | "CamelCaseMatching" -> True, 212 | "DeleteStopWords" -> True, 213 | "StoreTermVectors" -> False, 214 | "BulkRetrievalOptimized" -> False 215 | |>, 216 | <| 217 | "Name" -> "SnippetPlaintext", 218 | "Type" -> "Text", 219 | "Stored" -> True, 220 | "Searchable" -> False, 221 | "Tokenized" -> False, 222 | "Weight" -> 1, 223 | "Language" -> "English", 224 | "IgnoreCase" -> True, 225 | "StemmingMethod" -> Automatic, 226 | "CamelCaseMatching" -> True, 227 | "DeleteStopWords" -> True, 228 | "StoreTermVectors" -> False, 229 | "BulkRetrievalOptimized" -> False 230 | |>, 231 | <| 232 | "Name" -> "Dictionary", 233 | "Type" -> "Text", 234 | "OmitTermFreqAndPositions" -> True, 235 | "Tokenized" -> True, 236 | "Stored" -> False, 237 | "Weight" -> 1, 238 | "Searchable" -> True, 239 | "Language" -> "English", 240 | "IgnoreCase" -> True, 241 | "StemmingMethod" -> Automatic, 242 | "CamelCaseMatching" -> True, 243 | "DeleteStopWords" -> True, 244 | "StoreTermVectors" -> False, 245 | "BulkRetrievalOptimized" -> False 246 | |>, 247 | <| 248 | "Name" -> "URL", 249 | "Type" -> "Text", 250 | "Stored" -> True, 251 | "Searchable" -> False, 252 | "Tokenized" -> False, 253 | "Weight" -> 1, 254 | "Language" -> "English", 255 | "IgnoreCase" -> True, 256 | "StemmingMethod" -> Automatic, 257 | "CamelCaseMatching" -> True, 258 | "DeleteStopWords" -> True, 259 | "StoreTermVectors" -> False, 260 | "BulkRetrievalOptimized" -> False 261 | |>, 262 | <| 263 | "Name" -> "Location", 264 | "Type" -> "FilePath", 265 | "Tokenized" -> False, 266 | "Stored" -> True, 267 | "Weight" -> 1, 268 | "Searchable" -> True, 269 | "Language" -> "English", 270 | "IgnoreCase" -> True, 271 | "StemmingMethod" -> Automatic, 272 | "CamelCaseMatching" -> True, 273 | "DeleteStopWords" -> True, 274 | "StoreTermVectors" -> False, 275 | "BulkRetrievalOptimized" -> False 276 | |>, 277 | <| 278 | "Name" -> "Frequency", 279 | "Type" -> "Real", 280 | "Stored" -> True, 281 | "Searchable" -> False, 282 | "Tokenized" -> False, 283 | "BulkRetrievalOptimized" -> True, 284 | "Weight" -> 1 285 | |>, 286 | <| 287 | "Name" -> "Title", 288 | "Type" -> "Title", 289 | "Stored" -> True, 290 | "Weight" -> 2, 291 | "Tokenized" -> True, 292 | "Searchable" -> True, 293 | "Language" -> "English", 294 | "IgnoreCase" -> True, 295 | "StemmingMethod" -> Automatic, 296 | "CamelCaseMatching" -> True, 297 | "DeleteStopWords" -> True, 298 | "StoreTermVectors" -> False, 299 | "BulkRetrievalOptimized" -> False 300 | |>, 301 | <| 302 | "Name" -> "NormalizedTitle", 303 | "Type" -> "Text", 304 | "Tokenized" -> False, 305 | "LengthWeighted" -> False, 306 | "Stored" -> False, 307 | "Weight" -> 1, 308 | "Searchable" -> True, 309 | "Language" -> "English", 310 | "IgnoreCase" -> True, 311 | "StemmingMethod" -> Automatic, 312 | "CamelCaseMatching" -> True, 313 | "DeleteStopWords" -> True, 314 | "StoreTermVectors" -> False, 315 | "BulkRetrievalOptimized" -> False 316 | |>, 317 | <| 318 | "Name" -> "NotebookPackage", 319 | "Type" -> "Text", 320 | "Stored" -> True, 321 | "Searchable" -> False, 322 | "Tokenized" -> False, 323 | "BulkRetrievalOptimized" -> True, 324 | "Weight" -> 1, 325 | "Language" -> "English", 326 | "IgnoreCase" -> True, 327 | "StemmingMethod" -> Automatic, 328 | "CamelCaseMatching" -> True, 329 | "DeleteStopWords" -> True, 330 | "StoreTermVectors" -> False 331 | |>, 332 | <| 333 | "Name" -> "TokenizedNotebookType", 334 | "Type" -> "Text", 335 | "LengthWeighted" -> False, 336 | "Tokenized" -> True, 337 | "Stored" -> False, 338 | "Weight" -> 1, 339 | "Searchable" -> True, 340 | "Language" -> "English", 341 | "IgnoreCase" -> True, 342 | "StemmingMethod" -> Automatic, 343 | "CamelCaseMatching" -> True, 344 | "DeleteStopWords" -> True, 345 | "StoreTermVectors" -> False, 346 | "BulkRetrievalOptimized" -> False 347 | |>, 348 | <| 349 | "Name" -> "ShortNotations", 350 | "Type" -> "Text", 351 | "Tokenized" -> False, 352 | "LengthWeighted" -> False, 353 | "Stored" -> False, 354 | "Weight" -> 1, 355 | "Searchable" -> True, 356 | "Language" -> "English", 357 | "IgnoreCase" -> True, 358 | "StemmingMethod" -> Automatic, 359 | "CamelCaseMatching" -> True, 360 | "DeleteStopWords" -> True, 361 | "StoreTermVectors" -> False, 362 | "BulkRetrievalOptimized" -> False 363 | |>, 364 | <| 365 | "Name" -> "ReferredBy", 366 | "Type" -> "Text", 367 | "Weight" -> 0.5, 368 | "LengthWeighted" -> False, 369 | "Tokenized" -> True, 370 | "Stored" -> False, 371 | "Searchable" -> True, 372 | "Language" -> "English", 373 | "IgnoreCase" -> True, 374 | "StemmingMethod" -> Automatic, 375 | "CamelCaseMatching" -> True, 376 | "DeleteStopWords" -> True, 377 | "StoreTermVectors" -> False, 378 | "BulkRetrievalOptimized" -> False 379 | |>, 380 | <| 381 | "Name" -> "Abstract", 382 | "Type" -> "Text", 383 | "Weight" -> 1.5, 384 | "Tokenized" -> True, 385 | "Stored" -> False, 386 | "Searchable" -> True, 387 | "Language" -> "English", 388 | "IgnoreCase" -> True, 389 | "StemmingMethod" -> Automatic, 390 | "CamelCaseMatching" -> True, 391 | "DeleteStopWords" -> True, 392 | "StoreTermVectors" -> False, 393 | "BulkRetrievalOptimized" -> False 394 | |>, 395 | <| 396 | "Name" -> "FunctionsSubsection", 397 | "Type" -> "Text", 398 | "Tokenized" -> True, 399 | "Stored" -> False, 400 | "Weight" -> 1, 401 | "Searchable" -> True, 402 | "Language" -> "English", 403 | "IgnoreCase" -> True, 404 | "StemmingMethod" -> Automatic, 405 | "CamelCaseMatching" -> True, 406 | "DeleteStopWords" -> True, 407 | "StoreTermVectors" -> False, 408 | "BulkRetrievalOptimized" -> False 409 | |>, 410 | <| 411 | "Name" -> "LinkedSymbols", 412 | "Type" -> "Text", 413 | "Tokenized" -> True, 414 | "Stored" -> False, 415 | "Weight" -> 1, 416 | "Searchable" -> True, 417 | "Language" -> "English", 418 | "IgnoreCase" -> True, 419 | "StemmingMethod" -> Automatic, 420 | "CamelCaseMatching" -> True, 421 | "DeleteStopWords" -> True, 422 | "StoreTermVectors" -> False, 423 | "BulkRetrievalOptimized" -> False 424 | |>, 425 | <| 426 | "Name" -> "MathCaption", 427 | "Type" -> "Text", 428 | "Tokenized" -> True, 429 | "Stored" -> False, 430 | "Weight" -> 1, 431 | "Searchable" -> True, 432 | "Language" -> "English", 433 | "IgnoreCase" -> True, 434 | "StemmingMethod" -> Automatic, 435 | "CamelCaseMatching" -> True, 436 | "DeleteStopWords" -> True, 437 | "StoreTermVectors" -> False, 438 | "BulkRetrievalOptimized" -> False 439 | |>, 440 | <| 441 | "Name" -> "Caption", 442 | "Type" -> "Text", 443 | "Tokenized" -> True, 444 | "Stored" -> False, 445 | "Weight" -> 1, 446 | "Searchable" -> True, 447 | "Language" -> "English", 448 | "IgnoreCase" -> True, 449 | "StemmingMethod" -> Automatic, 450 | "CamelCaseMatching" -> True, 451 | "DeleteStopWords" -> True, 452 | "StoreTermVectors" -> False, 453 | "BulkRetrievalOptimized" -> False 454 | |> 455 | } -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/indexMetadata.wl: -------------------------------------------------------------------------------- 1 | <|"IndexedPaths" -> None, "Driver" -> "Lucene", 2 | "CreationDate" -> DateObject[{2020, 7, 17, 9, 18, 3 | 36.7748376`9.318125654500891}, "Instant", "Gregorian", -7.], 4 | "Version" -> 3, "Synonyms" -> None, "Method" -> "BM25", 5 | "Language" -> "English", "ContentFieldOptions" -> 6 | <|"Title" -> <|"Stored" -> True, "Weight" -> 2|>, 7 | "ExactTitle" -> <|"Stored" -> True, "Tokenized" -> False, 8 | "LengthWeighted" -> False|>, "NormalizedTitle" -> 9 | <|"Tokenized" -> False, "LengthWeighted" -> False|>, 10 | "PossibleAlternateNames" -> <|"Weight" -> 1.5, "LengthWeighted" -> 11 | False|>, "ShortNotations" -> <|"Tokenized" -> False, 12 | "LengthWeighted" -> False|>, "Synonyms" -> <|"Weight" -> 1.5, 13 | "Stored" -> True, "LengthWeighted" -> False|>, 14 | "Keywords" -> <|"Stored" -> True|>, 15 | "URI" -> <|"Stored" -> True, "Tokenized" -> False, 16 | "LengthWeighted" -> False|>, "SnippetPlaintext" -> 17 | <|"Stored" -> True, "Searchable" -> False, "Tokenized" -> False|>, 18 | "ReferredBy" -> <|"Weight" -> 0.5, "LengthWeighted" -> False|>, 19 | "Description" -> <|"Stored" -> True, "Searchable" -> False, 20 | "Tokenized" -> False|>, "PacletName" -> <|"Stored" -> True, 21 | "Searchable" -> False, "Tokenized" -> False|>, 22 | "Language" -> <|"Stored" -> True, "Searchable" -> False, 23 | "Tokenized" -> False|>, "Usage" -> <|"Weight" -> 1.5|>, 24 | "Abstract" -> <|"Weight" -> 1.5|>, "NotebookType" -> 25 | <|"Stored" -> True, "Tokenized" -> False, "BulkRetrievalOptimized" -> 26 | True, "LengthWeighted" -> False|>, "TokenizedNotebookType" -> 27 | <|"LengthWeighted" -> False|>, "DisplayedCategory" -> 28 | <|"Stored" -> True, "Searchable" -> False, "Tokenized" -> False|>, 29 | "URL" -> <|"Stored" -> True, "Searchable" -> False, 30 | "Tokenized" -> False|>, "Context" -> <|"Stored" -> True, 31 | "Searchable" -> False, "Tokenized" -> False|>, 32 | "SeeAlso" -> <|"LengthWeighted" -> False|>, 33 | "ExampleText" -> <|"Weight" -> 0.05|>, "Frequency" -> 34 | <|"Stored" -> True, "Searchable" -> False, "Tokenized" -> False, 35 | "BulkRetrievalOptimized" -> True|>, "NotebookStatus" -> 36 | <|"Stored" -> True, "Searchable" -> False, "Tokenized" -> False, 37 | "BulkRetrievalOptimized" -> True|>, "NotebookPackage" -> 38 | <|"Stored" -> True, "Searchable" -> False, "Tokenized" -> False, 39 | "BulkRetrievalOptimized" -> True|>, "Dictionary" -> 40 | <|"OmitTermFreqAndPositions" -> True|>|>, "ContentLocationFunction" -> 41 | <|"SnippetSource" -> ("field:SnippetPlaintext" & ), 42 | "ReferenceLocation" -> Function[DocumentationSearch`Private`c, 43 | URL[StringReplace[DocumentationSearch`Private`c["URL"], 44 | "http://reference.wolfram.com/language/" -> 45 | "http://reference.wolframcloud.com/cloudplatform/"]]]|>, 46 | "DocumentWeightingRules" -> 47 | <|"NotebookType" -> {"Symbol" -> 1., "Guide" -> 1., "Root Guide" -> 1., 48 | "Upgrade Information" -> 1., "WorkflowGuide" -> 1., 49 | "CompiledType" -> 0.9166666666666666, "DataStructure" -> 50 | 0.9166666666666666, "Format" -> 0.9166666666666666, 51 | "Entity" -> 0.9166666666666666, "ExternalEvaluationSystem" -> 52 | 0.9166666666666666, "Predictor" -> 0.9166666666666666, 53 | "Classifier" -> 0.9166666666666666, "Method" -> 0.9166666666666666, 54 | "NetEncoder" -> 0.9166666666666666, "NetDecoder" -> 0.9166666666666666, 55 | "Workflow" -> 0.9166666666666666, "Interpreter" -> 0.8333333333333334, 56 | "Tutorial" -> 0.8333333333333334, "Tech Note" -> 0.8333333333333334, 57 | "Overview" -> 0.8333333333333334, "Database Connection" -> 58 | 0.8333333333333334, "Device Connection" -> 0.8333333333333334, 59 | "Service Connection" -> 0.8333333333333334, "Text Content" -> 60 | 0.8333333333333334, "Character Name" -> 0.75, 61 | "MathLink C Function" -> 0.75, "UnityLink C# Function" -> 0.75, 62 | "System Program" -> 0.6666666666666666, "Program" -> 0.6666666666666666, 63 | "File" -> 0.6666666666666666, "Embedding Format" -> 0.6666666666666666, 64 | "Indicator" -> 0.6666666666666666, "Front End Object" -> 65 | 0.5833333333333334, "Example" -> 0.5, "Menu Item" -> 0.5, 66 | "Message" -> 0.5, "Widget" -> 0.5}, "NotebookStatus" -> 67 | {"ObsoleteFlag" -> 1.*^-6, "AwaitingFutureDesignReviewFlag" -> 0.25, 68 | "NewInOldVersion" -> 0.00001, "None" -> 1.}, 69 | "NotebookPackage" -> {"Compatibility" -> 1., "Package" -> 0.2, 70 | "Mathematica" -> 1.}|>, "DocumentWeightingFunction" -> 71 | {"min(max(1+(log10(Frequency)),0.1),1.5)"}|> 72 | -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/segments_2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SearchIndex/3/segments_2 -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SearchIndex/3/write.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SearchIndex/3/write.lock -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SpellIndex/_9.cfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SpellIndex/_9.cfs -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SpellIndex/segments.gen: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SpellIndex/segments.gen -------------------------------------------------------------------------------- /CSSTools/Documentation/English/SpellIndex/segments_l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Documentation/English/SpellIndex/segments_l -------------------------------------------------------------------------------- /CSSTools/Examples/BareNotebook.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 11.3' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 158, 7] 13 | NotebookDataLength[ 5015, 139] 14 | NotebookOptionsPosition[ 3811, 116] 15 | NotebookOutlinePosition[ 4155, 131] 16 | CellTagsIndexPosition[ 4112, 128] 17 | WindowFrame->Normal*) 18 | 19 | (* Beginning of Notebook Content *) 20 | Notebook[{ 21 | Cell["Importing CSS 2.1 For Use In Wolfram Desktop", "h1", 22 | CellChangeTimes->{ 23 | 3.7595262019291153`*^9},ExpressionUUID->"b7915119-a440-4d38-a360-\ 24 | 6545a65f0ab2"], 25 | 26 | Cell["Created by anon.", "h2", 27 | CellChangeTimes->{{3.7595262097819347`*^9, 3.759526213391903*^9}, { 28 | 3.7620300515336933`*^9, 29 | 3.762030053437059*^9}},ExpressionUUID->"f2db8889-8f1f-4370-9679-\ 30 | e7bbc3531169"], 31 | 32 | Cell["\<\ 33 | What is CSS? 34 | \ 35 | \>", "question", 36 | CellChangeTimes->{{3.7595262223317623`*^9, 3.7595262242031655`*^9}, 37 | 3.760399106810958*^9},ExpressionUUID->"be4a1da8-d0d1-492d-9c98-\ 38 | 1f5c82e5db54"], 39 | 40 | Cell[TextData[{ 41 | "Quoting from the ", 42 | Cell[BoxData[ 43 | FormBox[ 44 | TemplateBox[{ 45 | "\"2.1 Cascading Sheet specification Style\"", 46 | "https://www.w3.org/TR/2011/REC-CSS2-20110607/"}, 47 | "HyperlinkURL"], TraditionalForm]], 48 | FormatType->"TraditionalForm",ExpressionUUID-> 49 | "94223d3e-3242-493a-8bde-a8fba545f2f0"], 50 | ": \[OpenCurlyDoubleQuote]CSS 2.1 is a style sheet language that allows \ 51 | authors and users to attach style (e.g., fonts and spacing) to structured \ 52 | documents (e.g., HTML documents and XML applications).\[CloseCurlyDoubleQuote]" 53 | }], "p", 54 | CellChangeTimes->{{3.7595262727863092`*^9, 3.75952627781092*^9}, { 55 | 3.7595263206499877`*^9, 3.759526397160966*^9}, {3.759526466242968*^9, 56 | 3.7595264904154677`*^9}},ExpressionUUID->"d22cf7eb-c2d0-4fd8-b783-\ 57 | 4f3dd910016f"], 58 | 59 | Cell["\<\ 60 | How are WD notebooks styled? 61 | \ 62 | \>", "question", 63 | CellChangeTimes->{{3.7595262293659277`*^9, 3.7595262353550963`*^9}, 64 | 3.7603991088097878`*^9},ExpressionUUID->"d924ffed-9405-4291-9aa7-\ 65 | 5d2f7fe215a2"], 66 | 67 | Cell["\<\ 68 | Notebooks consist of a vertical arrangement of cells, wherein each cell can \ 69 | contain boxes or other inline cells. The Wolfram Desktop has its own \ 70 | implementation of cascading styles. They are similar to CSS, but details like \ 71 | inheritance and style-targeting differ. Moreover the style property names \ 72 | have slightly different meanings in a few cases.\ 73 | \>", "p", 74 | CellChangeTimes->{{3.759526534155332*^9, 75 | 3.7595265688761215`*^9}},ExpressionUUID->"3b6ff9df-fd91-49ae-ad87-\ 76 | f948860461dd"], 77 | 78 | Cell["\<\ 79 | Why import CSS into WD? 80 | \ 81 | \>", "questionSpecial", 82 | CellChangeTimes->{{3.7595262391823344`*^9, 3.759526244501975*^9}, 83 | 3.7603991110799427`*^9},ExpressionUUID->"f202f61c-9683-403c-aebb-\ 84 | 06e03ca421d0"], 85 | 86 | Cell["\<\ 87 | If you see a style in use on a website, wouldn\[CloseCurlyQuote]t it be nice \ 88 | to implement that style within WD? Other reasons that come to mind:\ 89 | \>", "p", 90 | CellChangeTimes->{ 91 | 3.759526625389226*^9},ExpressionUUID->"318efc69-4e0d-4b6f-8791-\ 92 | 29412e854774"], 93 | 94 | Cell["\<\ 95 | WD and HTML both arrange \[OpenCurlyDoubleQuote]boxes\[CloseCurlyDoubleQuote] \ 96 | on the screen so the language is similar.\ 97 | \>", "li", 98 | CellChangeTimes->{ 99 | 3.759526641755928*^9},ExpressionUUID->"129b4909-363c-4228-acce-\ 100 | 02b10d703878"], 101 | 102 | Cell["\<\ 103 | Even though style names differ, there is greater than 50% overlap in style \ 104 | types.\ 105 | \>", "li", 106 | CellChangeTimes->{ 107 | 3.7595266482942963`*^9},ExpressionUUID->"8dc2c6ac-332a-4426-96d5-\ 108 | c19123188d6c"], 109 | 110 | Cell["\<\ 111 | A lot of effort goes into making effective style choices; an importer can \ 112 | speed up style transfer.\ 113 | \>", "li", 114 | CellChangeTimes->{ 115 | 3.75952665481507*^9},ExpressionUUID->"241c55f0-d427-48a6-a80f-a0c36eb31363"] 116 | }, 117 | WindowSize->{495, 468}, 118 | WindowMargins->{{Automatic, 201}, {Automatic, 159}}, 119 | FrontEndVersion->"11.3 for Microsoft Windows (64-bit) (March 6, 2018)", 120 | StyleDefinitions->"Default.nb" 121 | ] 122 | (* End of Notebook Content *) 123 | 124 | (* Internal cache information *) 125 | (*CellTagsOutline 126 | CellTagsIndex->{} 127 | *) 128 | (*CellTagsIndex 129 | CellTagsIndex->{} 130 | *) 131 | (*NotebookFileOutline 132 | Notebook[{ 133 | Cell[558, 20, 162, 3, 23, "h1",ExpressionUUID->"b7915119-a440-4d38-a360-6545a65f0ab2"], 134 | Cell[723, 25, 209, 4, 23, "h2",ExpressionUUID->"f2db8889-8f1f-4370-9679-e7bbc3531169"], 135 | Cell[935, 31, 194, 6, 39, "question",ExpressionUUID->"be4a1da8-d0d1-492d-9c98-1f5c82e5db54"], 136 | Cell[1132, 39, 784, 17, 55, "p",ExpressionUUID->"d22cf7eb-c2d0-4fd8-b783-4f3dd910016f"], 137 | Cell[1919, 58, 212, 6, 39, "question",ExpressionUUID->"d924ffed-9405-4291-9aa7-5d2f7fe215a2"], 138 | Cell[2134, 66, 502, 9, 71, "p",ExpressionUUID->"3b6ff9df-fd91-49ae-ad87-f948860461dd"], 139 | Cell[2639, 77, 212, 6, 39, "questionSpecial",ExpressionUUID->"f202f61c-9683-403c-aebb-06e03ca421d0"], 140 | Cell[2854, 85, 269, 6, 39, "p",ExpressionUUID->"318efc69-4e0d-4b6f-8791-29412e854774"], 141 | Cell[3126, 93, 245, 6, 23, "li",ExpressionUUID->"129b4909-363c-4228-acce-02b10d703878"], 142 | Cell[3374, 101, 209, 6, 23, "li",ExpressionUUID->"8dc2c6ac-332a-4426-96d5-c19123188d6c"], 143 | Cell[3586, 109, 221, 5, 39, "li",ExpressionUUID->"241c55f0-d427-48a6-a80f-a0c36eb31363"] 144 | } 145 | ] 146 | *) 147 | 148 | -------------------------------------------------------------------------------- /CSSTools/Examples/html-background-png-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WolframResearch/CSSTools/cef665c4056907e7950ab7aea0876c3fb85a36cd/CSSTools/Examples/html-background-png-7.png -------------------------------------------------------------------------------- /CSSTools/Examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example 5 | 8 | 9 | 10 | 11 | 12 |

Importing CSS 2.1 For Use In Wolfram Desktop

13 |

Created by anon.

14 |

What is CSS?

15 |

Quoting from the Cascading Style Sheet 2.1 specification: "CSS 2.1 is a style sheet language that allows authors and users to attach style (e.g., fonts and spacing) to structured documents (e.g., HTML documents and XML applications)."

16 |

How are WD notebooks styled?

17 |

Notebooks consist of a vertical arrangement of cells, wherein each cell can contain boxes or other inline cells. The Wolfram Desktop has its own implementation of cascading styles. They are similar to CSS, but details like inheritance and style-targeting differ. Moreover the style property names have slightly different meanings in a few cases.

18 |

Why import CSS into WD?

19 |

If you see a style in use on a website, wouldn't it be nice to implement that style within WD? Other reasons that come to mind:

20 | 26 |
    27 |
  • WD and HTML both arrange "boxes" on the screen so the language is similar.
  • 28 |
  • Even though style names differ, there is greater than 50% overlap in style types.
  • 29 |
  • A lot of effort goes into making effective style choices; an importer can speed up style transfer.
  • 30 |
31 | 32 | -------------------------------------------------------------------------------- /CSSTools/Examples/mystyle1.css: -------------------------------------------------------------------------------- 1 | @import url("mystyle2.css"); 2 | 3 | .tooltip { 4 | color: red; 5 | } -------------------------------------------------------------------------------- /CSSTools/Examples/mystyle2.css: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | font-style: italic; 3 | } -------------------------------------------------------------------------------- /CSSTools/Examples/simple.css: -------------------------------------------------------------------------------- 1 | tag { 2 | font-size:24px 3 | } -------------------------------------------------------------------------------- /CSSTools/Examples/test.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url("html-background-png-7.png") repeat darkblue; 3 | color: #dfe366; 4 | } 5 | 6 | h1 { 7 | font-size: 32px; 8 | font-weight: bold; 9 | } 10 | 11 | ul {} 12 | 13 | /* This is a comment1 */ 14 | p { 15 | font-family: Times New Roman; 16 | font-size: 20px; 17 | color: #eeeeee; 18 | } 19 | 20 | h3 { 21 | counter-increment: question; 22 | height: 50px; 23 | background-color: rgba(0,0,1,0.2); 24 | width: auto; 25 | overFlow: hidden; /* property name is OK but better to be all lowercase */ 26 | padding-top: 2; /* this will be ignored because it's missing units */ 27 | padding-bottom: initial !important; 28 | padding-right: 1em; 29 | padding-left: 2px; 30 | border: 1ex solid; 31 | border-left-color: red; 32 | margin: 5px 50% 10px 20px; 33 | font-variant: small-caps; 34 | } 35 | 36 | h3:before { 37 | content: counter(question); 38 | } 39 | 40 | h2 { 41 | font-size: 12px; 42 | font-family: arial; 43 | font-style: italic; 44 | color: #aaaaaa; 45 | } 46 | 47 | a { 48 | width: 20px /* This is a comment2 */ 49 | } -------------------------------------------------------------------------------- /CSSTools/Examples/test2.css: -------------------------------------------------------------------------------- 1 | @import "mystyle1.css"; 2 | 3 | .modal-scrollbar-measure { 4 | position: absolute; 5 | top: -9999px; 6 | width: 50px; 7 | height: 50px; 8 | overflow: scroll} 9 | @media (min-width: 768px) { 10 | .modal-dialog { 11 | width: 500px; 12 | margin: 30px auto} 13 | .modal-content { 14 | box-shadow: 0 5px 15px rgba(0,0,0,.5)} 15 | .modal-sm { 16 | width: 348px}} 17 | @media (min-width: 992px) { 18 | .modal-lg { 19 | width: 900px}} 20 | @page { 21 | margin-left: 3cm; 22 | } 23 | .tooltip { 24 | font-weight: bold 25 | } -------------------------------------------------------------------------------- /CSSTools/Kernel/CSSColors4.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | BeginPackage["CSSTools`CSSColors4`", {"CSSTools`"}]; 4 | 5 | (* CSSTokenizer` 6 | ---> various tokenizer functions e.g. CSSTokenQ. TokenTypeIs 7 | ---> token position modifiers e.g. AdvancePosAndSkipWhitespace *) 8 | (* CSSPropertyInterpreter` 9 | ---> defines consumeProperty and CSSPropertyData *) 10 | 11 | Needs["CSSTools`CSSTokenizer`"]; 12 | Needs["CSSTools`CSSPropertyInterpreter`"] 13 | 14 | (* Package Notes: implements https://drafts.csswg.org/css-color/ 15 | This package extends the CSS Tools to include CSS Color Module Level 4 (currently only a CSS working draft). 16 | It modifies the CSS data type defined in CSSPropertyInterpreter. 17 | *) 18 | 19 | Begin["`Private`"]; (* Begin Private Context *) 20 | 21 | 22 | (* Keywords tokenize to ident tokens. As other parts of CSS must maintain case, CSSNormalizeEscapes @ ToLowerCase is applied here as opposed to during tokenization. *) 23 | parseSingleColorKeyWord[prop_String, keyword_String] := 24 | Switch[CSSNormalizeEscapes @ ToLowerCase @ keyword, 25 | "currentcolor", Dynamic @ CurrentValue[FontColor], 26 | "transparent", None, (* interpreted as GrayLevel[0, 0] by Interpreter["Color"] *) 27 | "aliceblue", RGBColor[Rational[16, 17], Rational[248, 255], 1], 28 | "antiquewhite", RGBColor[Rational[50, 51], Rational[47, 51], Rational[43, 51]], 29 | "aqua", RGBColor[0, 1, 1], 30 | "aquamarine", RGBColor[Rational[127, 255], 1, Rational[212, 255]], 31 | "azure", RGBColor[Rational[16, 17], 1, 1], 32 | "beige", RGBColor[Rational[49, 51], Rational[49, 51], Rational[44, 51]], 33 | "bisque", RGBColor[1, Rational[76, 85], Rational[196, 255]], 34 | "black", RGBColor[0, 0, 0], 35 | "blanchedalmond", RGBColor[1, Rational[47, 51], Rational[41, 51]], 36 | "blue", RGBColor[0, 0, 1], 37 | "blueviolet", RGBColor[Rational[46, 85], Rational[43, 255], Rational[226, 255]], 38 | "brown", RGBColor[Rational[11, 17], Rational[14, 85], Rational[14, 85]], 39 | "burlywood", RGBColor[Rational[74, 85], Rational[184, 255], Rational[9, 17]], 40 | "cadetblue", RGBColor[Rational[19, 51], Rational[158, 255], Rational[32, 51]], 41 | "chartreuse", RGBColor[Rational[127, 255], 1, 0], 42 | "chocolate", RGBColor[Rational[14, 17], Rational[7, 17], Rational[2, 17]], 43 | "coral", RGBColor[1, Rational[127, 255], Rational[16, 51]], 44 | "cornflowerblue", RGBColor[Rational[20, 51], Rational[149, 255], Rational[79, 85]], 45 | "cornsilk", RGBColor[1, Rational[248, 255], Rational[44, 51]], 46 | "crimson", RGBColor[Rational[44, 51], Rational[4, 51], Rational[4, 17]], 47 | "cyan", RGBColor[0, 1, 1], 48 | "darkblue", RGBColor[0, 0, Rational[139, 255]], 49 | "darkcyan", RGBColor[0, Rational[139, 255], Rational[139, 255]], 50 | "darkgoldenrod", RGBColor[Rational[184, 255], Rational[134, 255], Rational[11, 255]], 51 | "darkgray", RGBColor[Rational[169, 255], Rational[169, 255], Rational[169, 255]], 52 | "darkgreen", RGBColor[0, Rational[20, 51], 0], 53 | "darkgrey", RGBColor[Rational[169, 255], Rational[169, 255], Rational[169, 255]], 54 | "darkkhaki", RGBColor[Rational[63, 85], Rational[61, 85], Rational[107, 255]], 55 | "darkmagenta", RGBColor[Rational[139, 255], 0, Rational[139, 255]], 56 | "darkolivegreen", RGBColor[Rational[1, 3], Rational[107, 255], Rational[47, 255]], 57 | "darkorange", RGBColor[1, Rational[28, 51], 0], 58 | "darkorchid", RGBColor[Rational[3, 5], Rational[10, 51], Rational[4, 5]], 59 | "darkred", RGBColor[Rational[139, 255], 0, 0], 60 | "darksalmon", RGBColor[Rational[233, 255], Rational[10, 17], Rational[122, 255]], 61 | "darkseagreen", RGBColor[Rational[143, 255], Rational[188, 255], Rational[143, 255]], 62 | "darkslateblue", RGBColor[Rational[24, 85], Rational[61, 255], Rational[139, 255]], 63 | "darkslategray", RGBColor[Rational[47, 255], Rational[79, 255], Rational[79, 255]], 64 | "darkslategrey", RGBColor[Rational[47, 255], Rational[79, 255], Rational[79, 255]], 65 | "darkturquoise", RGBColor[0, Rational[206, 255], Rational[209, 255]], 66 | "darkviolet", RGBColor[Rational[148, 255], 0, Rational[211, 255]], 67 | "deeppink", RGBColor[1, Rational[4, 51], Rational[49, 85]], 68 | "deepskyblue", RGBColor[0, Rational[191, 255], 1], 69 | "dimgray", RGBColor[Rational[7, 17], Rational[7, 17], Rational[7, 17]], 70 | "dimgrey", RGBColor[Rational[7, 17], Rational[7, 17], Rational[7, 17]], 71 | "dodgerblue", RGBColor[Rational[2, 17], Rational[48, 85], 1], 72 | "firebrick", RGBColor[Rational[178, 255], Rational[2, 15], Rational[2, 15]], 73 | "floralwhite", RGBColor[1, Rational[50, 51], Rational[16, 17]], 74 | "forestgreen", RGBColor[Rational[2, 15], Rational[139, 255], Rational[2, 15]], 75 | "fuchsia", RGBColor[1, 0, 1], 76 | "gainsboro", RGBColor[Rational[44, 51], Rational[44, 51], Rational[44, 51]], 77 | "ghostwhite", RGBColor[Rational[248, 255], Rational[248, 255], 1], 78 | "gold", RGBColor[1, Rational[43, 51], 0], 79 | "goldenrod", RGBColor[Rational[218, 255], Rational[11, 17], Rational[32, 255]], 80 | "gray", RGBColor[Rational[128, 255], Rational[128, 255], Rational[128, 255]], 81 | "green", RGBColor[0, Rational[128, 255], 0], 82 | "greenyellow", RGBColor[Rational[173, 255], 1, Rational[47, 255]], 83 | "grey", RGBColor[Rational[128, 255], Rational[128, 255], Rational[128, 255]], 84 | "honeydew", RGBColor[Rational[16, 17], 1, Rational[16, 17]], 85 | "hotpink", RGBColor[1, Rational[7, 17], Rational[12, 17]], 86 | "indianred", RGBColor[Rational[41, 51], Rational[92, 255], Rational[92, 255]], 87 | "indigo", RGBColor[Rational[5, 17], 0, Rational[26, 51]], 88 | "ivory", RGBColor[1, 1, Rational[16, 17]], 89 | "khaki", RGBColor[Rational[16, 17], Rational[46, 51], Rational[28, 51]], 90 | "lavender", RGBColor[Rational[46, 51], Rational[46, 51], Rational[50, 51]], 91 | "lavenderblush", RGBColor[1, Rational[16, 17], Rational[49, 51]], 92 | "lawngreen", RGBColor[Rational[124, 255], Rational[84, 85], 0], 93 | "lemonchiffon", RGBColor[1, Rational[50, 51], Rational[41, 51]], 94 | "lightblue", RGBColor[Rational[173, 255], Rational[72, 85], Rational[46, 51]], 95 | "lightcoral", RGBColor[Rational[16, 17], Rational[128, 255], Rational[128, 255]], 96 | "lightcyan", RGBColor[Rational[224, 255], 1, 1], 97 | "lightgoldenrodyellow", RGBColor[Rational[50, 51], Rational[50, 51], Rational[14, 17]], 98 | "lightgray", RGBColor[Rational[211, 255], Rational[211, 255], Rational[211, 255]], 99 | "lightgreen", RGBColor[Rational[48, 85], Rational[14, 15], Rational[48, 85]], 100 | "lightgrey", RGBColor[Rational[211, 255], Rational[211, 255], Rational[211, 255]], 101 | "lightpink", RGBColor[1, Rational[182, 255], Rational[193, 255]], 102 | "lightsalmon", RGBColor[1, Rational[32, 51], Rational[122, 255]], 103 | "lightseagreen", RGBColor[Rational[32, 255], Rational[178, 255], Rational[2, 3]], 104 | "lightskyblue", RGBColor[Rational[9, 17], Rational[206, 255], Rational[50, 51]], 105 | "lightslategray", RGBColor[Rational[7, 15], Rational[8, 15], Rational[3, 5]], 106 | "lightslategrey", RGBColor[Rational[7, 15], Rational[8, 15], Rational[3, 5]], 107 | "lightsteelblue", RGBColor[Rational[176, 255], Rational[196, 255], Rational[74, 85]], 108 | "lightyellow", RGBColor[1, 1, Rational[224, 255]], 109 | "lime", RGBColor[0, 1, 0], 110 | "limegreen", RGBColor[Rational[10, 51], Rational[41, 51], Rational[10, 51]], 111 | "linen", RGBColor[Rational[50, 51], Rational[16, 17], Rational[46, 51]], 112 | "magenta", RGBColor[1, 0, 1], 113 | "maroon", RGBColor[Rational[128, 255], 0, 0], 114 | "mediumaquamarine", RGBColor[Rational[2, 5], Rational[41, 51], Rational[2, 3]], 115 | "mediumblue", RGBColor[0, 0, Rational[41, 51]], 116 | "mediumorchid", RGBColor[Rational[62, 85], Rational[1, 3], Rational[211, 255]], 117 | "mediumpurple", RGBColor[Rational[49, 85], Rational[112, 255], Rational[73, 85]], 118 | "mediumseagreen", RGBColor[Rational[4, 17], Rational[179, 255], Rational[113, 255]], 119 | "mediumslateblue", RGBColor[Rational[41, 85], Rational[104, 255], Rational[14, 15]], 120 | "mediumspringgreen", RGBColor[0, Rational[50, 51], Rational[154, 255]], 121 | "mediumturquoise", RGBColor[Rational[24, 85], Rational[209, 255], Rational[4, 5]], 122 | "mediumvioletred", RGBColor[Rational[199, 255], Rational[7, 85], Rational[133, 255]], 123 | "midnightblue", RGBColor[Rational[5, 51], Rational[5, 51], Rational[112, 255]], 124 | "mintcream", RGBColor[Rational[49, 51], 1, Rational[50, 51]], 125 | "mistyrose", RGBColor[1, Rational[76, 85], Rational[15, 17]], 126 | "moccasin", RGBColor[1, Rational[76, 85], Rational[181, 255]], 127 | "navajowhite", RGBColor[1, Rational[74, 85], Rational[173, 255]], 128 | "navy", RGBColor[0, 0, Rational[128, 255]], 129 | "oldlace", RGBColor[Rational[253, 255], Rational[49, 51], Rational[46, 51]], 130 | "olive", RGBColor[Rational[128, 255], Rational[128, 255], 0], 131 | "olivedrab", RGBColor[Rational[107, 255], Rational[142, 255], Rational[7, 51]], 132 | "orange", RGBColor[1, Rational[11, 17], 0], 133 | "orangered", RGBColor[1, Rational[23, 85], 0], 134 | "orchid", RGBColor[Rational[218, 255], Rational[112, 255], Rational[214, 255]], 135 | "palegoldenrod", RGBColor[Rational[14, 15], Rational[232, 255], Rational[2, 3]], 136 | "palegreen", RGBColor[Rational[152, 255], Rational[251, 255], Rational[152, 255]], 137 | "paleturquoise", RGBColor[Rational[35, 51], Rational[14, 15], Rational[14, 15]], 138 | "palevioletred", RGBColor[Rational[73, 85], Rational[112, 255], Rational[49, 85]], 139 | "papayawhip", RGBColor[1, Rational[239, 255], Rational[71, 85]], 140 | "peachpuff", RGBColor[1, Rational[218, 255], Rational[37, 51]], 141 | "peru", RGBColor[Rational[41, 51], Rational[133, 255], Rational[21, 85]], 142 | "pink", RGBColor[1, Rational[64, 85], Rational[203, 255]], 143 | "plum", RGBColor[Rational[13, 15], Rational[32, 51], Rational[13, 15]], 144 | "powderblue", RGBColor[Rational[176, 255], Rational[224, 255], Rational[46, 51]], 145 | "purple", RGBColor[Rational[128, 255], 0, Rational[128, 255]], 146 | "rebeccapurple", RGBColor[Rational[2, 5], Rational[1, 5], Rational[3, 5]], 147 | "red", RGBColor[1, 0, 0], 148 | "rosybrown", RGBColor[Rational[188, 255], Rational[143, 255], Rational[143, 255]], 149 | "royalblue", RGBColor[Rational[13, 51], Rational[7, 17], Rational[15, 17]], 150 | "saddlebrown", RGBColor[Rational[139, 255], Rational[23, 85], Rational[19, 255]], 151 | "salmon", RGBColor[Rational[50, 51], Rational[128, 255], Rational[38, 85]], 152 | "sandybrown", RGBColor[Rational[244, 255], Rational[164, 255], Rational[32, 85]], 153 | "seagreen", RGBColor[Rational[46, 255], Rational[139, 255], Rational[29, 85]], 154 | "seashell", RGBColor[1, Rational[49, 51], Rational[14, 15]], 155 | "sienna", RGBColor[Rational[32, 51], Rational[82, 255], Rational[3, 17]], 156 | "silver", RGBColor[Rational[64, 85], Rational[64, 85], Rational[64, 85]], 157 | "skyblue", RGBColor[Rational[9, 17], Rational[206, 255], Rational[47, 51]], 158 | "slateblue", RGBColor[Rational[106, 255], Rational[6, 17], Rational[41, 51]], 159 | "slategray", RGBColor[Rational[112, 255], Rational[128, 255], Rational[48, 85]], 160 | "slategrey", RGBColor[Rational[112, 255], Rational[128, 255], Rational[48, 85]], 161 | "snow", RGBColor[1, Rational[50, 51], Rational[50, 51]], 162 | "springgreen", RGBColor[0, 1, Rational[127, 255]], 163 | "steelblue", RGBColor[Rational[14, 51], Rational[26, 51], Rational[12, 17]], 164 | "tan", RGBColor[Rational[14, 17], Rational[12, 17], Rational[28, 51]], 165 | "teal", RGBColor[0, Rational[128, 255], Rational[128, 255]], 166 | "thistle", RGBColor[Rational[72, 85], Rational[191, 255], Rational[72, 85]], 167 | "tomato", RGBColor[1, Rational[33, 85], Rational[71, 255]], 168 | "turquoise", RGBColor[Rational[64, 255], Rational[224, 255], Rational[208, 255]], 169 | "violet", RGBColor[Rational[14, 15], Rational[26, 51], Rational[14, 15]], 170 | "wheat", RGBColor[Rational[49, 51], Rational[74, 85], Rational[179, 255]], 171 | "white", RGBColor[1, 1, 1], 172 | "whitesmoke", RGBColor[Rational[49, 51], Rational[49, 51], Rational[49, 51]], 173 | "yellow", RGBColor[1, 1, 0], 174 | "yellowgreen", RGBColor[Rational[154, 255], Rational[41, 51], Rational[10, 51]], 175 | _, unrecognizedValueFailure @ prop 176 | ] 177 | 178 | 179 | (* Hex *) 180 | $1XC = Repeated[RegularExpression[RE["hex digit"]], {1}]; 181 | $2XC = Repeated[RegularExpression[RE["hex digit"]], {2}]; 182 | fromhexdigits[s_] := FromDigits[s, 16] 183 | (* 3 digits *) hexPattern3[] := StartOfString ~~ r:$1XC ~~ g:$1XC ~~ b:$1XC ~~ EndOfString :> RGBColor @@ (fromhexdigits /@ {r, g, b } / 15); 184 | (* 4 digits *) hexPattern4[] := StartOfString ~~ r:$1XC ~~ g:$1XC ~~ b:$1XC ~~ a:$1XC ~~ EndOfString :> RGBColor @@ (fromhexdigits /@ {r, g, b, a} / 15); 185 | (* 6 digits *) hexPattern6[] := StartOfString ~~ r:$2XC ~~ g:$2XC ~~ b:$2XC ~~ EndOfString :> RGBColor @@ (fromhexdigits /@ {r, g, b } / 255); 186 | (* 8 digits *) hexPattern8[] := StartOfString ~~ r:$2XC ~~ g:$2XC ~~ b:$2XC ~~ a:$2XC ~~ EndOfString :> RGBColor @@ (fromhexdigits /@ {r, g, b, a} / 255); 187 | 188 | parseSingleColorHex[prop_String, hexString_String] := 189 | Which[ 190 | StringMatchQ[hexString, First @ hexPattern3[]], First[StringCases[hexString, hexPattern3[]], unrecognizedValueFailure @ prop], 191 | StringMatchQ[hexString, First @ hexPattern4[]], First[StringCases[hexString, hexPattern4[]], unrecognizedValueFailure @ prop], 192 | StringMatchQ[hexString, First @ hexPattern6[]], First[StringCases[hexString, hexPattern6[]], unrecognizedValueFailure @ prop], 193 | StringMatchQ[hexString, First @ hexPattern8[]], First[StringCases[hexString, hexPattern8[]], unrecognizedValueFailure @ prop], 194 | True, Failure["UnexpectedParse", <|"Message" -> "Unrecognized hex color " <> hexString <> "."|>]] 195 | 196 | 197 | (* RGB *) 198 | (* The patterns assume all whitespace has been removed. *) 199 | rgbaPattern[] := 200 | { 201 | CSSToken[KeyValuePattern[{"Type" -> v1:"number"|"percentage", "Value" -> r_}]], 202 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 203 | CSSToken[KeyValuePattern[{"Type" -> v1:"number"|"percentage", "Value" -> g_}]], 204 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 205 | CSSToken[KeyValuePattern[{"Type" -> v1:"number"|"percentage", "Value" -> b_}]], 206 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 207 | CSSToken[KeyValuePattern[{"Type" -> v2:"number"|"percentage", "Value" -> a_}]] 208 | } :> Apply[RGBColor, Append[{r, g, b}/If[v1 == "number", 255, 100.], If[v2 == "number", Clip[a, {0, 1}], a/100.]]] 209 | rgbPattern[] := 210 | { 211 | CSSToken[KeyValuePattern[{"Type" -> v1:"number"|"percentage", "Value" -> r_}]], 212 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 213 | CSSToken[KeyValuePattern[{"Type" -> v1:"number"|"percentage", "Value" -> g_}]], 214 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 215 | CSSToken[KeyValuePattern[{"Type" -> v1:"number"|"percentage", "Value" -> b_}]] 216 | } :> Apply[RGBColor, {r, g, b}/If[v1 == "number", 255, 100.]] 217 | 218 | 219 | (* HSL *) 220 | HSLtoHSB[h_, s_, l_, a___] := With[{b = (2 * l + s * (1 - Abs[2 * l - 1])) / 2}, If[b == 0, Hue[h, 0, 0, a], Hue[h, 2 * (b - l) / b, b, a]]] 221 | 222 | (* The patterns assume all whitespace has been removed. *) 223 | hslaPattern[] := 224 | { 225 | Alternatives[ 226 | hAll:CSSToken[KeyValuePattern[{"Type" -> type:"dimension", "Value" -> h_, "Unit" -> "deg"|"grad"|"rad"|"turn"}]], 227 | hAll:CSSToken[KeyValuePattern[{"Type" -> type:"number", "Value" -> h_}]]], 228 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 229 | CSSToken[KeyValuePattern[{"Type" -> "percentage", "Value" -> s_}]], 230 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 231 | CSSToken[KeyValuePattern[{"Type" -> "percentage", "Value" -> l_}]], 232 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 233 | CSSToken[KeyValuePattern[{"Type" -> "number", "Value" -> a_}]] 234 | } :> HSLtoHSB[If[type == "number", h, parseAngle[hAll]]/360, s/100, l/100, Clip[a, {0, 1}]] 235 | hslPattern[] := 236 | { 237 | Alternatives[ 238 | hAll:CSSToken[KeyValuePattern[{"Type" -> type:"dimension", "Value" -> h_, "Unit" -> "deg"|"grad"|"rad"|"turn"}]], 239 | hAll:CSSToken[KeyValuePattern[{"Type" -> type:"number", "Value" -> h_}]]], 240 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 241 | CSSToken[KeyValuePattern[{"Type" -> "percentage", "Value" -> s_}]], 242 | d:Repeated[CSSToken[KeyValuePattern["Type" -> "comma"]], {0, 1}], 243 | CSSToken[KeyValuePattern[{"Type" -> "percentage", "Value" -> l_}]] 244 | } :> HSLtoHSB[If[type == "number", h, parseAngle[hAll]]/360, s/100, l/100] 245 | 246 | 247 | parseSingleColorFunction[prop_String, token_?CSSTokenQ] := 248 | Module[{relevantTokens, function = token["String"]}, 249 | (* relevantTokens drops the token's type and string, and removes all whitespace tokens *) 250 | relevantTokens = DeleteCases[token["Children"], CSSToken[KeyValuePattern["Type" -> "whitespace"]], {1}]; 251 | Which[ 252 | (* the "a" of rgb function heads is optional *) 253 | StringMatchQ[function, RegularExpression[RE["R"] ~~ RE["G"] ~~ RE["B"] ~~ "(" ~~ RE["A"] ~~ "?)"]], 254 | Which[ 255 | MatchQ[relevantTokens, First @ rgbaPattern[]], Replace[relevantTokens, rgbaPattern[]], 256 | MatchQ[relevantTokens, First @ rgbPattern[]], Replace[relevantTokens, rgbPattern[]], 257 | True, unrecognizedValueFailure @ prop], 258 | (* the "a" of hsl function heads is optional *) 259 | StringMatchQ[function, RegularExpression[RE["H"] ~~ RE["S"] ~~ RE["L"] ~~ "(" ~~ RE["A"] ~~ "?)"]], 260 | Which[ 261 | MatchQ[relevantTokens, First @ hslaPattern[]], Replace[relevantTokens, hslaPattern[]], 262 | MatchQ[relevantTokens, First @ hslPattern[]], Replace[relevantTokens, hslPattern[]], 263 | True, unrecognizedValueFailure @ prop], 264 | True, 265 | Failure["UnexpectedParse", <|"Message" -> "Unrecognized color function " <> function <> "."|>]]] 266 | 267 | 268 | (* ::Section:: *) 269 | (*New Properties*) 270 | 271 | 272 | (* modified CSS properties *) 273 | If[!AssociationQ[CSSPropertyData], CSSPropertyData = <||>]; 274 | AssociateTo[CSSPropertyData, { 275 | "color" -> <| 276 | "Inherited" -> True, 277 | "CSSInitialValue" -> "black", (* CSS 2.1 did not define this *) 278 | "InterpretedGlobalValues" -> <| 279 | "inherit" -> FontColor -> Inherited, 280 | "initial" -> FontColor -> Black|>, 281 | "Animatable" -> True, 282 | "Values" -> {""}, 283 | "AppliesTo" -> All|>}] 284 | 285 | (* ::Subsection:: *) 286 | (*Color*) 287 | 288 | 289 | (* new interpreters *) 290 | (* parse all color types *) 291 | parseSingleColor[prop_String, token_?CSSTokenQ] := parseSingleColor[prop, token] = 292 | Switch[token["Type"], 293 | "ident", parseSingleColorKeyWord[prop, token["String"]], 294 | "hash", parseSingleColorHex[prop, token["String"]], 295 | "function", parseSingleColorFunction[prop, token], 296 | _, unrecognizedValueFailure @ prop] 297 | 298 | parseSingleColor[prop_String, ___] := unrecognizedValueFailure @ prop 299 | 300 | 301 | (* ::Section:: *) 302 | (*Package Footer*) 303 | 304 | 305 | End[]; (* End Private Context *) 306 | EndPackage[]; 307 | -------------------------------------------------------------------------------- /CSSTools/Kernel/CSSCustomProperties1.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | BeginPackage["CSSTools`CSSCustomProperties1`"] 4 | (* Exported symbols added here with SymbolName::usage *) 5 | 6 | (* CSSTokenizer` 7 | ---> various tokenizer functions e.g. CSSToken, CSSTokenQ, CSSUntokenize *) 8 | (* CSSPropertyInterpreter` 9 | ---> defines consumeProperty *) 10 | (* CSSStyleSheetInterpreter` 11 | ---> defines inheritedPropertyRules *) 12 | 13 | Needs["CSSTools`CSSTokenizer`"]; 14 | Needs["CSSTools`CSSPropertyInterpreter`"]; 15 | Needs["CSSTools`CSSStyleSheetInterpreter`"]; 16 | 17 | 18 | Begin["`Private`"] (* Begin Private Context *) 19 | 20 | 21 | (* ::Subsection::Closed:: *) 22 | (*custom properties*) 23 | 24 | 25 | (* Custom Property Definition 26 | A custom CSS property definition is defined by having a property name that starts with two dashes. 27 | The values of a custom property definition are very permissive: 28 | * CSS Syntax 3 trims whitespace around property values; effectively substituting Nothing 29 | * any token sequence is allowed (bad tokens like bad-url or unmatched brackets still fail) 30 | * the 'initial' ident token is replaced with a "guaranteed-failure" value 31 | * the 'inherit' or 'unset' ident tokens are effectively ignored since all custom properties inherit 32 | 33 | Custom property definitions follow CSS cascade rules: the most important and highest specificity variable definition found in the CSS is used *) 34 | 35 | (* var() referencing of custom property definitions 36 | * A custom CSS property definition is referenced with the var() function e.g. var(--prop, fallback) 37 | * var() can only appear in the property value 38 | * var() is parsed as a token sequence, not string substitution e.g. var(--prop)px is not 39 | * The fallback is not required. If present, it can be any token sequence, including comma tokens or more var() substitutions. 40 | * Care must be taken to avoid generation of large token sequences. A cutoff token length is suggested but arbitrary. 41 | + All var() substitution happens at compute time during the cascade/inheritance: 42 | * any var() in a property value effectively keeps the entire value from parsing 43 | * at compute time the value can fail to parse after substitution 44 | * recursive definitions are checked and, if found, generates a "guaranteed-failure" value 45 | *) 46 | 47 | (* The DownValue for consuming var() referencing in properties needs to come early in order to override existing behavior *) 48 | (* 49 | The DownValue position for defining custom properties is not as particular since it does not conflict with vendor prefixes e.g. -moz-*, -webkit-* etc. 50 | We put it at the start of the DownValues list as well for no good reason. *) 51 | DownValues[consumeProperty] = DeleteDuplicates @ (* in case this file is loaded multiple times, delete duplicate DownValues *) 52 | Join[ 53 | { 54 | (* corner case of no property value is still a valid custom property definition *) 55 | HoldPattern[ 56 | Condition[consumeProperty[prop_String, {}, opts:OptionsPattern[]], StringQ[prop] && StringStartsQ[prop, "--"]] 57 | ] :> 58 | <|"CSSCustomPropertyDefinition" -> <| 59 | "Name" -> prop, 60 | "Value" -> Nothing, 61 | "Namespaces" -> OptionValue["Namespaces"]|>|>, 62 | 63 | (* normal custom property definition *) 64 | HoldPattern[ 65 | Condition[consumeProperty[prop_String, tokens:{__?CSSTokenQ}, opts:OptionsPattern[]], StringQ[prop] && StringStartsQ[prop, "--"]] 66 | ] :> 67 | <|"CSSCustomPropertyDefinition" -> <| 68 | "Name" -> prop, 69 | "Value" -> 70 | If[Length[tokens] == 1 && TokenTypeIs["ident", tokens[[1]]], 71 | Which[ 72 | TokenStringIs["initial", tokens[[1]]], Failure["GuaranteedInvalidValue", <|"Message" -> "No custom property found."|>], 73 | TokenStringIs["inherit" | "unset", tokens[[1]]], Inherited, 74 | True, CSSUntokenize[tokens] 75 | ] 76 | , 77 | CSSUntokenize[tokens] 78 | ], 79 | "Namespaces" -> OptionValue["Namespaces"]|>|>, 80 | 81 | (* any use of var() must be resolved at compute time (CSSCascade/CSSInheritance) unless a parse error is detected *) 82 | HoldPattern[ 83 | Condition[consumeProperty[prop_String, tokens:{__?CSSTokenQ}, opts:OptionsPattern[]], !FreeQ[tokens, TokenPatternString["var", "function"]]] 84 | ] :> 85 | Module[{varCheck, failPosition}, 86 | varCheck = parseVarFunctionToken[#, {}]& /@ Extract[tokens, Position[tokens, TokenPatternString["var", "function"]]]; 87 | failPosition = FirstPosition[Replace[varCheck, x_Failure :> x["MessageParameters"]["Type"], 1], "Parse", {}, 1]; 88 | If[failPosition =!= {}, 89 | Extract[varCheck, failPosition] 90 | , 91 | <|"CSSResolveValueAtComputeTime" -> <| 92 | "String" -> CSSUntokenize[tokens], 93 | "Property" -> prop, 94 | "Namespaces" -> OptionValue["Namespaces"]|>|> 95 | ] 96 | ]}, 97 | DownValues[consumeProperty]] 98 | 99 | 100 | (* all custom property definitions inherit *) 101 | inheritedPropertyRules = Append[inheritedPropertyRules, StringStartsQ[#, "--"]&]; 102 | 103 | 104 | (* ========== Parsing var() function ========== *) 105 | 106 | ClearAll[varFailureNoDefinition, varFailureRecursion]; 107 | varFailureNotVarFunction = 108 | Failure["UnexpectedToken", <| 109 | "MessageTemplate" -> "Expected a var() function token.", 110 | "MessageParameters" -> <|"Type" -> "Parse"|>|>]; 111 | varFailureNoName = 112 | Failure["GuaranteedInvalidValue", <| 113 | "MessageTemplate" -> "Missing custom property name.", 114 | "MessageParameters" -> <|"Type" -> "Parse"|>|>]; 115 | varFailureBadName = 116 | Failure["GuaranteedInvalidValue", <| 117 | "MessageTemplate" -> "Invalid custom property name.", 118 | "MessageParameters" -> <|"Type" -> "Parse"|>|>]; 119 | varFailureNoDefinition[def_] := 120 | Failure["GuaranteedInvalidValue", <| 121 | "MessageTemplate" -> "Failed to find custom property definition.", 122 | "Prop" -> def, 123 | "MessageParameters" -> <|"Type" -> "Compute"|>|>]; 124 | varFailureNoComma = 125 | Failure["GuaranteedInvalidValue", <| 126 | "MessageTemplate" -> "Expected a comma token before the fallback value.", 127 | "MessageParameters" -> <|"Type" -> "Parse"|>|>]; 128 | varFailureRecursion[cycles_] := 129 | Failure["GuaranteedInvalidValue", <| 130 | "MessageTemplate" -> "Recursive custom property definition.", 131 | "Loops" -> cycles, 132 | "MessageParameters" -> <|"Type" -> "Parse"|>|>]; 133 | 134 | Attributes[getCustomPropertyNameFromVarFunction] = {HoldRest}; 135 | getCustomPropertyNameFromVarFunction[token_?CSSTokenQ] := 136 | Module[{pos = 1, l, tokens}, 137 | tokens = token["Children"]; 138 | l = Length[tokens]; 139 | getCustomPropertyNameFromVarFunction[token, pos, l, tokens] 140 | ] 141 | 142 | getCustomPropertyNameFromVarFunction[token_?CSSTokenQ, pos_, l_, tokens_] := 143 | Module[{}, 144 | If[TokenTypeIsNot["function", token] || TokenStringIsNot["var", token], Return @ varFailureNotVarFunction]; 145 | 146 | (* case of var() with no arguments *) 147 | If[l == 0, Return @ varFailureNoName]; 148 | 149 | (* var() function could have leading whitespace *) 150 | If[TokenTypeIs["whitespace", tokens[[pos]]], AdvancePosAndSkipWhitespace[pos, l, tokens]]; 151 | If[pos > l, Return @ varFailureNoName]; 152 | 153 | (* next token string must start with "--" *) 154 | If[TokenTypeIs["ident", tokens[[pos]]] && StringStartsQ[tokens[[pos]]["String"], "--"], tokens[[pos]]["String"], varFailureBadName] 155 | ] 156 | 157 | parseVarFunctionToken[token_?CSSTokenQ, replacements_] := 158 | Module[{pos = 1, l, tokens, name}, 159 | tokens = token["Children"]; 160 | l = Length[tokens]; 161 | name = getCustomPropertyNameFromVarFunction[token, pos, l, tokens]; 162 | If[FailureQ[name], Return @ name]; 163 | 164 | (* ==== check for fallback syntax, which could still lead to a failure ==== *) 165 | 166 | AdvancePosAndSkipWhitespace[pos, l, tokens]; 167 | 168 | (* if nothing but whitespace remains, then the value is good to go *) 169 | If[(pos > l) || (pos == l && TokenTypeIs["whitespace", tokens[[pos]]]), 170 | If[MemberQ[replacements[[All, 1]], name], 171 | Return @ CSSTokenize[name /. replacements] 172 | , 173 | Return @ varFailureNoDefinition[name] 174 | ] 175 | ]; 176 | 177 | (* comma must be present for a fallback to exist *) 178 | If[TokenTypeIsNot["comma", tokens[[pos]]], Return @ varFailureNoComma]; 179 | pos++; (* everything after the comma is valid, even whitespace tokens *) 180 | If[MemberQ[replacements[[All, 1]], name], 181 | CSSTokenize[name /. replacements] 182 | , 183 | If[pos > l, Nothing, tokens[[pos ;; ]]] 184 | ] 185 | ] 186 | 187 | 188 | (* ========== var() function substitution ========== *) 189 | customPropertyRelationshipGraph[replacements:{Rule[_?StringQ, _?StringQ]...}] := 190 | Module[{reps, newRules}, 191 | (* find all var() token instances in the custom property replacement rules; get the names; ignore Failures as these should be removed during other parsing *) 192 | reps = CSSTokenize /@ replacements[[All, 2]]; 193 | newRules = Map[getCustomPropertyNameFromVarFunction, Extract[#, Position[#, TokenPatternString["var", "function"]]]]& /@ reps; 194 | newRules = 195 | With[{choices = FreeQ[#, Failure]& /@ newRules}, 196 | Flatten[Thread /@ Thread[Rule[Pick[replacements[[All, 1]], choices], Pick[newRules, choices]]]]]; 197 | Graph[newRules] 198 | ] 199 | 200 | 201 | (* check for recursive definitions; return cycles/self-loops if any found *) 202 | customPropertyDefinitionCycles[replacements:{Rule[_?StringQ, _?StringQ]...}] := 203 | Module[{g}, 204 | (* make a graph and check for looping structures *) 205 | g = customPropertyRelationshipGraph[replacements]; 206 | Join[(*cycles*)FindCycle[g, Infinity, All], (*self loops*)EdgeList[g, _?(#[[1]] === #[[2]]&)]] 207 | ] 208 | 209 | replaceVarFunctionWithTokens[tokensInput:{__?CSSTokenQ}, replacements_] := 210 | Module[{cycles, tokens = tokensInput, varPosition, varToken, varCheck, name, l}, 211 | (* get any cyclic dependencies in the replacement rules *) 212 | cycles = customPropertyDefinitionCycles[replacements]; 213 | 214 | (* replace var() from the deepest instance to the most shallow and check for failures at each step *) 215 | (* Position is sorted depth-first, which is good because we should substitute the deepest var() instances first. *) 216 | varPosition = FirstPosition[tokens, TokenPatternString["var", "function"], None]; 217 | l = Length[tokens]; 218 | While[varPosition =!= None && l < 10^6, 219 | varToken = Extract[tokens, varPosition]; 220 | 221 | (* check for recursion *) 222 | name = getCustomPropertyNameFromVarFunction[varToken]; 223 | If[!FreeQ[cycles, name], Throw @ varFailureRecursion[Pick[cycles, !FreeQ[#, name]& /@ cycles]]]; 224 | 225 | (* do token replacement *) 226 | varCheck = parseVarFunctionToken[varToken, replacements]; 227 | If[FailureQ[varCheck], Throw @ varCheck, tokens = ReplacePart[tokens, varPosition -> Unevaluated[Sequence @@ varCheck]]]; 228 | varPosition = FirstPosition[tokens, TokenPatternString["var", "function"], None]; 229 | l = Length[tokens]; 230 | ]; 231 | tokens //. HoldPattern[{a___, Sequence[b__], c___}] :> {a, b, c} (* flatten any Sequence held within Association *) 232 | ] 233 | 234 | 235 | (* ================= CSSCustomPropertyDefinition replacement if they contain other functions ================= *) 236 | (* 237 | CSS is almost frustratingly flexible. A CSS custom property declaration e.g. --varName:varValue can itself have 238 | other resolvable functions in its property value. Moreover, @media declarations can re-define the property 239 | based on some condition. So what do we do? 240 | 241 | We need to resolve the property definitions before we can substitute them elsewhere in the CSS. 242 | 243 | Resolving calc() and attr() (from CSSValuesAndUnits) is relatively simple to do in comparison to resolving other var() functions. 244 | Recall that var() functions can contain dependencies that could lead to infinite recursion. Thus, we create 245 | a dependency graph and check it for loops. If no loops exist, then the substitution order is determined by 246 | following the directed graph. 247 | 248 | If there are multiple property declarations with the same property name (recall the prop name is case sensitive), 249 | then we follow each definition as it makes substitutions into subsequent custom properties. Any conditions on 250 | said definition are joined with any other conditions that are encountered along the way. 251 | 252 | In a sense we have a multi-verse scenario: any custom property definition is resolved to its logical conclusion, 253 | but there could be many such conclusions. After each branch in the chain is fully resolved, we merge them all 254 | back together. It often ends up duplicating the custom property definitions, but each one is also often unique in its 255 | stated conditions. Even if there is no uniqueness of condition, the cascade-order has not been affected by the duplications, 256 | so the correct value can be found by assembling all definitions together with their conditions. 257 | 258 | Assembling duplicate props with conditions is normally handled by CSSTools`CSSStyleSheetInterpreter`Private`assembleWithConditions. 259 | 260 | There are further consequences to this approach. Now that we have duplicate custom properties with varying conditions, 261 | any substitution into a var() function will ultimately pass those conditions on. This bloat will slow down the FE 262 | as it attempts to resolve all the conditions, but that is the world we live in. In practice it is better to work with 263 | "simplified" CSS in that all media conditions have first been excised before running CSSCascade or CSSInheritance. 264 | *) 265 | Options[resolveCSSCustomPropertyDefinition] = {"IgnoreSpecificity" -> False, "IgnoreImportance" -> False, "PropertyIsCaseSensitive" -> False}; 266 | resolveCSSCustomPropertyDefinition[CSSDataSubset_, scope_, opts:OptionsPattern[]] := 267 | Module[{replacements, cycles, localSubset = CSSDataSubset, graph, customProp, localDecs, propLoop, result, tmp, pos}, 268 | (* check for dependency loops. Remove any dependent properties, but issue a warning. *) 269 | replacements = getAllVarReplacementRules[localSubset]; 270 | graph = Graph[customPropertyRelationshipGraph[replacements], VertexLabels -> Automatic]; 271 | cycles = Join[(*cycles*)FindCycle[graph, Infinity, All], (*self loops*)EdgeList[graph, _?(#[[1]] === #[[2]]&)]]; 272 | If[cycles =!= {}, Echo[varFailureRecursion /@ cycles, "CSS custom property recursion detected:"]]; 273 | Do[ 274 | If[!ListQ[cycles[[i]]], cycles[[i]] = {cycles[[i]]}]; 275 | pos = Position[localSubset, KeyValuePattern[{"Property" -> Alternatives @@ cycles[[i]][[All, 1]]}]]; 276 | Do[localSubset[[Sequence @@ j]] = <|localSubset[[Sequence @@ j]], "Interpretation" -> varFailureRecursion[cycles[[i]]]|>, {j, pos}] 277 | , 278 | {i, 1, Length[cycles], 1} 279 | ]; 280 | replacements = getAllVarReplacementRules[localSubset]; 281 | graph = Graph[customPropertyRelationshipGraph[replacements], VertexLabels -> Automatic]; 282 | 283 | (* Which property should we evaluate first? Assuming there's no dependency loops, start with the property that is the source of all others *) 284 | customProp = First[Pick[VertexList[graph], 0 === #& /@ VertexOutDegree[graph]], None]; 285 | 286 | (* get all cascade-ordered declarations, remove ones with parse failures *) 287 | localDecs = CSSTools`CSSStyleSheetInterpreter`Private`cssCascadeDeclarations[scope, localSubset, All, opts]; 288 | localDecs = DeleteCases[localDecs, KeyValuePattern[{"Interpretation" -> _?FailureQ}]]; 289 | 290 | (* tokenize CSSCustomPropertyDefinition instances and add tokens as a new key *) 291 | Do[ 292 | tmp = localDecs[[i]]; 293 | If[AssociationQ[tmp["Interpretation"]] && KeyExistsQ[tmp["Interpretation"], "CSSCustomPropertyDefinition"], 294 | AssociateTo[tmp["Interpretation", "CSSCustomPropertyDefinition"], "Tokens" -> CSSTokenize[tmp["Value"]]]]; 295 | localDecs[[i]] = tmp 296 | , 297 | {i, Length[localDecs]}]; 298 | 299 | (* 300 | If there are multiple prop definitions, then we need to follow each to its end state. 301 | This could incur recursive function calls, which is OK as each duplication makes a same-length copy of the declarations. 302 | To keep cascade-ordering, transpose all same-length "chains" together and delete duplicate declarations. *) 303 | propLoop = Flatten @ Position[localDecs, KeyValuePattern[{"Property" -> customProp}], {1}]; 304 | Do[localDecs[[i]] = reduceDeclarationWithoutVar[localDecs[[i]]], {i, propLoop}]; 305 | If[propLoop === {}, 306 | result = localDecs 307 | , 308 | result = followChainToEnd[graph, localDecs, #]& /@ propLoop; 309 | result = Transpose[result] // Flatten // DeleteDuplicates; 310 | ]; 311 | 312 | (* clean up any modifications made to the declarations in the scope of this function *) 313 | Do[ 314 | If[AssociationQ[result[[i, "Interpretation"]]] && KeyExistsQ[result[[i, "Interpretation"]], "CSSCustomPropertyDefinition"], 315 | tmp = CSSUntokenize @ result[[i, "Interpretation", "CSSCustomPropertyDefinition", "Tokens"]]; 316 | result[[i, "Interpretation", "CSSCustomPropertyDefinition", "Value"]] = tmp; 317 | result[[i, "Value"]] = tmp; 318 | ] 319 | , 320 | {i, Length[result]}]; 321 | Do[ 322 | If[ListQ[result[[i, "Condition"]]], 323 | result[[i, "Condition"]] = 324 | Replace[ 325 | Thread[DeleteCases[result[[i, "Condition"]], None], Hold], 326 | { 327 | Hold[{x___}] :> If[Length[{x}] > 1, Hold[And[x]], Hold[x]], 328 | {} -> None}]] 329 | , 330 | {i, Length[result]}]; 331 | tmp = Select[result, AssociationQ[#Interpretation] && KeyExistsQ[#Interpretation, "CSSCustomPropertyDefinition"]&]; 332 | {result, <| 333 | "Property" -> #["Interpretation", "CSSCustomPropertyDefinition", "Name"], 334 | "Value" -> #["Interpretation", "CSSCustomPropertyDefinition", "Value"], 335 | "Condition" -> #Condition|> & /@ tmp} 336 | ] 337 | 338 | getAllVarReplacementRules[CSSDataSubset_] := 339 | Module[{customPropertyDefinitions}, 340 | customPropertyDefinitions = Flatten[CSSDataSubset[[All, "Block"]]][[All, "Interpretation"]]; 341 | customPropertyDefinitions = Pick[customPropertyDefinitions, (AssociationQ[#] && KeyExistsQ[#, "CSSCustomPropertyDefinition"])& /@ customPropertyDefinitions]; 342 | (#Name -> #Value)& /@ Flatten @ Values @ customPropertyDefinitions 343 | ] 344 | 345 | followChainToEnd[currentGraph_Graph, currentDeclarations_, propPosition_] := 346 | Module[{replaceParts, localDecs = currentDeclarations, replaceLoop, parts, graph = currentGraph, customProp, propLoop = {}, tokens, result = currentDeclarations}, 347 | customProp = localDecs[[propPosition]]["Property"]; 348 | 349 | (* 350 | Find positions where we need to replace the custom prop with new values. 351 | Each declaration may call the same var() function multiple times, so group them under the same declaration index. *) 352 | replaceParts = 353 | GroupBy[ 354 | Position[ 355 | localDecs, 356 | Condition[ 357 | CSSToken[KeyValuePattern[{"Type" -> "function", "String" -> s_?StringQ /; StringMatchQ[s, "var", IgnoreCase -> True], "Children" -> c_}]], 358 | Position[c, CSSToken[KeyValuePattern[{"Type" -> "ident", "String" -> customProp}]]] =!= {}]], 359 | First -> Rest]; 360 | 361 | (* 362 | Only continue down the chain if there's a valid substitution to make. 363 | If at any time we detect that no more var() functions appear in the property value, reduce all other calc() and attr() functions. *) 364 | If[replaceParts =!= <||>, 365 | (* reduce property value if no var() functions are found in its value *) 366 | localDecs[[propPosition]] = reduceDeclarationWithoutVar[localDecs[[propPosition]]]; 367 | 368 | replaceLoop = Keys[replaceParts]; 369 | tokens = localDecs[[propPosition, "Interpretation", "CSSCustomPropertyDefinition", "Tokens"]]; 370 | 371 | (* every substitution location gets replaced by the same token sequence *) 372 | parts = 373 | Table[ 374 | reduceDeclarationWithoutVar[ 375 | ReplacePart[localDecs[[replaceLoopIndex]], 376 | Join[ 377 | {{Key["Condition"]} -> combineConditions[localDecs[[replaceLoopIndex, "Condition"]], localDecs[[propPosition, "Condition"]]]}, 378 | Thread[replaceParts[replaceLoopIndex] -> Unevaluated @ Sequence @@ tokens]] 379 | ] //. HoldPattern[{a___, Sequence[b__], c___}] :> {a, b, c}] 380 | , 381 | {replaceLoopIndex, replaceLoop}]; 382 | localDecs = Flatten @ ReplacePart[localDecs, Thread[replaceLoop -> parts]]; 383 | 384 | (* move backwards along the custom prop replacement graph *) 385 | graph = VertexDelete[graph, customProp]; 386 | customProp = First[Pick[VertexList[graph], 0 === #& /@ VertexOutDegree[graph]], None]; 387 | propLoop = Flatten @ Position[localDecs, KeyValuePattern[{"Property" -> customProp}], {1}]; 388 | Do[localDecs[[i]] = reduceDeclarationWithoutVar[localDecs[[i]]], {i, propLoop}]; 389 | 390 | (* recursively continue this process until reaching the end of the chain *) 391 | result = followChainToEnd[graph, localDecs, #]& /@ propLoop; 392 | result = Transpose[result] // Flatten // DeleteDuplicates; 393 | ]; 394 | result 395 | ] 396 | 397 | reduceDeclarationWithoutVar[dec_?AssociationQ] := 398 | Module[{d = dec, funcPositions, token, try}, 399 | If[Position[d, t_?CSSTokenQ /; TokenStringIs["var", t]] === {}, 400 | funcPositions = Position[d, t_?CSSTokenQ /; TokenStringIs["attr" | "calc", t]]; 401 | Do[ 402 | token = Extract[d, funcPos]; 403 | try = Catch @ 404 | Which[ 405 | TokenStringIs["calc", token], CSSTools`CSSValuesAndUnits3`Private`replaceCalcFunctionsWithTokens[{token}, "prop"], 406 | TokenStringIs["attr", token], CSSTools`CSSValuesAndUnits3`Private`replaceAttrFunctionsWithTokens[{token}, d["Element"], d["Interpretation", "CustomPropertyDefinition", "Namespaces"]], 407 | True, Failure["BadParse", <|"MessageTemplate" -> "Could not find expected function token."|>] 408 | ]; 409 | If[FailureQ[try], 410 | d["Interpretation"] = try 411 | , 412 | d = ReplacePart[d, funcPos -> Unevaluated[Sequence @@ try]] //. HoldPattern[{a___, Sequence[b__], c___}] :> {a, b, c} 413 | ] 414 | , 415 | {funcPos, funcPositions}] 416 | ]; 417 | d 418 | ] 419 | 420 | combineConditions[cOld_, cAdd_] := DeleteDuplicates @ Sort @ Flatten @ {cOld, cAdd} 421 | 422 | 423 | End[] (* End Private Context *) 424 | 425 | EndPackage[] -------------------------------------------------------------------------------- /CSSTools/Kernel/CSSTools.m: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | (* ::Title:: *) 4 | (*CSS Visual Style Importer*) 5 | 6 | 7 | (* ::Text:: *) 8 | (*Author: Kevin Daily*) 9 | (*Date: 20200716*) 10 | (*Version: 1.3.1*) 11 | 12 | 13 | BeginPackage["CSSTools`"] 14 | (* Exported symbols added here with SymbolName::usage *) 15 | 16 | Needs["GeneralUtilities`"]; (* for SetUsage *) 17 | 18 | Unprotect["CSSTools`*"] 19 | 20 | (* ==== CSSStyleSheetInterpreter` ==== *) 21 | SetUsage[CSSCascade, "\ 22 | CSSCascade[CSSProperty$, type$, CSSData$, CSSSelectorFilter$] combines options that were interpreted from the CSS importer. \ 23 | CSS declarations are merged following the CSS cascade and the resulting options are filtered by type$."]; 24 | 25 | SetUsage[ExtractCSSFromXML, "\ 26 | ExtractCSSFromXML[XMLObject$] imports the CSS declarations within XMLObject$."]; 27 | 28 | SetUsage[CSSSubjects, "\ 29 | CSSSubjects[XMLObject$, CSSData$] applies the CSSData$ to the symbolic XML, returning the CSSData$ with the subjects of the selectors."]; 30 | 31 | SetUsage[CSSInheritance, "\ 32 | CSSInheritance[CSSSubject$, type$, CSSData$] calculates the properties of the CSSSubject$ including any inherited CSS properties."]; 33 | 34 | (* ==== Selectors3` ==== *) 35 | SetUsage[CSSSelector, "\ 36 | CSSSelector[string$] parses string$ as a CSS selector. If valid it returns a CSSSelector object."]; 37 | 38 | SetUsage[CSSSelectorQ, "\ 39 | CSSSelectorQ[CSSSelector$] returns True if CSSSelector$ is a valid CSSSelector object."]; 40 | 41 | SetUsage[CSSSubject, "\ 42 | CSSSubject[string$] parses string$ as the XML object that is the subject of a CSS selector. If valid it returns a CSSSubject object."]; 43 | 44 | SetUsage[CSSSubjectQ, "\ 45 | CSSSubjectQ[CSSSubject$] returns True if CSSSubject$ is a valid CSSSubject object."]; 46 | 47 | (* === CSSImages3` === *) 48 | SetUsage[CSSLinearGradientImage, "\ 49 | CSSLinearGradientImage[{{pos$1, color$1}, {pos$2, color$2}, $$}] returns an image with values linearly changing from top to bottom following the CSS specification for color stops. 50 | CSSLinearGradientImage[{{pos$1, color$1}, {pos$2, color$2}, $$}, direction$] returns an image where the gradient points along direction$. 51 | CSSLinearGradientImage[$$, size$] returns a linear gradient image of the specified size$."]; 52 | 53 | SetUsage[CSSRadialGradientImage, "\ 54 | CSSRadialGradientImage[{{pos$1, color$1}, {pos$2, color$2}, $$}] returns an image with values linearly changing from the center to corners following the CSS specification for color stops. 55 | CSSRadialGradientImage[{{pos$1, color$1}, {pos$2, color$2}, $$}, startPosition$] returns an image where the gradient center is located at startPosition$. 56 | CSSRadialGradientImage[$$, size$] returns a radial gradient image of the specified size$."]; 57 | 58 | (* ==== required System` functions ==== *) 59 | System`CellFrameStyle; 60 | System`Box; 61 | 62 | (* ==== load base packages ==== *) 63 | Get["CSSTools`CSSSelectors3`"] (* defines CSSSelector object *) 64 | Get["CSSTools`CSSPropertyInterpreter`"] (* needs to be loaded first to define basic CSS 2.1 properties *) 65 | Get["CSSTools`CSSStyleSheetInterpreter`"] (* defines basic stylesheet token consumers and CSS cascade *) 66 | 67 | (* ==== load upgrade packages ==== *) 68 | Get["CSSTools`CSSColors4`"]; (* redefines parseSingleColor (first defined in CSSPropertyInterpreter) *) 69 | Get["CSSTools`CSSPagedMedia3`"] (* redefines @page token consumer (first defined in CSSStyleSheetInterpreter) *) 70 | Get["CSSTools`CSSMediaQueries4`"] (* redefines consumeMediaQuery (first defined in CSSStyleSheetInterpreter) *) 71 | Get["CSSTools`SVG11`"] (* adds consumeProperty definitions for SVG 1.1 *) 72 | Get["CSSTools`CSSValuesAndUnits3`"] (* prepends consumeProperty definitions for values that contain attr() and calc() functions *) 73 | Get["CSSTools`CSSCustomProperties1`"] (* prepends consumeProperty definitions for custom properties i.e. --* idents, and var() function *) 74 | Get["CSSTools`CSSImages3`"] (* defines gradient images *) 75 | 76 | 77 | Begin["`Private`"] 78 | 79 | ImportExport`RegisterImport[ 80 | "CSS", 81 | { 82 | "Elements" :> (("Elements" -> {"RawData", "Interpreted", "Stylesheet"})&), 83 | (* Interpreted is the same as default *) 84 | "Interpreted" :> (("Interpreted" -> With[{d = CSSTools`CSSStyleSheetInterpreter`Private`InterpretedCSS[#]}, If[FailureQ[d], d, Dataset @ d]])&), 85 | "RawData" :> (("RawData" -> With[{d = CSSTools`CSSStyleSheetInterpreter`Private`RawCSS[#]}, If[FailureQ[d], d, Dataset @ d]])&), 86 | "Stylesheet" :> (("Stylesheet" -> CSSTools`CSSStyleSheetInterpreter`Private`ProcessToStylesheet[#])&), 87 | ((With[{d = CSSTools`CSSStyleSheetInterpreter`Private`InterpretedCSS[#]}, If[FailureQ[d], d, Dataset @ d]])&)}, 88 | {}, 89 | "AvailableElements" -> {"Elements", "RawData", "Interpreted", "Stylesheet"}] 90 | 91 | End[] 92 | 93 | 94 | SetAttributes[ 95 | { 96 | CSSCascade, ExtractCSSFromXML, CSSSubjects, CSSInheritance, 97 | CSSSelector, CSSSelectorQ, CSSSubject, CSSSubjectQ, 98 | CSSLinearGradientImage, CSSRadialGradientImage}, 99 | {Protected, ReadProtected}]; 100 | 101 | 102 | EndPackage[] 103 | 104 | -------------------------------------------------------------------------------- /CSSTools/PacletInfo.m: -------------------------------------------------------------------------------- 1 | (* Paclet Info File *) 2 | 3 | (* created 2020/07/16*) 4 | 5 | Paclet[ 6 | Name -> "CSSTools", 7 | Version -> "1.3.1", 8 | MathematicaVersion -> "11+", 9 | Description -> "Import and process CSS into Wolfram Language options.", 10 | Creator -> "Kevin Daily", 11 | Extensions -> 12 | { 13 | {"Documentation", Language -> "English"}, 14 | {"Kernel", Root -> "Kernel", Context -> "CSSTools`"} 15 | } 16 | ] 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSS Tools for Wolfram Language 2 | 3 | [![View notebooks](https://wolfr.am/HAAhzkRq)](https://wolfr.am/O7pBpV8s) 4 | 5 | CSSTools is a package for importing [CSS](https://www.w3.org/Style/CSS/) files into the [Wolfram Language](https://www.wolfram.com/language/). CSSTools supports 11.0 and later versions of Wolfram Language deployments for the desktop, including [Wolfram Desktop](https://www.wolfram.com/desktop/) and [Mathematica](https://www.wolfram.com/mathematica/). 6 | 7 | The initial release of CSSTools contains the core [CSS Level 2 Revision 1](https://www.w3.org/TR/CSS2/) specification. The tokenizer follows the [CSS Syntax Module Level 3](https://www.w3.org/TR/css-syntax-3/) specification and the selectors follow [Selectors Level 3](https://www.w3.org/TR/selectors-3/). Additional supported modules include: 8 | * [CSS Namespaces Module Level 3](https://www.w3.org/TR/css-namespaces-3/) 9 | * [CSS Colors Module Level 4](https://www.w3.org/TR/css-color-4/) 10 | * [CSS Media Queries Level 4](https://www.w3.org/TR/mediaqueries-4/) 11 | * [CSS Custom Properties for Cascading Variables Module Level 1](https://drafts.csswg.org/css-variables/) 12 | * [CSS Values and Units Module Level 3](https://www.w3.org/TR/css-values-3/) 13 | * [CSS Images Module Level 3](https://drafts.csswg.org/css-images-3) 14 | 15 | The Wolfram Desktop front end uses its own stylesheet system and translation from CSS to Wolfram Desktop is not one-to-one. Regardless, the goal is to conform with all included specifications as much as possible. The listed modules indicate which CSS properties can be validated while importing into Wolfram Desktop. Though the properties can be validated and imported, not all imported CSS properties have a corresponding option in the Wolfram Desktop front end. 16 | 17 | ### Installing the CSSTools release 18 | 19 | The CSSTools release comes in the form of a `.paclet` file, which contains the entire package and its documentation. Download the latest release from [this latest release link](https://github.com/WolframResearch/CSSTools/releases/latest/download/CSSTools-1.3.1.paclet). To install, run the following command in the Wolfram Language: 20 | ``` 21 | PacletInstall["/full/path/to/CSSTools.paclet"] 22 | ``` 23 | This will permanently install the CSSTools paclet. The Wolfram Language will always use the latest installed version of CSSTools. Installed versions can be enumerated using the command: 24 | ``` 25 | PacletFind["CSSTools"] 26 | ``` 27 | And all versions can be uninstalled using the command: 28 | ``` 29 | PacletUninstall["CSSTools"] 30 | ``` 31 | 32 | ### Using CSSTools 33 | 34 | To access the documentation, open the notebook interface help viewer and search for CSSTools. The two results will be a guide page enumerating the most commonly used functions in CSSTools, and a detailed tutorial. 35 | 36 | To start, load the CSSTools package and try importing some basic CSS rules. 37 | ``` 38 | Needs["CSSTools`"] 39 | cssData = ImportString["h1 {font-size:14pt; color:red}", "CSS"] 40 | ``` 41 | The result is a `Dataset` expression that matches a canonical layout of a CSS file with additional interpretations. Use the `CSSCascade` function to perform the CSS cascade algorithm and translate the imported CSS to Wolfram Desktop options. 42 | ``` 43 | CSSCascade[All (*all properties*), Cell (*as cell-level options*), cssData, All (*all rulesets*)] 44 | ``` 45 | More details can be found in the included documentation. 46 | 47 | 48 | ### Where did this come from? 49 | 50 | CSSTools is a paclet maintained by [Kevin Daily](https://github.com/KMDaily) of Wolfram Research. He began building CSSTools because he thought it would be neat to use the CSS stylesheet language in Wolfram Desktop. He did not realize how hard it would be to translate CSS to Wolfram Desktop options including the multitude of additional CSS modules that must all work together. 51 | 52 | CSSTools is implemented completely in the Wolfram Language. It might have been better suited to build off of an existing library, but none were found that exactly matched the translations that were needed to match Wolfram Language code. 53 | 54 | ### ...and where's it going? 55 | 56 | The hope is for CSSTools to be further developed by community support. Using the tokenizer and its related functions, additional properties should be straightforward to add to the package. Some CSS features that would be nice to see are vendor-specific properties added as recognizable properties. More ambitious additions would be animation rules. 57 | 58 | ### More... 59 | 60 | See the following files for more information: 61 | 62 | * [[video](https://www.wolfram.com/broadcast/video.php?v=2842)] [[notebook](https://files.wolframcdn.com/pub/www.wolfram.com/technology-conference/2019/Tuesday/2019KevinDailyCSSImport.nb)] Wolfram Technology Conference 2019 Presentation 63 | * [COPYING.md](ReadMeFiles/COPYING.md) - CSSTools license 64 | * [CONTRIBUTING.md](ReadMeFiles/CONTRIBUTING.md) - Guidelines for contributing to CSSTools 65 | * [ForDevelopers.md](ReadMeFiles/ForDevelopers.md) - Walkthrough of how to contribute new features to CSSTools 66 | * [HowToBuild.md](ReadMeFiles/HowToBuild.md) - Instructions for building CSSTools as a paclet 67 | -------------------------------------------------------------------------------- /ReadMeFiles/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Wolfram® 2 | 3 | Thank you for taking the time to contribute to the [Wolfram Research](https://github.com/wolframresearch) repos on GitHub. 4 | 5 | ## Licensing of Contributions 6 | 7 | By contributing to Wolfram, you agree and affirm that: 8 | 9 | > Wolfram may release your contribution under the terms of the [MIT license](https://opensource.org/licenses/MIT); and 10 | 11 | > You have read and agreed to the [Developer Certificate of Origin](http://developercertificate.org/), version 1.1 or later. 12 | 13 | Please see [COPYING.md](ReadMeFiles/COPYING.md) for licensing conditions pertaining 14 | to individual repositories. 15 | 16 | 17 | ## Bug reports 18 | 19 | ### Security Bugs 20 | 21 | Please **DO NOT** file a public issue regarding a security issue. 22 | Rather, send your report privately to security@wolfram.com. Security 23 | reports are appreciated and we will credit you for it. We do not offer 24 | a security bounty, but the forecast in your neighborhood will be cloudy 25 | with a chance of Wolfram schwag! 26 | 27 | ### General Bugs 28 | 29 | Please use the repository issues page to submit general bug issues. 30 | 31 | Please do not duplicate issues. 32 | 33 | Please do send a complete and well-written report to us. Note: **the 34 | thoroughness of your report will positively correlate to our willingness 35 | and ability to address it**. 36 | 37 | When reporting issues, always include: 38 | 39 | * Your version of *Mathematica*® or the Wolfram Language. 40 | * Your operating system. 41 | * The version of the CSSTools paclet. -------------------------------------------------------------------------------- /ReadMeFiles/COPYING.md: -------------------------------------------------------------------------------- 1 | CSSTools is Copyright (C) 2019, Wolfram Research, Inc. 2 | 3 | --- 4 | 5 | [![Create Commons License](https://i.creativecommons.org/l/by-nc/4.0/88x31.png)](http://creativecommons.org/licenses/by-nc/4.0/) 6 | 7 | 8 | This work is licensed under a [Creative Commons Attribution-NonCommercial 4.0 International License](http://creativecommons.org/licenses/by-nc/4.0/). 9 | -------------------------------------------------------------------------------- /ReadMeFiles/ForDevelopers.md: -------------------------------------------------------------------------------- 1 | # Contributing to CSSTools 2 | 3 | ## Table of Contents 4 | 5 | [Overview](#overview) 6 | 7 | [Details of the tokenizer](#details-of-the-tokenizer) 8 | 9 | [Example of Modifying an Existing Parser](#example-of-modifying-an-existing-parser) 10 | 11 | [Example of Adding a New Property](#example-of-adding-a-new-property) 12 | 13 | 14 | ## Overview 15 | 16 | CSSTools consists of packages that are designed to follow CSS module organization. The core packages include: 17 | 18 | | File | Description | 19 | | --------------------------- | ----------- | 20 | | CSSTokenizer.wl | converts strings into CSS tokens; contains utilities for processing CSS tokens | 21 | | CSSPropretyInterpreter.wl | contains all CSS Level 2 Revision 1 properties and how they are translated to Wolfram Desktop options | 22 | | CSSStyleSheetInterpreter.wl | parsing of a CSS stylesheet and assembly of interpreted Wolfram Desktop options | 23 | | CSSSelectors3.wl | defines CSSSelector following CSS Selectors Level 3 | 24 | 25 | Additional packages are named after the corresponding CSS module. They are intended to modify existing functionality within the core packages. 26 | 27 | The tokenizer is described below. The other three files are always loaded first in order to define the core functionality. Additional packages are loaded after the core set. These additional packages modify or add to the core functions. 28 | 29 | 30 | ## Details of the tokenizer 31 | 32 | The tokenizer follows [CSS Syntax Module Level 3](https://www.w3.org/TR/css-syntax-3/). One noteworthy feature of this syntax is that "ident" tokens are allowed to start with two dashes "--" which allows for custom variables. See [CSS Custom Properties for Cascading Variables Module Level 1](https://www.w3.org/TR/css-variables-1/) for more details. An implemented extensions to this level 3 syntax, though not a standard CSS features, is that URLs can includes [URL modifiers](https://www.w3.org/TR/css-values-3/#url-modifiers). 33 | 34 | The tokenizer also does a small amount of parsing. In particular, brackets like `[]`, `{}` and `()` are matched into block tokens. These block tokens have a key "Children" whose value is a flat list of CSS tokens that are within the scope of the block. 35 | 36 | The tokenizer is not loaded when CSSTools loads but can be accessed via 37 | ``` 38 | Needs["CSSTools`CSSTokenizer`"] 39 | ``` 40 | There are two functions that provide the tokenizing and the serialization: `CSSTokenize` and `CSSUntokenize`. `CSSTokenize` operates on a string and creates a flat list of tokens. Individual tokens have the head `CSSToken` and contain a single argument: an association that indicates their structure. For example: 41 | ``` 42 | In[] := tokens = CSSTokenize["h1 {color:\\red}"] 43 | Out[] = { 44 | CSSToken[<|"Type" -> "ident", "String" -> "h1"|>], 45 | CSSToken[<|"Type" -> "whitespace", "String" -> " "|>], 46 | CSSToken[<|"Type" -> "{}", "Children" -> { 47 | CSSToken[<|"Type" -> "ident", "String" -> "color"|>], 48 | CSSToken[<|"Type" -> "colon", "String" -> ":"|>], 49 | CSSToken[<|"Type" -> "ident", "String" -> "\\red"|>]}|>]} 50 | ``` 51 | The `"String"` key stores the unmodified original string. The exception is whitespace which is always normalized to a single space. The tokenizer package provides functions like `CSSNormalizeEscapes` to help process non-standard token strings. 52 | 53 | Use `CSSUntokenize` to serialize the tokens back into a string: 54 | ``` 55 | In[] := CSSUntokenize[tokens] 56 | Out[] = "h1 {color:\\red}" 57 | ``` 58 | Following the CSS syntax module specification, a round-trip of `CSSUntokenize[CSSTokenize[...]` is not guaranteed to return the same initial string. The reason is that some characters like whitespace can be simplified without loss of information. However, token sequences must round-trip. Said differently, `CSSTokenize[CSSUntokenize[CSSTokenize[...]]` must be the same as the original set of tokens. 59 | ``` 60 | In[] := tokens === CSSTokenize[CSSUntokenize[tokens]] 61 | Out[] = True 62 | ``` 63 | To assist parsing of tokens, functions like `CSSTokenQ`, `TokenTypeIs` and `AdvancePosAndSkipWhitespace` exist in the CSSTokenizer.wl package. Starting with the above token sequence, we can move along the sequence like so: 64 | ``` 65 | In[] := pos = 1; t = tokens[[pos]]; 66 | 67 | In[] := CSSTokenQ[t] 68 | Out[] = True 69 | 70 | In[] := If[TokenTypeIs["ident", t], AdvancePosAndSkipWhitespace[pos, Length[tokens], tokens]] 71 | 72 | In[] := pos 73 | Out[] = 3 74 | ``` 75 | The `pos` variable tracks the position along the token sequence. At each position the token can be checked for correctness and processed accordingly. More details can be found in the CSSTokenizer.wl package. 76 | 77 | For the curious, the tokenizer has been validated using a number of unit tests. They can be found in this repo under Testing/RunTests.wl. 78 | 79 | 80 | [Back to top](#table-of-contents) 81 | 82 | 83 | ## Example of Modifying an Existing Parser 84 | 85 | The color definitions from CSS Level 2 Revision 1 are limited in comparison with Colors Module Level 4. We extend its definitions by creating a new package: "CSSColors4.wl". Its functionality is extended by following these steps: 86 | 87 | 1. The parser function `parseSingleColor` defined in CSSPropretyInterpreter.wl is made public by moving its name before the ``Begin["`Private`"]`` section. 88 | 89 | _Start of CSSPropretyInterpreter.wl_ 90 | 91 | (* Wolfram Language Package *) 92 | 93 | BeginPackage["CSSTools`CSSPropertyInterpreter`", {"CSSTools`"}] 94 | 95 | Needs["CSSTools`CSSTokenizer`"]; (* keep tokenizer utilities hidden *) 96 | 97 | (* functions to expose to outside packages via Needs *) 98 | ... 99 | (*STEP 1*)parseSingleColor; 100 | CSSPropertyData; 101 | ... 102 | 103 | Begin["`Private`"] (* Begin Private Context *) 104 | ... 105 | 106 | 2. Create a new package CSSColors4.wl where in this new package 107 | 108 | A. keep the context within CSSTools 109 | 110 | B. load the tokenizer as we will be processing CSS tokens 111 | 112 | C. load the property interpreter to modify `parseSingleColor`: 113 | 114 | _Start of CSSColors4.wl_ 115 | 116 | (* Wolfram Language Package *) 117 | 118 | BeginPackage["CSSTools`CSSColors4`", {(*STEP 2A*)"CSSTools`"}]; 119 | 120 | (*STEP 2B*) Needs["CSSTools`CSSTokenizer`"]; 121 | (*STEP 2C*) Needs["CSSTools`CSSPropertyInterpreter`"]; 122 | 123 | Begin["`Private`"]; (* Begin Private Context *) 124 | ... 125 | 126 | 3. Create new private functions that extend the functionality. 127 | 128 | _Somewhere within CSSColors4.wl after ``Begin["`Private`"]``_ 129 | 130 | ... 131 | parseSingleColorKeyWord[prop_String, keyword_String] := ... 132 | ... 133 | parseSingleColorHex[prop_String, hexString_String] := ... 134 | ... 135 | parseSingleColorFunction[prop_String, token_?CSSTokenQ] := ... 136 | ... 137 | 138 | 4. Modify as necessary existing functions such as the `CSSPropertyData` (also publicly exposed): 139 | 140 | _Somewhere within CSSColors4.wl after ``Begin["`Private`"]``_ 141 | 142 | ... 143 | If[!AssociationQ[CSSPropertyData], CSSPropertyData = <||>]; 144 | AssociateTo[CSSPropertyData, { (* AssociateTo is used in case the package order changes *) 145 | "color" -> <| 146 | "Inherited" -> True, 147 | "CSSInitialValue" -> "black", (* CSS 2.1 did not define this *) 148 | "InterpretedGlobalValues" -> <| 149 | "inherit" -> FontColor -> Inherited, 150 | "initial" -> FontColor -> Black|>, 151 | "Animatable" -> True, 152 | "Values" -> {""}, 153 | "AppliesTo" -> All|>}] 154 | ... 155 | 156 | 5. Add a new definition for `parseSingleColor`. 157 | 158 | _Somewhere within CSSColors4.wl after ``Begin["`Private`"]``_ 159 | 160 | ... 161 | (* new interpreters *) 162 | (* parse all color types *) 163 | parseSingleColor[prop_String, token_?CSSTokenQ] := parseSingleColor[prop, token] = 164 | Switch[token["Type"], 165 | "ident", parseSingleColorKeyWord[prop, token["String"]], 166 | "hash", parseSingleColorHex[prop, token["String"]], 167 | "function", parseSingleColorFunction[prop, token], 168 | _, unrecognizedValueFailure @ prop] 169 | ... 170 | 171 | 6. Add the package to CSSTools.m after the loading of the main packages: ``Get["CSSTools`CSSColors4`"];`` 172 | 173 | _Somewhere within CSSTools.m after defining package-scope functions_ 174 | 175 | ... 176 | (* ==== load base packages ==== *) 177 | Get["CSSTools`CSSSelectors3`"] (* defines CSSSelector object *) 178 | Get["CSSTools`CSSPropertyInterpreter`"] (* needs to be loaded first to define basic CSS 2.1 properties *) 179 | Get["CSSTools`CSSStyleSheetInterpreter`"] (* defines basic stylesheet token consumers and CSS cascade *) 180 | 181 | (* ==== load upgrade packages ==== *) 182 | (*STEP 6*)Get["CSSTools`CSSColors4`"]; (* redefines parseSingleColor (first defined in CSSPropertyInterpreter) *) 183 | Get["CSSTools`CSSPagedMedia3`"] (* redefines @page token consumer (first defined in CSSStyleSheetInterpreter) *) 184 | Get["CSSTools`CSSMediaQueries4`"] (* redefines consumeMediaQuery (first defined in CSSStyleSheetInterpreter) *) 185 | ... 186 | 187 | For the curious, the color parser has been validated using a number of unit tests. They can be found in this repo under the directory Testing/ and include files GeneralColors.wl, HSLColors.wl and NamedColors.wl. 188 | 189 | [Back to top](#table-of-contents) 190 | 191 | 192 | ## Example of Adding a New Property 193 | 194 | The [CSS Paged Media Module Level 3](https://www.w3.org/TR/css-page-3/) adds new page-specific properties 'size', 'marks', 'bleed' and 'page'. Though these printing properties are not all fully supported in the Wolfram Desktop, any new properties should still be developed to validate the input CSS. The following steps show how to add the 'bleed' property to the existing set of parsed CSS properties. 195 | 196 | 1. The parser function `consumeProperty` should already be made public in the CSSPropretyInterpreter.wl package. 197 | 198 | _Start of CSSPropretyInterpreter.wl_ 199 | 200 | (* Wolfram Language Package *) 201 | 202 | BeginPackage["CSSTools`CSSPropertyInterpreter`", {"CSSTools`"}] 203 | (* Exported symbols added here with SymbolName::usage *) 204 | 205 | Needs["CSSTools`CSSTokenizer`"]; (* keep tokenizer utilities hidden *) 206 | 207 | (* functions to expose to outside packages via Needs *) 208 | CSSPropertyData; 209 | (*STEP 1*)consumeProperty; 210 | ... 211 | 212 | Begin["`Private`"] (* Begin Private Context *) 213 | ... 214 | 215 | 2. In the sub-package (here CSSPagedMedia3.wl) create the new property consuming function. A property consumer has two arguments. The first is the property name. Though CSS is case-insensitive this first argument to the property consumer requires the canonicalized all-lower-case name. The second argument is the token sequence of the declaration's property value. Processing done within CSSStyleSheetInterpreter.wl has already trimmed any whitespace tokens. It makes processing the token sequence a little easier, such as this case, where only keywords are allowed so only one token is expected in the token sequence: 216 | 217 | _Somewhere within CSSPagedMedia3.wl_ 218 | 219 | ... 220 | consumeProperty[prop:"bleed", tokens:{__?CSSTokenQ}, opts:OptionsPattern[]] := 221 | Module[{pos = 1, l = Length[tokens], value}, 222 | If[l > 1, Return @ tooManyTokensFailure @ tokens]; 223 | value = 224 | Switch[tokens[[pos]]["Type"], 225 | "ident", 226 | Switch[CSSNormalizeEscapes @ ToLowerCase @ tokens[[pos]]["String"], 227 | "auto", Missing["Not supported."], (* Computes to 6pt if marks has crop and to zero otherwise. *) 228 | _, unrecognizedKeyWordFailure @ prop 229 | ], 230 | "dimension", parseLength @ tokens[[pos]] 231 | ]; 232 | If[FailureQ[value], value, Missing["Not supported."]] 233 | ] 234 | ... 235 | 236 | In the above code the utility functions `tooManyTokensFailure` and `parseLength` were used and come from the CSSPropretyInterpreter.wl package (publicly exposed). 237 | 238 | 3. Add to the CSSPropertyData to define the initial and inherited CSS values, as well as information on allowed data types, animatability, etc.: 239 | 240 | _Somewhere within CSSPagedMedia3.wl_ 241 | 242 | ... 243 | If[!AssociationQ[CSSPropertyData], CSSPropertyData = <||>]; 244 | AssociateTo[CSSPropertyData, 245 | { 246 | "bleed" -> <| 247 | "Inherited" -> False, 248 | "CSSInitialValue" -> "auto", 249 | "InterpretedGlobalValues" -> <| 250 | "inherit" -> <||>, (* no equivalent FE option *) 251 | "initial" -> Missing["Not supported."]|>|>}]; 252 | ... 253 | 254 | The method of parsing of new properties is largely up to the contributer, but we encourage certain features. 255 | 256 | 1. follow the existing specification 257 | 258 | 2. return a descriptive `Failure` object if parsing fails for any reason 259 | 260 | 3. return `Missing["Not supported."]` if the Wolfram Desktop front end can not currently use this feature 261 | 262 | [Back to top](#table-of-contents) -------------------------------------------------------------------------------- /ReadMeFiles/HowToBuild.md: -------------------------------------------------------------------------------- 1 | # Building CSSTools Components 2 | 3 | The CSSTools repo has two buildable components: the documentation and then the distributable paclet. 4 | 5 | ## How to build CSSTools documentation 6 | 7 | 1. [Install Eclipse and the Wolfram Workbench plug-in for Eclipse](https://support.wolfram.com/kb/27221) 8 | 2. Import the CSSTools project into Eclipse 9 | 3. Open the "Application Tools" under the menu Window > Show View > Application Tools 10 | 4. In the Application Tools window select the CSSTools project 11 | 5. Click "Build" in the documentation panel 12 | 13 | 14 | ## How to build the CSSTools paclet 15 | The paclet structure is self-contained within the project structure. The paclet is the subdirectory "CSSTools". Assuming all changes to the package files and documentation are complete: 16 | 17 | 1. Update the PacletInfo.m file's Version. 18 | If a bugfix, then add one to the 3rd decimal e.g. 1.0.1 --> 1.0.2. 19 | If a feature, then add one to the 2nd decimal e.g. 1.0.0 --> 1.1.0 20 | 2. In Mathematica 12.1 or newer run `CreatePacletArchive["/CSSTools"]`, else use `PackPaclet` instead. 21 | 3. The newly generated paclet will be in the parent location of the path in the previous step. -------------------------------------------------------------------------------- /Testing/ANB.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | (* ::Section:: *) 4 | (*ANB Sub-Grammar Tests*) 5 | 6 | 7 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- N - 1"],_Failure] 8 | 9 | 10 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ N - 1"],_Failure] 11 | 12 | 13 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n - 1"],{-1,-1}] 14 | 15 | 16 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +n - 1"],{1,-1}] 17 | 18 | 19 | Test[CSSTools`CSSSelectors3`Private`parseANB[" N - 1"],{1,-1}] 20 | 21 | 22 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 n - 1"],_Failure] 23 | 24 | 25 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1N - 1"],_Failure] 26 | 27 | 28 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14N - 1 "],_Failure] 29 | 30 | 31 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2N - 1 "],_Failure] 32 | 33 | 34 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n - 1 "],{-14,-1}] 35 | 36 | 37 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2n - 1 "],{2,-1}] 38 | 39 | 40 | Test[CSSTools`CSSSelectors3`Private`parseANB["3N - 1"],{3,-1}] 41 | 42 | 43 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- N + 1"],_Failure] 44 | 45 | 46 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ N + 1"],_Failure] 47 | 48 | 49 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -N + 1"],{-1,1}] 50 | 51 | 52 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +n + 1"],{1,1}] 53 | 54 | 55 | Test[CSSTools`CSSSelectors3`Private`parseANB[" n + 1"],{1,1}] 56 | 57 | 58 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 N + 1"],_Failure] 59 | 60 | 61 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1n + 1"],_Failure] 62 | 63 | 64 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14N + 1 "],_Failure] 65 | 66 | 67 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2n + 1 "],_Failure] 68 | 69 | 70 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n + 1 "],{-14,1}] 71 | 72 | 73 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2N + 1 "],{2,1}] 74 | 75 | 76 | Test[CSSTools`CSSSelectors3`Private`parseANB["3N + 1"],{3,1}] 77 | 78 | 79 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- N- 1"],_Failure] 80 | 81 | 82 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ n- 1"],_Failure] 83 | 84 | 85 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n- 1"],{-1,-1}] 86 | 87 | 88 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +N- 1"],{1,-1}] 89 | 90 | 91 | Test[CSSTools`CSSSelectors3`Private`parseANB[" N- 1"],{1,-1}] 92 | 93 | 94 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 n- 1"],_Failure] 95 | 96 | 97 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1n- 1"],_Failure] 98 | 99 | 100 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14n- 1 "],_Failure] 101 | 102 | 103 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2N- 1 "],_Failure] 104 | 105 | 106 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14N- 1 "],{-14,-1}] 107 | 108 | 109 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2N- 1 "],{2,-1}] 110 | 111 | 112 | Test[CSSTools`CSSSelectors3`Private`parseANB["3n- 1"],{3,-1}] 113 | 114 | 115 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- N+ 1"],_Failure] 116 | 117 | 118 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ n+ 1"],_Failure] 119 | 120 | 121 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -N+ 1"],{-1,1}] 122 | 123 | 124 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +N+ 1"],{1,1}] 125 | 126 | 127 | Test[CSSTools`CSSSelectors3`Private`parseANB[" N+ 1"],{1,1}] 128 | 129 | 130 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 N+ 1"],_Failure] 131 | 132 | 133 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1n+ 1"],_Failure] 134 | 135 | 136 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14N+ 1 "],_Failure] 137 | 138 | 139 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2n+ 1 "],_Failure] 140 | 141 | 142 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n+ 1 "],{-14,1}] 143 | 144 | 145 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2n+ 1 "],{2,1}] 146 | 147 | 148 | Test[CSSTools`CSSSelectors3`Private`parseANB["3n+ 1"],{3,1}] 149 | 150 | 151 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- n -1"],_Failure] 152 | 153 | 154 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ n -1"],_Failure] 155 | 156 | 157 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n -1"],{-1,-1}] 158 | 159 | 160 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +N -1"],{1,-1}] 161 | 162 | 163 | Test[CSSTools`CSSSelectors3`Private`parseANB[" N -1"],{1,-1}] 164 | 165 | 166 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 N -1"],_Failure] 167 | 168 | 169 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1N -1"],_Failure] 170 | 171 | 172 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14N -1 "],_Failure] 173 | 174 | 175 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2n -1 "],_Failure] 176 | 177 | 178 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n -1 "],{-14,-1}] 179 | 180 | 181 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2n -1 "],{2,-1}] 182 | 183 | 184 | Test[CSSTools`CSSSelectors3`Private`parseANB["3N -1"],{3,-1}] 185 | 186 | 187 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- N +1"],_Failure] 188 | 189 | 190 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ n +1"],_Failure] 191 | 192 | 193 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n +1"],{-1,1}] 194 | 195 | 196 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +N +1"],{1,1}] 197 | 198 | 199 | Test[CSSTools`CSSSelectors3`Private`parseANB[" n +1"],{1,1}] 200 | 201 | 202 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3n + foo"],_Failure] 203 | 204 | 205 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3n foo"],_Failure] 206 | 207 | 208 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 n +1"],_Failure] 209 | 210 | 211 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1N +1"],_Failure] 212 | 213 | 214 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14n +1 "],_Failure] 215 | 216 | 217 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2N +1 "],_Failure] 218 | 219 | 220 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n +1 "],{-14,1}] 221 | 222 | 223 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2N +1 "],{2,1}] 224 | 225 | 226 | Test[CSSTools`CSSSelectors3`Private`parseANB["3N +1"],{3,1}] 227 | 228 | 229 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB[" -n-1foo"],_Failure] 230 | 231 | 232 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB[" +n-1foo"],_Failure] 233 | 234 | 235 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- n-1"],_Failure] 236 | 237 | 238 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ n-1"],_Failure] 239 | 240 | 241 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n-1"],{-1,-1}] 242 | 243 | 244 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +n-1"],{1,-1}] 245 | 246 | 247 | Test[CSSTools`CSSSelectors3`Private`parseANB[" n-1"],{1,-1}] 248 | 249 | 250 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3n-1foo"],_Failure] 251 | 252 | 253 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 n-1"],_Failure] 254 | 255 | 256 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1n-1"],_Failure] 257 | 258 | 259 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14N-1 "],_Failure] 260 | 261 | 262 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2N-1 "],_Failure] 263 | 264 | 265 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n-1 "],{-14,-1}] 266 | 267 | 268 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2N-1 "],{2,-1}] 269 | 270 | 271 | Test[CSSTools`CSSSelectors3`Private`parseANB["3n-1"],{3,-1}] 272 | 273 | 274 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- N+1"],_Failure] 275 | 276 | 277 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ N+1"],_Failure] 278 | 279 | 280 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n+1"],{-1,1}] 281 | 282 | 283 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +N+1"],{1,1}] 284 | 285 | 286 | Test[CSSTools`CSSSelectors3`Private`parseANB[" n+1"],{1,1}] 287 | 288 | 289 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 n+1"],_Failure] 290 | 291 | 292 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1n+1"],_Failure] 293 | 294 | 295 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14n+1 "],_Failure] 296 | 297 | 298 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2N+1 "],_Failure] 299 | 300 | 301 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n+1 "],{-14,1}] 302 | 303 | 304 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2n+1 "],{2,1}] 305 | 306 | 307 | Test[CSSTools`CSSSelectors3`Private`parseANB["3N+1"],{3,1}] 308 | 309 | 310 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- n"],_Failure] 311 | 312 | 313 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ n"],_Failure] 314 | 315 | 316 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -n"],{-1,0}] 317 | 318 | 319 | Test[CSSTools`CSSSelectors3`Private`parseANB[" +n"],{1,0}] 320 | 321 | 322 | Test[CSSTools`CSSSelectors3`Private`parseANB[" N"],{1,0}] 323 | 324 | 325 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3 n"],_Failure] 326 | 327 | 328 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1N"],_Failure] 329 | 330 | 331 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14N "],_Failure] 332 | 333 | 334 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2N "],_Failure] 335 | 336 | 337 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14n "],{-14,0}] 338 | 339 | 340 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2N "],{2,0}] 341 | 342 | 343 | Test[CSSTools`CSSSelectors3`Private`parseANB["3N"],{3,0}] 344 | 345 | 346 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["3.1"],_Failure] 347 | 348 | 349 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["- 14 "],_Failure] 350 | 351 | 352 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["+ 2 "],_Failure] 353 | 354 | 355 | Test[CSSTools`CSSSelectors3`Private`parseANB[" -14 "],{0,-14}] 356 | 357 | 358 | Test[CSSTools`CSSSelectors3`Private`parseANB["+2 "],{0,2}] 359 | 360 | 361 | Test[CSSTools`CSSSelectors3`Private`parseANB["3"],{0,3}] 362 | 363 | 364 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB[" /**/\t EveN /**/\n"],_Failure] 365 | 366 | 367 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB[" /**/\t OdD /**/\n"],_Failure] 368 | 369 | 370 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["\[EAcute]ven"],_Failure] 371 | 372 | 373 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB["\[ODoubleDot]dd"],_Failure] 374 | 375 | 376 | Test[CSSTools`CSSSelectors3`Private`parseANB["even"],{2,0}] 377 | 378 | 379 | Test[CSSTools`CSSSelectors3`Private`parseANB["odd"],{2,1}] 380 | 381 | 382 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB[" \n"],_Failure] 383 | 384 | 385 | TestMatch[CSSTools`CSSSelectors3`Private`parseANB[""],_Failure] 386 | -------------------------------------------------------------------------------- /Testing/CalcTests.wl: -------------------------------------------------------------------------------- 1 | (* Wolfram Language Package *) 2 | 3 | 4 | (* ::Section:: *) 5 | (*CSS calc() Expression Tests*) 6 | 7 | 8 | Get["CSSTools`CSSTokenizer`"] (* defines CSSTokenize/CSSUntokenize *) 9 | 10 | 11 | (* Basic addition/subtraction *) 12 | Test[ 13 | And[ 14 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(1px - 2px)"]]], "-1px"], 15 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 1px - 2px )"]]], "-1px"], 16 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 1px - 2px )"]]], "-1px"] 17 | ], 18 | True] 19 | 20 | 21 | Test[ 22 | And[ 23 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(1px + 2px)"]]], "3px"], 24 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 1px + 2px )"]]], "3px"], 25 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 1px + 2px )"]]], "3px"] 26 | ], 27 | True] 28 | 29 | 30 | Test[ 31 | And[ 32 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(2px - 1px)"]]], "1px"], 33 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 2px - 1px )"]]], "1px"], 34 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 2px - 1px )"]]], "1px"] 35 | ], 36 | True] 37 | 38 | 39 | (* Basic multiplication/division *) 40 | Test[ 41 | And[ 42 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(5px*2)"]]], "10px"], 43 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 5px*2 )"]]], "10px"], 44 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(2*5px)"]]], "10px"], 45 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(2 * 5px)"]]], "10px"], 46 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(2.2 * 5px)"]]], "11.0px"], 47 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc((2)*(((5px))))"]]], "10px"] 48 | ], 49 | True] 50 | 51 | 52 | Test[ 53 | And[ 54 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(10px/2)"]]], "5px"], 55 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 10px/2 )"]]], "5px"], 56 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(5px/2)"]]], "2.5px"], 57 | StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc( 5px/2 )"]]], "2.5px"] 58 | ], 59 | True] 60 | 61 | 62 | (* keep similar types together *) 63 | Test[StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(100%/3 - 2*1em - 2*1px)"]]], "calc(33.3333% - 2em - 2px)"], True] 64 | 65 | (* nesting is allowed *) 66 | Test[StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(calc(100%)"]]], "100%"], True] 67 | Test[StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc((2))"]]], "2"], True] 68 | Test[StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(2/(3))"]]], "0.666667"], True] 69 | 70 | (* complicated example with parenthetical grouping *) 71 | Test[StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(5px + 2*calc(100%/3 - 21px/2)/3)"]]], "calc(22.2222% - 2.0px)"], True] 72 | 73 | (* corner case of required grouping with subtraction *) 74 | Test[StringMatchQ[CSSUntokenize @ Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(calc(2% - 2px) - calc(4% - 5px))"]]], "calc(-2% + 3px)"], True] 75 | 76 | (* each term should have an operator in between (checked after multiplication resolves) *) 77 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(3px+10%)"]]], _Failure] 78 | 79 | (* ==== correct failure detections ==== *) 80 | (* space between number and unit *) 81 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(100%/3 - 2*1 em - 2*1px)"]]], _Failure] 82 | 83 | (* missing multiplication sign (multiplication is not implied) *) 84 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(calc(3) calc(calc(100%)))"]]], _Failure] 85 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(((3px)(2))*(2))"]]], _Failure] 86 | 87 | (* missing spaces around + operator *) 88 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(3px+10%)"]]], _Failure] 89 | 90 | (* px (length) and hz (frequency) are units of different types *) 91 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(3px + 2hz)"]]], _Failure] 92 | 93 | (* missing terms *) 94 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(3px + ( + ))"]]], _Failure] 95 | TestMatch[Catch @ CSSTools`CSSValuesAndUnits3`Private`calcReduce[First[CSSTokenize["calc(( + ))"]]], _Failure] 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Testing/GeneralColors.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | (* ::Section:: *) 4 | (*General Color Tests*) 5 | 6 | 7 | Get["CSSTools`CSSTools`"]; 8 | Get["CSSTools`CSSTokenizer`"]; 9 | 10 | 11 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["cmyk(0, 0, 0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 12 | 13 | 14 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(0, 0%, 0%, 1, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 15 | 16 | 17 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(0, 0%, 0%, 50%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 18 | 19 | 20 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(0, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 21 | 22 | 23 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 24 | 25 | 26 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla()"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 27 | 28 | 29 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(0, 0%, light, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 30 | 31 | 32 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(30deg, 100%, 100%, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`,1.`}] 33 | 34 | 35 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(0, 0% 0%, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 36 | 37 | 38 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(50%, 50%, 0%, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 39 | 40 | 41 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(10, 50%, 0, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 42 | 43 | 44 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(-300, 100%, 37.5%, -3)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`,0.`}] 45 | 46 | 47 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(-300, 100%, 37.5%, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`,0.`}] 48 | 49 | 50 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsla(-300, 100%, 37.5%, 0.2)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`,0.2`}] 51 | 52 | 53 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsLA(-300, 100%, 37.5%, 12)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`,1.`}] 54 | 55 | 56 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["HSLA(-300, 100%, 37.5%, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`,1.`}] 57 | 58 | 59 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(0, 0%, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 60 | 61 | 62 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(0, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 63 | 64 | 65 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 66 | 67 | 68 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl()"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 69 | 70 | 71 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(0, 0%, light)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 72 | 73 | 74 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(30deg, 100%, 100%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`}] 75 | 76 | 77 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(0, 0% 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 78 | 79 | 80 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(50%, 50%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 81 | 82 | 83 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(10, 50%, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 84 | 85 | 86 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(300, 50%, 50%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.25`,0.75`}] 87 | 88 | 89 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(-300, 100%, 37.5%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`}] 90 | 91 | 92 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(780, 100%, 37.5%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.7499999999999993`,0.`}] 93 | 94 | 95 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsl(60, 100%, 37.5%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.75`,0.75`,0.`}] 96 | 97 | 98 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["hsL(0, 100%, 50%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,0.`,0.`}] 99 | 100 | 101 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["HSL(0, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`}] 102 | 103 | 104 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 0%, 0%, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 105 | 106 | 107 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 0%, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`,0.`}] 108 | 109 | 110 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`}] 111 | 112 | 113 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 114 | 115 | 116 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 117 | 118 | 119 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 0, 0, 0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 120 | 121 | 122 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`}] 123 | 124 | 125 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 126 | 127 | 128 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba()"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 129 | 130 | 131 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 0, 0, light)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 132 | 133 | 134 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 0, 0, 0deg)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 135 | 136 | 137 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 0, 0 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 138 | 139 | 140 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(255, 50%, 0%, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 141 | 142 | 143 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(10%, 50%, 0, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 144 | 145 | 146 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(255, 255, 255, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`,0.`}] 147 | 148 | 149 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 20%, 100%, -139)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.`}] 150 | 151 | 152 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 20%, 100%, -0.1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.`}] 153 | 154 | 155 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 20%, 100%, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.`}] 156 | 157 | 158 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 20%, 100%, 0.42)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.42`}] 159 | 160 | 161 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 20%, 100%, 37)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,1.`}] 162 | 163 | 164 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0%, 20%, 100%, 1.1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,1.`}] 165 | 166 | 167 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgBA(0%, 20%, 100%, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,1.`}] 168 | 169 | 170 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["RGBA(100%, 100%, 100%, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`,0.`}] 171 | 172 | 173 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(42%, 3%, 50%, 0.3)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.42`,0.03`,0.5`,0.3`}] 174 | 175 | 176 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 51, 255, -139)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.`}] 177 | 178 | 179 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 51, 255, -0.1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.`}] 180 | 181 | 182 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 51, 255, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.`}] 183 | 184 | 185 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 51, 255, 0.42)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,0.42`}] 186 | 187 | 188 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 51, 255, 37)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,1.`}] 189 | 190 | 191 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 51, 255, 1.1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,1.`}] 192 | 193 | 194 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgBA(0, 51, 255, 1)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`,1.`}] 195 | 196 | 197 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["RGBA(255, 255, 255, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`,0.`}] 198 | 199 | 200 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(204, 0, 102, 0.3)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.8`,0.`,0.4`,0.3`}] 201 | 202 | 203 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgba(0, 0, 0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`,0.`}] 204 | 205 | 206 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0%, 0%, 0%, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`,0.`}] 207 | 208 | 209 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0%, 0%, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`,0.`}] 210 | 211 | 212 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 213 | 214 | 215 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 216 | 217 | 218 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0, 0, 0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`,0.`}] 219 | 220 | 221 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 222 | 223 | 224 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 225 | 226 | 227 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb()"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 228 | 229 | 230 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0, 0, light)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 231 | 232 | 233 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0, 0, 0deg)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 234 | 235 | 236 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0, 0 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 237 | 238 | 239 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(255, 50%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 240 | 241 | 242 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(10%, 50%, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 243 | 244 | 245 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(-12%, 110%, 1400%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,1.`,1.`}] 246 | 247 | 248 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(/* R */ 10%, /* G */ 20%, /* B */ 30%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.1`,0.2`,0.3`}] 249 | 250 | 251 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(10%\t, 20% ,30%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.1`,0.2`,0.3`}] 252 | 253 | 254 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(10%,20%,30%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.1`,0.2`,0.3`}] 255 | 256 | 257 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgB(10%, 20%, 30%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.1`,0.2`,0.3`}] 258 | 259 | 260 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgB(0%, 0%, 0%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`}] 261 | 262 | 263 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["RGB(100%, 100%, 100%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`}] 264 | 265 | 266 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(42%, 3%, 50%)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.42`,0.03`,0.5`}] 267 | 268 | 269 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(-51, 306, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,1.`,0.`}] 270 | 271 | 272 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(/* R */0, /* G */51, /* B */255)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`}] 273 | 274 | 275 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0\t, 51 ,255)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`}] 276 | 277 | 278 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(0,51,255)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`}] 279 | 280 | 281 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgB(0, 51, 255)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,1.`}] 282 | 283 | 284 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgB(0, 0, 0)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`}] 285 | 286 | 287 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["RGB(153, 204, 255)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.6`,0.8`,1.`}] 288 | 289 | 290 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["r\\67 b(00, 51, 102)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,0.4`}] 291 | 292 | 293 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["r\\gb(00, 51, 102)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,0.4`}] 294 | 295 | 296 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["rgb(00, 51, 102)"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.2`,0.4`}] 297 | 298 | 299 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#369"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.2`,0.4`,0.6`}] 300 | 301 | 302 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#FFCc99"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,0.8`,0.6`}] 303 | 304 | 305 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fffffffff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 306 | 307 | 308 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fffffffg"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 309 | 310 | 311 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#ffffffff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`,1.`}] 312 | 313 | 314 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fffffff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 315 | 316 | 317 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fffffg"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 318 | 319 | 320 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#ffffff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`}] 321 | 322 | 323 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fffff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 324 | 325 | 326 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fffg"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 327 | 328 | 329 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#ffff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`,1.`}] 330 | 331 | 332 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#ffg"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 333 | 334 | 335 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#fff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`}] 336 | 337 | 338 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#ff"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 339 | 340 | 341 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#f"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 342 | 343 | 344 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["#"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 345 | 346 | 347 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["CyAn"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,1.`,1.`}] 348 | 349 | 350 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["cyan"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,1.`,1.`}] 351 | 352 | 353 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["fuchsia"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,0.`,1.`}] 354 | 355 | 356 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["white"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{1.`,1.`,1.`}] 357 | 358 | 359 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["black"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],{0.`,0.`,0.`}] 360 | 361 | 362 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["current-Color"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 363 | 364 | 365 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["CURRENTcolor"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]], Dynamic[CurrentValue[FontColor],___]] 366 | 367 | 368 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["currentColor"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]], Dynamic[CurrentValue[FontColor],___]] 369 | 370 | 371 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["TransParent"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],None] 372 | 373 | 374 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize[" transparent\n"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 375 | 376 | 377 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["transparent"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],None] 378 | 379 | 380 | NTest[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["/**/transparent"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],None] 381 | 382 | 383 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["top"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 384 | 385 | 386 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize["4"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 387 | 388 | 389 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize[" /* hey */\n"],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 390 | 391 | 392 | TestMatch[With[{val=CSSTools`CSSPropertyInterpreter`parseSingleColor["color",First[CSSTokenize[""],{}]]},If[FailureQ[val]||val===None||Head[val]===Dynamic,val,List@@ColorConvert[val,"RGB"]]],_Failure] 393 | -------------------------------------------------------------------------------- /Testing/Gradients.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | (* ::Section:: *) 4 | (*Named Colors Tests*) 5 | 6 | (* basic top-to-bottom linear gradient tests *) 7 | res = { 8 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(yellow, blue)"]], 9 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(to bottom, yellow, blue)"]], 10 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(180deg, yellow, blue)"]], 11 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(to top, blue, yellow)"]], 12 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(to bottom, yellow 0%, blue 100%)"]]}; 13 | 14 | TestMatch[AnyTrue[res, _?FailureQ], False] 15 | 16 | TestRequirement[!AnyTrue[res, _?FailureQ]]; 17 | 18 | (* all expressions in 'res' should produce the same gradient within tolerance *) 19 | res = Through @ res[{200, 100}]; 20 | res = Table[Union[Clip[Round[Flatten[ImageData[#]], 0.01]]]& @ ImageDifference[res[[i]], res[[j]]], {i, 1, Length[res]}, {j, i + 1, Length[res]}]; 21 | 22 | TestMatch[Equal[Clip[Union[Flatten[res, {0.}]]]], True] 23 | 24 | EndRequirement[]; 25 | 26 | 27 | 28 | (* basic angled gradient tests *) 29 | res = { 30 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(135deg, yellow, blue)"]], 31 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(-45deg, blue, yellow)"]]} 32 | 33 | TestMatch[AnyTrue[res, _?FailureQ], False] 34 | 35 | TestRequirement[!AnyTrue[res, _?FailureQ]]; 36 | 37 | (* all expressions in 'res' should produce the same gradient within tolerance *) 38 | res = Through @ res[{200, 100}]; 39 | res = Table[Union[Clip[Round[Flatten[ImageData[#]], 0.01]]]& @ ImageDifference[res[[i]], res[[j]]], {i, 1, Length[res]}, {j, i + 1, Length[res]}]; 40 | 41 | TestMatch[Equal[Clip[Union[Flatten[res, {0.}]]]], True] 42 | 43 | EndRequirement[]; 44 | 45 | 46 | 47 | (* basic angled gradient tests *) 48 | res = { 49 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(135deg, yellow, blue)"]], 50 | Catch @ CSSTools`CSSImages3`Private`parseLinearGradientFunction["test", First @ CSSTokenize["linear-gradient(-45deg, blue, yellow)"]]} 51 | 52 | TestMatch[AnyTrue[res, _?FailureQ], False] 53 | 54 | TestRequirement[!AnyTrue[res, _?FailureQ]]; 55 | 56 | (* all expressions in 'res' should produce the same gradient within tolerance *) 57 | res = Through @ res[{200, 100}]; 58 | res = Table[Union[Clip[Round[Flatten[ImageData[#]], 0.01]]]& @ ImageDifference[res[[i]], res[[j]]], {i, 1, Length[res]}, {j, i + 1, Length[res]}]; 59 | 60 | TestMatch[Equal[Clip[Union[Flatten[res, {0.}]]]], True] 61 | 62 | EndRequirement[]; 63 | 64 | 65 | -------------------------------------------------------------------------------- /Testing/RegularExpressions.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | (* ::Section:: *) 4 | (*Regex Tests*) 5 | 6 | 7 | Get["CSSTools`CSSTokenizer`"] (* defines RE *) 8 | 9 | 10 | Test[And@@(StringMatchQ[#, RegularExpression[RE["hex digit"]]]& /@ ToString /@ Join[Range[0,9], CharacterRange["a","f"], CharacterRange["A","F"]]), True] 11 | 12 | 13 | Test[Apply[ 14 | And, 15 | StringMatchQ[#, RegularExpression @ RE["A"]]& /@ Flatten@{"a","A",Outer[StringJoin, {"\\"},{"","0","00","000","0000"},{"41","61"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 16 | 17 | 18 | Test[Apply[ 19 | And, 20 | StringMatchQ[#, RegularExpression @ RE["C"]]& /@ Flatten@{"c","C",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"43","63"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 21 | 22 | 23 | Test[Apply[ 24 | And, 25 | StringMatchQ[#, RegularExpression @ RE["D"]]& /@ Flatten@{"d","D",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"44","64"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 26 | 27 | 28 | Test[Apply[ 29 | And, 30 | StringMatchQ[#, RegularExpression @ RE["E"]]& /@ Flatten@{"e","E",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"45","65"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 31 | 32 | 33 | Test[Apply[ 34 | And, 35 | StringMatchQ[#, RegularExpression @ RE["G"]]& /@ Flatten@{"g","G","\\g","\\G",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"47","67"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 36 | 37 | 38 | Test[Apply[ 39 | And, 40 | StringMatchQ[#, RegularExpression @ RE["H"]]& /@ Flatten@{"h","H","\\h","\\H",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"48","68"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 41 | 42 | 43 | Test[Apply[ 44 | And, 45 | StringMatchQ[#, RegularExpression @ RE["I"]]& /@ Flatten@{"i","I","\\i","\\I",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"49","69"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 46 | 47 | 48 | Test[Apply[ 49 | And, 50 | StringMatchQ[#, RegularExpression @ RE["K"]]& /@ Flatten@{"k","K","\\k","\\K",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"4b","6b"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 51 | 52 | 53 | Test[Apply[ 54 | And, 55 | StringMatchQ[#, RegularExpression @ RE["L"]]& /@ Flatten@{"l","L","\\l","\\L",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"4c","6c"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 56 | 57 | 58 | Test[Apply[ 59 | And, 60 | StringMatchQ[#, RegularExpression @ RE["M"]]& /@ Flatten@{"m","M","\\m","\\M",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"4d","6d"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 61 | 62 | 63 | Test[Apply[ 64 | And, 65 | StringMatchQ[#, RegularExpression @ RE["N"]]& /@ Flatten@{"n","N","\\n","\\N",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"4e","6e"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 66 | 67 | 68 | Test[Apply[ 69 | And, 70 | StringMatchQ[#, RegularExpression @ RE["O"]]& /@ Flatten@{"o","O","\\o","\\O",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"4f","6f"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 71 | 72 | 73 | Test[Apply[ 74 | And, 75 | StringMatchQ[#, RegularExpression @ RE["P"]]& /@ Flatten@{"p","P","\\p","\\P",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"50","70"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 76 | 77 | 78 | Test[Apply[ 79 | And, 80 | StringMatchQ[#, RegularExpression @ RE["R"]]& /@ Flatten@{"r","R","\\r","\\R",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"52","72"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 81 | 82 | 83 | Test[Apply[ 84 | And, 85 | StringMatchQ[#, RegularExpression @ RE["S"]]& /@ Flatten@{"s","S","\\s","\\S",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"53","73"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 86 | 87 | 88 | Test[Apply[ 89 | And, 90 | StringMatchQ[#, RegularExpression @ RE["T"]]& /@ Flatten@{"t","T","\\t","\\T",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"44","74"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 91 | 92 | 93 | Test[Apply[ 94 | And, 95 | StringMatchQ[#, RegularExpression @ RE["U"]]& /@ Flatten@{"u","U","\\u","\\U",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"55","75"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 96 | 97 | 98 | Test[Apply[ 99 | And, 100 | StringMatchQ[#, RegularExpression @ RE["X"]]& /@ Flatten@{"x","X","\\x","\\X",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"58","78"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 101 | 102 | 103 | Test[Apply[ 104 | And, 105 | StringMatchQ[#, RegularExpression @ RE["Z"]]& /@ Flatten@{"z","Z","\\z","\\Z",Outer[StringJoin, {"\\"},{"0","00","000","0000"},{"5a","7a"},{"","\r\n"," ","\t","\r","\n","\f"}]}], True] 106 | -------------------------------------------------------------------------------- /Testing/RunTests.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | (* Wolfram Language package *) 4 | 5 | Get["MUnit`"]; 6 | SetDirectory[NotebookDirectory[]]; 7 | 8 | 9 | Get["CSSTools`CSSTools`"]; 10 | Get["CSSTools`CSSTokenizer`"]; 11 | 12 | 13 | res = TestReport["CalcTests.wl"]; 14 | res["TestsFailed"] 15 | 16 | 17 | res = TestReport["ANB.wl"]; 18 | res["TestsFailed"] 19 | 20 | 21 | res = TestReport["GeneralColors.wl"]; 22 | res["TestsFailed"] 23 | 24 | 25 | res = TestReport["HSLColors.wl"]; 26 | res["TestsFailed"] 27 | 28 | 29 | res = TestReport["NamedColors.wl"]; 30 | res["TestsFailed"] 31 | 32 | 33 | res = TestReport["RegularExpressions.wl"]; 34 | res["TestsFailed"] 35 | 36 | 37 | res = TestReport["Tokenizer.wl"]; 38 | res["TestsFailed"] 39 | -------------------------------------------------------------------------------- /WLDocumentationTemplates/English/Guides/CSSTools.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 12.1' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 158, 7] 13 | NotebookDataLength[ 18895, 467] 14 | NotebookOptionsPosition[ 12781, 342] 15 | NotebookOutlinePosition[ 13259, 359] 16 | CellTagsIndexPosition[ 13216, 356] 17 | WindowFrame->Normal*) 18 | 19 | (* Beginning of Notebook Content *) 20 | Notebook[{ 21 | Cell[TextData[{ 22 | "New in: ", 23 | Cell["0.0", "HistoryData", 24 | CellTags->"New",ExpressionUUID->"92cb4b11-1884-42b8-9b84-379879e0d3f6"], 25 | " | Modified in: ", 26 | Cell[" ", "HistoryData", 27 | CellTags->"Modified",ExpressionUUID->"8d629473-be2b-4dd0-be97-a44b708ef80c"], 28 | " | Obsolete in: ", 29 | Cell[" ", "HistoryData", 30 | CellTags->"Obsolete",ExpressionUUID->"482803a2-23e1-4f80-ba07-2f735e002bea"], 31 | " | Excised in: ", 32 | Cell[" ", "HistoryData", 33 | CellTags->"Excised",ExpressionUUID->"af2a187f-069d-418e-9b24-fb850c52d60b"] 34 | }], "History", 35 | CellID->1247902091,ExpressionUUID->"3f228a90-67e3-4ddc-aba9-a30260165a01"], 36 | 37 | Cell[CellGroupData[{ 38 | 39 | Cell["Categorization", "CategorizationSection", 40 | CellID->1122911449,ExpressionUUID->"49b8370b-fba4-43fd-8feb-61a22f3afb98"], 41 | 42 | Cell["Guide", "Categorization", 43 | CellLabel->"Entity Type", 44 | CellID->686433507,ExpressionUUID->"afefdc72-4615-44a1-a8e0-af54b52288ad"], 45 | 46 | Cell["CSSTools", "Categorization", 47 | CellLabel->"Paclet Name", 48 | CellID->605800465,ExpressionUUID->"2ae2ce4e-aff7-4c77-bb96-48ac12359267"], 49 | 50 | Cell["CSSTools`", "Categorization", 51 | CellLabel->"Context", 52 | CellID->468444828,ExpressionUUID->"61dd1053-5793-48bf-bf29-331afbd03b25"], 53 | 54 | Cell["CSSTools/guide/CSSTools", "Categorization", 55 | CellLabel->"URI",ExpressionUUID->"0e8027d0-a5f1-4054-bed7-e8a194cd5768"] 56 | }, Closed]], 57 | 58 | Cell[CellGroupData[{ 59 | 60 | Cell["Keywords", "KeywordsSection", 61 | CellID->1427428552,ExpressionUUID->"120852a4-1ab9-4488-88a7-f502b583274a"], 62 | 63 | Cell["XXXX", "Keywords", 64 | CellID->1251852827,ExpressionUUID->"0ae6185c-4b9c-43c4-a810-6b67bf388f86"] 65 | }, Closed]], 66 | 67 | Cell[CellGroupData[{ 68 | 69 | Cell["Details", "DetailsSection", 70 | CellID->307771771,ExpressionUUID->"e2325835-5bf9-4fea-b925-53e4db557e2d"], 71 | 72 | Cell["XXXX", "Details", 73 | CellLabel->"Lead", 74 | CellID->795394057,ExpressionUUID->"f56ab596-32d7-4da1-8bf5-90baf09e6c61"], 75 | 76 | Cell["XXXX", "Details", 77 | CellLabel->"Developers", 78 | CellID->350963985,ExpressionUUID->"5681448f-080c-407b-8713-4cba7ee95130"], 79 | 80 | Cell["XXXX", "Details", 81 | CellLabel->"Authors", 82 | CellID->802101,ExpressionUUID->"50cc3ff9-0ec4-4a83-a2b0-9378c4ce01f3"], 83 | 84 | Cell["XXXX", "Details", 85 | CellLabel->"Feature Name", 86 | CellID->509823116,ExpressionUUID->"33a10c42-452c-4b09-ae79-30801d6c1909"], 87 | 88 | Cell["XXXX", "Details", 89 | CellLabel->"QA", 90 | CellID->199884516,ExpressionUUID->"535969ea-5525-4bd5-ad4e-418273868a9c"], 91 | 92 | Cell["XXXX", "Details", 93 | CellLabel->"DA", 94 | CellID->463951815,ExpressionUUID->"df3a7c4b-bbf9-4aa9-bd63-05cdff2d38b6"], 95 | 96 | Cell["XXXX", "Details", 97 | CellLabel->"Docs", 98 | CellID->8237523,ExpressionUUID->"4f658b12-1c05-4518-ae92-ad067588a2a8"], 99 | 100 | Cell["XXXX", "Details", 101 | CellLabel->"Features Page Notes", 102 | CellID->813936640,ExpressionUUID->"ba2183a6-95c4-4c26-830e-f23e2f1f3c3f"], 103 | 104 | Cell["XXXX", "Details", 105 | CellLabel->"Comments", 106 | CellID->240026365,ExpressionUUID->"303fa587-fdc7-4a69-8e02-26b667c593f4"] 107 | }, Closed]], 108 | 109 | Cell[CellGroupData[{ 110 | 111 | Cell["CSSTools", "GuideTitle", 112 | CellChangeTimes->{{3.7627351689380827`*^9, 3.7627351691474466`*^9}, { 113 | 3.7745353275294247`*^9, 3.774535327718917*^9}}, 114 | CellID->942062912,ExpressionUUID->"a2dfbf4b-a400-497d-b964-cad8f8e0772e"], 115 | 116 | Cell["\<\ 117 | Cascading Style Sheets (CSS) is a stylesheet language used for describing the \ 118 | presentation of a document written in markup language like HTML and XML. \ 119 | Wolfram Desktop also uses stylesheets though the specifications differ. This \ 120 | package provides tools for importing and processing CSS to be used within \ 121 | Wolfram Desktop's stylesheet system.\ 122 | \>", "GuideAbstract", 123 | CellChangeTimes->{{3.7616491132104626`*^9, 3.7616491254825068`*^9}, { 124 | 3.761649212394489*^9, 3.7616494135696383`*^9}, {3.7621015002399387`*^9, 125 | 3.7621015070717745`*^9}, {3.7772272356737833`*^9, 3.777227235876914*^9}, 126 | 3.792931463833679*^9, {3.8039150054168043`*^9, 3.8039150055205193`*^9}}, 127 | CellID->2001916300,ExpressionUUID->"b9255c52-39e9-48e0-bedb-b4fa7ec2beba"] 128 | }, Open ]], 129 | 130 | Cell[CellGroupData[{ 131 | 132 | Cell["", "GuideFunctionsSection", 133 | CellID->1866139230,ExpressionUUID->"50d091ef-42cf-4d28-b7a3-da0423b384b3"], 134 | 135 | Cell[CellGroupData[{ 136 | 137 | Cell["Importing CSS", "GuideFunctionsSubsection", 138 | CellChangeTimes->{{3.7616495039235115`*^9, 3.761649505545987*^9}}, 139 | CellID->811494718,ExpressionUUID->"8d817216-d113-4b36-bc3d-a0f25f4d05de"], 140 | 141 | Cell[TextData[{ 142 | Cell[BoxData[ 143 | ButtonBox["Import", 144 | BaseStyle->"Link", 145 | ButtonData->"paclet:ref/Import"]], "InlineGuideFunction",ExpressionUUID-> 146 | "c9fdab9c-6be2-48f2-94fe-b22372b67f18"], 147 | " \[LongDash] Supports the \"CSS\" file type: Import[", 148 | Cell[BoxData[ 149 | StyleBox["path", "TI"]], "InlineFormula",ExpressionUUID-> 150 | "fa056fd2-0493-4371-9e7c-c4c7a48afaaa"], 151 | ", \"CSS\"]" 152 | }], "GuideText", 153 | CellChangeTimes->{{3.761650054058169*^9, 3.761650122627078*^9}, { 154 | 3.792931444577236*^9, 3.7929314469219213`*^9}}, 155 | CellID->100541697,ExpressionUUID->"dee08810-36bd-4ef8-b550-71bf497466fd"], 156 | 157 | Cell[TextData[{ 158 | Cell[BoxData[ 159 | ButtonBox["ExtractCSSFromXML", 160 | BaseStyle->"Link", 161 | ButtonData->"paclet:CSSTools/ref/ExtractCSSFromXML"]], 162 | "InlineGuideFunction",ExpressionUUID-> 163 | "f3729722-c0dc-4b1e-8057-8bb654336ad1"], 164 | " \[LongDash] imports the CSS declarations within an XMLObject" 165 | }], "GuideText", 166 | CellChangeTimes->{{3.761649518383849*^9, 3.761649518383849*^9}, { 167 | 3.7616495934236593`*^9, 3.7616495966736116`*^9}, {3.7616500300429096`*^9, 168 | 3.761650030177866*^9}, {3.762101516914629*^9, 3.762101517889311*^9}}, 169 | CellID->203374175,ExpressionUUID->"fa3304e9-15e7-4c88-80b5-5c41585afd56"] 170 | }, Open ]], 171 | 172 | Cell["\t", "GuideDelimiter", 173 | CellID->622275174,ExpressionUUID->"92df8e96-2df7-4fb0-b6b7-28dfc06ca57c"], 174 | 175 | Cell[CellGroupData[{ 176 | 177 | Cell["Processing CSS", "GuideFunctionsSubsection", 178 | CellChangeTimes->{{3.761650166944778*^9, 3.761650193985075*^9}, { 179 | 3.777287528860149*^9, 3.777287529227656*^9}}, 180 | CellID->91319310,ExpressionUUID->"5f8eaa5a-bc2f-4fac-88db-96866e681ff0"], 181 | 182 | Cell[TextData[{ 183 | Cell[BoxData[ 184 | ButtonBox["CSSCascade", 185 | BaseStyle->"Link", 186 | ButtonData->"paclet:CSSTools/ref/CSSCascade"]], "InlineGuideFunction", 187 | ExpressionUUID->"32ad7f09-e866-48f1-bd17-2aedcb9006d7"], 188 | " \[LongDash] follows the CSS cascade algorithm and converts interpreted CSS \ 189 | styles to Notebook, Cell, or Box options" 190 | }], "GuideText", 191 | CellChangeTimes->{{3.761650230489294*^9, 3.761650284335936*^9}, { 192 | 3.761650458687731*^9, 3.7616504588396816`*^9}, {3.7771371057105975`*^9, 193 | 3.7771371140425143`*^9}, {3.7929313587618027`*^9, 3.7929313622255363`*^9}}, 194 | CellID->47789317,ExpressionUUID->"22c8ab8e-8da0-47ea-8af6-3ed63aad5b8a"], 195 | 196 | Cell[TextData[{ 197 | Cell[BoxData[ 198 | ButtonBox["CSSInheritance", 199 | BaseStyle->"Link", 200 | ButtonData->"paclet:CSSTools/ref/CSSInheritance"]], "InlineGuideFunction", 201 | ExpressionUUID->"4ca9529b-766b-4845-937c-8c206e6691b7"], 202 | " \[LongDash] for CSS generated from an XMLObject" 203 | }], "GuideText", 204 | CellChangeTimes->{{3.7616502242493057`*^9, 3.76165022809309*^9}, { 205 | 3.7616504020000057`*^9, 3.761650408866815*^9}, {3.761650455968608*^9, 206 | 3.7616504561085625`*^9}}, 207 | CellID->348206879,ExpressionUUID->"9fff43cf-59ce-41dc-a1cd-c525790c844f"] 208 | }, Open ]], 209 | 210 | Cell["\t", "GuideDelimiter", 211 | CellID->71783130,ExpressionUUID->"97bc2ebf-8ed5-4a50-830d-bcb39efb1d4e"], 212 | 213 | Cell[CellGroupData[{ 214 | 215 | Cell["Searching SymbolicXML", "GuideFunctionsSubsection", 216 | CellChangeTimes->{{3.7616505171049*^9, 3.7616505186234107`*^9}, { 217 | 3.7616531409074535`*^9, 3.7616531518761473`*^9}}, 218 | CellID->159396722,ExpressionUUID->"3f2d20fc-7cdc-4adb-8fc5-a03b4a0fdbf4"], 219 | 220 | Cell[TextData[{ 221 | Cell[BoxData[ 222 | ButtonBox["CSSSelector", 223 | BaseStyle->"Link", 224 | ButtonData->"paclet:CSSTools/ref/CSSSelector"]], "InlineGuideFunction", 225 | ExpressionUUID->"c98bed6c-5104-4cbe-91a3-343c7131bde9"], 226 | " \[LongDash] creates a CSS selector object" 227 | }], "GuideText", 228 | CellChangeTimes->{{3.7616505265928416`*^9, 3.7616505324859414`*^9}, { 229 | 3.76165061320792*^9, 3.761650616294925*^9}, {3.76165302378302*^9, 230 | 3.761653112985676*^9}, {3.761653649108163*^9, 3.761653667248663*^9}, { 231 | 3.7745353859883537`*^9, 3.774535408980158*^9}}, 232 | CellID->41288703,ExpressionUUID->"76b7ff53-5475-4aac-af5f-dfa262a0aec6"], 233 | 234 | Cell[TextData[{ 235 | Cell[BoxData[ 236 | ButtonBox["CSSSelectorQ", 237 | BaseStyle->"Link", 238 | ButtonData->"paclet:CSSTools/ref/CSSSelectorQ"]], "InlineGuideFunction", 239 | ExpressionUUID->"d84dff61-df7e-43ce-8bff-f5b2c5c82f20"], 240 | " \[LongDash] returns True if expression is a CSS selector object" 241 | }], "GuideText", 242 | CellChangeTimes->{{3.7772874230717745`*^9, 3.777287459798074*^9}}, 243 | CellID->46073956,ExpressionUUID->"a2cd85ab-f27a-4852-9806-a0247ac5cce9"], 244 | 245 | Cell[TextData[{ 246 | Cell[BoxData[ 247 | ButtonBox["CSSSubjects", 248 | BaseStyle->"Link", 249 | ButtonData->"paclet:CSSTools/ref/CSSSubjects"]], "InlineGuideFunction", 250 | ExpressionUUID->"6d1e3204-9a0d-49d1-834d-9d9ae641f56e"], 251 | " \[LongDash] applies a CSS selector to an XMLObject or CSS dataset, \ 252 | returning selector subject information" 253 | }], "GuideText", 254 | CellChangeTimes->{{3.764630515136366*^9, 3.764630575518057*^9}, { 255 | 3.7745353470183153`*^9, 3.774535348341634*^9}, {3.7745354297091537`*^9, 256 | 3.7745354308690653`*^9}, {3.7929314142573347`*^9, 3.7929314239374104`*^9}, { 257 | 3.8039150387286863`*^9, 3.8039151254407*^9}}, 258 | CellID->2444546,ExpressionUUID->"3d3dc613-bae0-45a3-970e-a82dcf688d97"], 259 | 260 | Cell[TextData[{ 261 | Cell[BoxData[ 262 | ButtonBox["CSSSubjectQ", 263 | BaseStyle->"Link", 264 | ButtonData->"paclet:CSSTools/ref/CSSSubjectQ"]], "InlineGuideFunction", 265 | ExpressionUUID->"fb12b143-0134-4c3d-936a-0cf8a6e1ef25"], 266 | " \[LongDash] returns True if expression is a CSSSubject object" 267 | }], "GuideText", 268 | CellChangeTimes->{{3.764630515136366*^9, 3.764630575518057*^9}, { 269 | 3.7745353470183153`*^9, 3.774535348341634*^9}, {3.7745354297091537`*^9, 270 | 3.7745354308690653`*^9}, {3.7929313735861387`*^9, 3.7929314053940506`*^9}, { 271 | 3.803915022272683*^9, 3.8039150233049555`*^9}}, 272 | CellID->399786665,ExpressionUUID->"6ef07e31-cc99-4c06-84f5-6ec15c87c6b7"] 273 | }, Open ]], 274 | 275 | Cell["\t", "GuideDelimiter", 276 | CellID->294180157,ExpressionUUID->"bd8319f4-05f5-4ea8-af26-0dfcea2bc15f"], 277 | 278 | Cell[CellGroupData[{ 279 | 280 | Cell["Images Module", "GuideFunctionsSubsection", 281 | CellChangeTimes->{{3.7997599370326385`*^9, 3.799759943608016*^9}, { 282 | 3.7997600229602747`*^9, 3.799760068487496*^9}}, 283 | CellID->262714310,ExpressionUUID->"4fb25de5-3a55-44c3-ac83-960ebfc02839"], 284 | 285 | Cell[TextData[{ 286 | Cell[BoxData[ 287 | ButtonBox["CSSLinearGradientImage", 288 | BaseStyle->"Link", 289 | ButtonData->"paclet:CSSTools/ref/CSSLinearGradientImage"]], 290 | "InlineGuideFunction",ExpressionUUID-> 291 | "b3356218-30b4-40ba-a95f-314494a8f651"], 292 | " \[LongDash] create a linear gradient following the CSS specification" 293 | }], "GuideText", 294 | CellChangeTimes->{{3.799759960585163*^9, 3.7997599714201736`*^9}, { 295 | 3.799760086136243*^9, 3.799760097959608*^9}}, 296 | CellID->213621991,ExpressionUUID->"06fc4090-62d9-461f-88f5-ac3889552ddc"], 297 | 298 | Cell[TextData[{ 299 | Cell[BoxData[ 300 | ButtonBox["CSSRadialGradientImage", 301 | BaseStyle->"Link", 302 | ButtonData->"paclet:CSSTools/ref/CSSRadialGradientImage"]], 303 | "InlineGuideFunction",ExpressionUUID-> 304 | "da129d4d-923c-4d6d-a058-6867ee31a3a4"], 305 | " \[LongDash] create a radial gradient following the CSS specification" 306 | }], "GuideText", 307 | CellChangeTimes->{{3.7997599732961907`*^9, 3.7997599798805375`*^9}, { 308 | 3.7997601022880583`*^9, 3.799760111184224*^9}}, 309 | CellID->10494712,ExpressionUUID->"a717bb5b-d598-4684-a4d2-2325577685ac"] 310 | }, Open ]] 311 | }, Open ]], 312 | 313 | Cell[CellGroupData[{ 314 | 315 | Cell["Tutorials", "GuideTutorialsSection", 316 | CellID->415694126,ExpressionUUID->"3ca24ca6-1273-4b67-b6fb-aac4d9ca4b9d"], 317 | 318 | Cell[TextData[ButtonBox["CSSTools", 319 | BaseStyle->"Link", 320 | ButtonData->"paclet:CSSTools/tutorial/CSSTools"]], "GuideTutorial", 321 | CellChangeTimes->{{3.7618452298340945`*^9, 3.761845234580893*^9}}, 322 | CellID->806871991,ExpressionUUID->"717421b9-35be-4e27-aafb-89bdf7866184"], 323 | 324 | Cell["XXXX", "GuideTutorial", 325 | CellID->1885805579,ExpressionUUID->"3f3d2612-dd9b-442e-93fd-05aea4cc6148"] 326 | }, Open ]], 327 | 328 | Cell[CellGroupData[{ 329 | 330 | Cell["More About", "GuideMoreAboutSection", 331 | CellID->23220180,ExpressionUUID->"c4c7e779-dc62-456f-a9cd-5dfc7f84f64b"], 332 | 333 | Cell["XXXX", "GuideMoreAbout", 334 | CellID->1567025153,ExpressionUUID->"ed62ac3b-d0c9-467c-b99f-dd256402375f"], 335 | 336 | Cell["XXXX", "GuideMoreAbout", 337 | CellID->252299663,ExpressionUUID->"62caeb8e-f99b-44c7-aa74-d22e700dbbe7"] 338 | }, Open ]], 339 | 340 | Cell["Related Links", "GuideRelatedLinksSection", 341 | CellID->415694148,ExpressionUUID->"03f3a530-6cb3-417d-bfd1-8cf9cd53e760"] 342 | }, 343 | WindowSize->{870., 735.75}, 344 | WindowMargins->{{Automatic, 236.25}, {Automatic, 0}}, 345 | FrontEndVersion->"12.1 for Microsoft Windows (64-bit) (June 19, 2020)", 346 | StyleDefinitions->FrontEnd`FileName[{"Wolfram"}, "GuidePageStyles.nb", 347 | CharacterEncoding -> "UTF-8"], 348 | ExpressionUUID->"e2b7e4bc-c9c7-4e68-9e53-9a911fac4d6e" 349 | ] 350 | (* End of Notebook Content *) 351 | 352 | (* Internal cache information *) 353 | (*CellTagsOutline 354 | CellTagsIndex->{} 355 | *) 356 | (*CellTagsIndex 357 | CellTagsIndex->{} 358 | *) 359 | (*NotebookFileOutline 360 | Notebook[{ 361 | Cell[558, 20, 600, 14, 18, "History",ExpressionUUID->"3f228a90-67e3-4ddc-aba9-a30260165a01", 362 | CellID->1247902091], 363 | Cell[CellGroupData[{ 364 | Cell[1183, 38, 123, 1, 22, "CategorizationSection",ExpressionUUID->"49b8370b-fba4-43fd-8feb-61a22f3afb98", 365 | CellID->1122911449], 366 | Cell[1309, 41, 133, 2, 70, "Categorization",ExpressionUUID->"afefdc72-4615-44a1-a8e0-af54b52288ad", 367 | CellID->686433507], 368 | Cell[1445, 45, 136, 2, 70, "Categorization",ExpressionUUID->"2ae2ce4e-aff7-4c77-bb96-48ac12359267", 369 | CellID->605800465], 370 | Cell[1584, 49, 133, 2, 70, "Categorization",ExpressionUUID->"61dd1053-5793-48bf-bf29-331afbd03b25", 371 | CellID->468444828], 372 | Cell[1720, 53, 123, 1, 70, "Categorization",ExpressionUUID->"0e8027d0-a5f1-4054-bed7-e8a194cd5768"] 373 | }, Closed]], 374 | Cell[CellGroupData[{ 375 | Cell[1880, 59, 111, 1, 15, "KeywordsSection",ExpressionUUID->"120852a4-1ab9-4488-88a7-f502b583274a", 376 | CellID->1427428552], 377 | Cell[1994, 62, 100, 1, 70, "Keywords",ExpressionUUID->"0ae6185c-4b9c-43c4-a810-6b67bf388f86", 378 | CellID->1251852827] 379 | }, Closed]], 380 | Cell[CellGroupData[{ 381 | Cell[2131, 68, 108, 1, 15, "DetailsSection",ExpressionUUID->"e2325835-5bf9-4fea-b925-53e4db557e2d", 382 | CellID->307771771], 383 | Cell[2242, 71, 118, 2, 70, "Details",ExpressionUUID->"f56ab596-32d7-4da1-8bf5-90baf09e6c61", 384 | CellID->795394057], 385 | Cell[2363, 75, 124, 2, 70, "Details",ExpressionUUID->"5681448f-080c-407b-8713-4cba7ee95130", 386 | CellID->350963985], 387 | Cell[2490, 79, 118, 2, 70, "Details",ExpressionUUID->"50cc3ff9-0ec4-4a83-a2b0-9378c4ce01f3", 388 | CellID->802101], 389 | Cell[2611, 83, 126, 2, 70, "Details",ExpressionUUID->"33a10c42-452c-4b09-ae79-30801d6c1909", 390 | CellID->509823116], 391 | Cell[2740, 87, 116, 2, 70, "Details",ExpressionUUID->"535969ea-5525-4bd5-ad4e-418273868a9c", 392 | CellID->199884516], 393 | Cell[2859, 91, 116, 2, 70, "Details",ExpressionUUID->"df3a7c4b-bbf9-4aa9-bd63-05cdff2d38b6", 394 | CellID->463951815], 395 | Cell[2978, 95, 116, 2, 70, "Details",ExpressionUUID->"4f658b12-1c05-4518-ae92-ad067588a2a8", 396 | CellID->8237523], 397 | Cell[3097, 99, 133, 2, 70, "Details",ExpressionUUID->"ba2183a6-95c4-4c26-830e-f23e2f1f3c3f", 398 | CellID->813936640], 399 | Cell[3233, 103, 122, 2, 70, "Details",ExpressionUUID->"303fa587-fdc7-4a69-8e02-26b667c593f4", 400 | CellID->240026365] 401 | }, Closed]], 402 | Cell[CellGroupData[{ 403 | Cell[3392, 110, 226, 3, 57, "GuideTitle",ExpressionUUID->"a2dfbf4b-a400-497d-b964-cad8f8e0772e", 404 | CellID->942062912], 405 | Cell[3621, 115, 755, 11, 55, "GuideAbstract",ExpressionUUID->"b9255c52-39e9-48e0-bedb-b4fa7ec2beba", 406 | CellID->2001916300] 407 | }, Open ]], 408 | Cell[CellGroupData[{ 409 | Cell[4413, 131, 109, 1, 52, "GuideFunctionsSection",ExpressionUUID->"50d091ef-42cf-4d28-b7a3-da0423b384b3", 410 | CellID->1866139230], 411 | Cell[CellGroupData[{ 412 | Cell[4547, 136, 192, 2, 27, "GuideFunctionsSubsection",ExpressionUUID->"8d817216-d113-4b36-bc3d-a0f25f4d05de", 413 | CellID->811494718], 414 | Cell[4742, 140, 592, 14, 19, "GuideText",ExpressionUUID->"dee08810-36bd-4ef8-b550-71bf497466fd", 415 | CellID->100541697], 416 | Cell[5337, 156, 601, 12, 19, "GuideText",ExpressionUUID->"fa3304e9-15e7-4c88-80b5-5c41585afd56", 417 | CellID->203374175] 418 | }, Open ]], 419 | Cell[5953, 171, 103, 1, 22, "GuideDelimiter",ExpressionUUID->"92df8e96-2df7-4fb0-b6b7-28dfc06ca57c", 420 | CellID->622275174], 421 | Cell[CellGroupData[{ 422 | Cell[6081, 176, 239, 3, 27, "GuideFunctionsSubsection",ExpressionUUID->"5f8eaa5a-bc2f-4fac-88db-96866e681ff0", 423 | CellID->91319310], 424 | Cell[6323, 181, 644, 12, 31, "GuideText",ExpressionUUID->"22c8ab8e-8da0-47ea-8af6-3ed63aad5b8a", 425 | CellID->47789317], 426 | Cell[6970, 195, 532, 11, 19, "GuideText",ExpressionUUID->"9fff43cf-59ce-41dc-a1cd-c525790c844f", 427 | CellID->348206879] 428 | }, Open ]], 429 | Cell[7517, 209, 102, 1, 22, "GuideDelimiter",ExpressionUUID->"97bc2ebf-8ed5-4a50-830d-bcb39efb1d4e", 430 | CellID->71783130], 431 | Cell[CellGroupData[{ 432 | Cell[7644, 214, 251, 3, 27, "GuideFunctionsSubsection",ExpressionUUID->"3f2d20fc-7cdc-4adb-8fc5-a03b4a0fdbf4", 433 | CellID->159396722], 434 | Cell[7898, 219, 613, 12, 19, "GuideText",ExpressionUUID->"76b7ff53-5475-4aac-af5f-dfa262a0aec6", 435 | CellID->41288703], 436 | Cell[8514, 233, 442, 9, 19, "GuideText",ExpressionUUID->"a2cd85ab-f27a-4852-9806-a0247ac5cce9", 437 | CellID->46073956], 438 | Cell[8959, 244, 684, 13, 31, "GuideText",ExpressionUUID->"3d3dc613-bae0-45a3-970e-a82dcf688d97", 439 | CellID->2444546], 440 | Cell[9646, 259, 642, 12, 19, "GuideText",ExpressionUUID->"6ef07e31-cc99-4c06-84f5-6ec15c87c6b7", 441 | CellID->399786665] 442 | }, Open ]], 443 | Cell[10303, 274, 103, 1, 22, "GuideDelimiter",ExpressionUUID->"bd8319f4-05f5-4ea8-af26-0dfcea2bc15f", 444 | CellID->294180157], 445 | Cell[CellGroupData[{ 446 | Cell[10431, 279, 243, 3, 27, "GuideFunctionsSubsection",ExpressionUUID->"4fb25de5-3a55-44c3-ac83-960ebfc02839", 447 | CellID->262714310], 448 | Cell[10677, 284, 520, 11, 19, "GuideText",ExpressionUUID->"06fc4090-62d9-461f-88f5-ac3889552ddc", 449 | CellID->213621991], 450 | Cell[11200, 297, 523, 11, 19, "GuideText",ExpressionUUID->"a717bb5b-d598-4684-a4d2-2325577685ac", 451 | CellID->10494712] 452 | }, Open ]] 453 | }, Open ]], 454 | Cell[CellGroupData[{ 455 | Cell[11772, 314, 117, 1, 54, "GuideTutorialsSection",ExpressionUUID->"3ca24ca6-1273-4b67-b6fb-aac4d9ca4b9d", 456 | CellID->415694126], 457 | Cell[11892, 317, 267, 4, 17, "GuideTutorial",ExpressionUUID->"717421b9-35be-4e27-aafb-89bdf7866184", 458 | CellID->806871991], 459 | Cell[12162, 323, 105, 1, 17, "GuideTutorial",ExpressionUUID->"3f3d2612-dd9b-442e-93fd-05aea4cc6148", 460 | CellID->1885805579] 461 | }, Open ]], 462 | Cell[CellGroupData[{ 463 | Cell[12304, 329, 117, 1, 54, "GuideMoreAboutSection",ExpressionUUID->"c4c7e779-dc62-456f-a9cd-5dfc7f84f64b", 464 | CellID->23220180], 465 | Cell[12424, 332, 106, 1, 17, "GuideMoreAbout",ExpressionUUID->"ed62ac3b-d0c9-467c-b99f-dd256402375f", 466 | CellID->1567025153], 467 | Cell[12533, 335, 105, 1, 17, "GuideMoreAbout",ExpressionUUID->"62caeb8e-f99b-44c7-aa74-d22e700dbbe7", 468 | CellID->252299663] 469 | }, Open ]], 470 | Cell[12653, 339, 124, 1, 54, "GuideRelatedLinksSection",ExpressionUUID->"03f3a530-6cb3-417d-bfd1-8cf9cd53e760", 471 | CellID->415694148] 472 | } 473 | ] 474 | *) 475 | 476 | -------------------------------------------------------------------------------- /docbuild.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 86 | 87 | 88 | 89 | 90 | 91 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 114 | 115 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | --------------------------------------------------------------------------------