Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Parse CSS styles and swap background position value Date: Mon, 02 Feb 2015 18:17:20 +0100 Organization: PointedEars Software (PES) Lines: 145 Message-ID: <7622963.yZKU775dzf@PointedEars.de> References: <8be9bcae-a221-46e1-8e0f-ec41632517a4@googlegroups.com> <54cf68f5$0$2870$e4fe514c@news2.news.xs4all.nl> <1609092.d9bYY2oEu8@PointedEars.de> <54cf7dfa$0$2962$e4fe514c@news2.news.xs4all.nl> Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1422897479 16922 eJwNwoERwEAEBMCW4rlDOcjrv4RkdqEUjhtBw2LdNirLpfP86gbGNadV2NeOGcB64ryexdAPERYQWg== (2 Feb 2015 17:17:59 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Mon, 2 Feb 2015 17:17:59 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwNy8EBwCAIA8CVxBDAcUBk/xHa+x9hYtfVaMrhyHt1hZZr5YoZ13iAgo3q0EQ0j3cyvMSrTtvs809Y1W5+WFMVnA== Cancel-Lock: sha1:VcHGkH+PL2FXXJcf3RvSmyi/Bg4= X-NNTP-Posting-Host: eJwNxMkRwDAIBLCWiPdgUo6Nof8SEj0k+HElLVOjaXnu+G/rII0ONNRvBkzu4LAO1s2olbE+JCEQzQ== Xref: csiph.com comp.lang.javascript:26778 Erwin Moller wrote: > On 2/2/2015 2:01 PM, Thomas 'PointedEars' Lahn wrote: >> Erwin Moller wrote: >>> On 1/31/2015 7:39 PM, Cezary Tomczyk wrote: >>>> Here is a sample of CSS (the properties are repeated, but this is just >>>> for example to test regular expression): >>>> […] >>>> My goal is to find all "background" properties and then swap horizontal >>>> position value from left to right or right to left or value% to (100% - >>>> value%). >>>> […] >>>> Here is the site where I play with regular expressions: >>>> https://www.regex101.com/r/sJ2uL5/1 >>> […] >>> I would load the file into a programming language of your choice (eg >>> PHP, Phyton, etc) and fix the CSS from there. >> […] >> But I do not see what difference that would make, unless >> there is a CSS library in either language that I am not aware of. >> Recursive regular expressions which are supported by Python and PCRE as >> supported by PHP can only get you that far. > > I wasn't suggesting a helper-CCS library at all. > My suggestion was to just find the declarations which mention > "background" or "background-*". What exactly did you have in mind, then? >> Or do not parse the stylesheet at all, but find the selectors that apply >> in the document.styleSheets NodeList and modify the property values >> there. > > That would be a fix at client-side of the CSS then. I am not sure I like > that idea (load on the client while the right CSS would suffice.). It is not my preferred approach either, although I have written ECMAScript- conforming code that allows one to access rules in the CSSOM by selector to make that easy. I find the OP’s problem description sufficiently imprecise to give a good recommendation as to the best approach. > I see where you are heading: using ; in the content. > > Yes, that would make my (not posted) algorithm fail horribly. > I stand corrected. > >>> I think that covers all appearances. >> >> It does not, of course. See the CSS 2.1 grammar to begin with. >> >> The used parser would have to recognize, in top-down order: media >> queries, rulesets, declarations, property names, and property values, in >> order to do >> something useful with property values. (And probably I have forgotten >> something else.) > > AAARGH, please stop! > > You convinced me completely. Now that I have given sufficient warning for the *general* case ;-), I should point out that, because of the restrictions in the CSS3 module specifications for background property values *so far*, this is a *special* case where you could find the pertinent declarations, and tell apart the property names and value *without* a full-blown CSS parser, under the following conditions: - Every background property declaration (even the last one in a ruleset, where it is optional) is terminated with a semicolon (otherwise, newlines complicate everything); - Property values do not contain semicolons (there is the syntactical possibility for semicolons in “data” URIs for the “background-image” property value or “background” property value component, for example); - Property values do not contain substrings that match a “background” or “background-position” property declaration. And then I am rather certain (also tested positive on the example code) that you can use /\bbackground(-position)?\s*:\s*([^;]+)\s*;/gi for matching. Still, the difficulty here is to tell apart the parts of the property value for exchanging their value ("$2"). Again, *iff* you can make sure that *all* percentages in the matched property values relate to horizontal background-position (which usually is _not_ the case: they can also be something that precedes a URI-encoded value for the background image; a radius, position or color stop of a gradient; the background size, or an RGB[A]/HSL[A] background color component, or the vertical background- position – did I miss anything?), then you could use … = value.replace(/\b(?:(left)|(right)|(\d+)%)\b/gi, function (match, left, right, percentage) { return (left ? "right" : (right ? "left" : (100 - percentage) + "%"))); }); But this does not work already in the case of background: url(example1.png) repeat-x right 50%; And the “right” value can be anywhere in the property value: Specifically, you have to exclude the cases where you found a percentage and either “left” or “right” (in any order) because that percentage, in the aforementioned context, refers to the *vertical* position instead. As is obvious now, even though it is generally possible to use regular expressions in this case, many conditions have to be met in order to make it possible. It is a lot easier to use the CSSOM instead (document.styleSheets, the return value of document.defaultView.getComputedStyle(…), or the “style” property): there you have the rulesets and declarations already parsed, and can access the “backgroundPosition” or “backgroundPositionX” property value directly where it should always be retrievable in percentages. >> It is not logical to rebuild a CSS parser when simpler >> measures would suffice. > > I am not familiar with Chomsky hierarchy, but after reading your post > I think I should. I have the feeling I wouldn't have posted my first > suggestion if I did know about Chomsky hierarchy. At least not in *that* way, for sure. > Thanks for the explanation. You’re welcome. > And good luck to OP fixing the CSS in another way. ACK. -- PointedEars FAQ: | SVN: Twitter: @PointedEars2 | ES Matrix: Please do not cc me. / Bitte keine Kopien per E-Mail.