00001 # TKE - Advanced Programmer's Editor 00002 # Copyright (C) 2014-2019 Trevor Williams (phase1geo@gmail.com) 00003 # 00004 # This program is free software; you can redistribute it and/or modify 00005 # it under the terms of the GNU General Public License as published by 00006 # the Free Software Foundation; either version 2 of the License, or 00007 # (at your option) any later version. 00008 # 00009 # This program is distributed in the hope that it will be useful, 00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 # GNU General Public License for more details. 00013 # 00014 # You should have received a copy of the GNU General Public License along 00015 # with this program; if not, write to the Free Software Foundation, Inc., 00016 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 00018 ###################################################################### 00019 # Name: emmet_css.tcl 00020 # Author: Trevor Williams (phase1geo@gmail.com) 00021 # Date: 03/17/2016 00022 # Brief: Namespace containing Emmet CSS-related functionality. 00023 ###################################################################### 00024 00025 namespace eval emmet_css { 00026 00027 array set lookup { 00028 pos {{position} {{|relative}}} 00029 pos:s {{position} {static}} 00030 pos:a {{position} {absolute}} 00031 pos:r {{position} {relative}} 00032 pos:f {{position} {fixed}} 00033 t {{top} {{|}}} 00034 t:a {{top} {auto}} 00035 r {{right} {{|}}} 00036 r:a {{right} {auto}} 00037 b {{bottom} {{|}}} 00038 b:a {{bottom} {auto}} 00039 l {{left} {{|}}} 00040 l:a {{left} {auto}} 00041 z {{z-index} {{|}}} 00042 z:a {{z-index} {auto}} 00043 fl {{float} {{|left}}} 00044 fl:n {{float} {none}} 00045 fl:l {{float} {left}} 00046 fl:r {{float} {right}} 00047 cl {{clear} {{|both}}} 00048 cl:n {{clear} {none}} 00049 cl:l {{clear} {left}} 00050 cl:r {{clear} {right}} 00051 cl:b {{clear} {both}} 00052 d {{display} {{|block}}} 00053 d:n {{display} {none}} 00054 d:b {{display} {block}} 00055 d:i {{display} {inline}} 00056 d:ib {{display} {inline-block}} 00057 d:li {{display} {list-item}} 00058 d:cp {{display} {compact}} 00059 d:tb {{display} {table}} 00060 d:itb {{display} {inline-table}} 00061 d:tbcp {{display} {table-caption}} 00062 d:tbcl {{display} {table-column}} 00063 d:tbclg {{display} {table-column-group}} 00064 d:tbhg {{display} {table-header-group}} 00065 d:tbfg {{display} {table-footer-group}} 00066 d:tbr {{display} {table-row}} 00067 d:tbrg {{display} {table-row-group}} 00068 d:tbc {{display} {table-cell}} 00069 d:rb {{display} {ruby}} 00070 d:rbb {{display} {ruby-base}} 00071 d:rbbg {{display} {ruby-base-group}} 00072 d:rbt {{display} {ruby-text}} 00073 d:rbtg {{display} {ruby-text-group}} 00074 v {{visibility} {{|hidden}}} 00075 v:v {{visibility} {visible}} 00076 v:h {{visibility} {hidden}} 00077 v:c {{visibility} {collapse}} 00078 ov {{overflow} {{|hidden}}} 00079 ov:v {{overflow} {visible}} 00080 ov:h {{overflow} {hidden}} 00081 ov:s {{overflow} {scroll}} 00082 ov:a {{overflow} {auto}} 00083 ovx {{overflow-x} {{|hidden}}} 00084 ovx:v {{overflow-x} {visible}} 00085 ovx:h {{overflow-x} {hidden}} 00086 ovx:s {{overflow-x} {scroll}} 00087 ovx:a {{overflow-x} {auto}} 00088 ovy {{overflow-y} {{|hidden}}} 00089 ovy:v {{overflow-y} {visible}} 00090 ovy:h {{overflow-y} {hidden}} 00091 ovy:s {{overflow-y} {scroll}} 00092 ovy:a {{overflow-y} {auto}} 00093 ovs {{overflow-style} {{|scrollbar}}} 00094 ovs:a {{overflow-style} {auto}} 00095 ovs:s {{overflow-style} {scrollbar}} 00096 ovs:p {{overflow-style} {panner}} 00097 ovs:m {{overflow-style} {move}} 00098 ovs:mq {{overflow-style} {marquee}} 00099 zoo {{zoom} {1}} 00100 zm {{zoom} {1}} 00101 cp {{clip} {{|}}} 00102 cp:a {{clip} {auto}} 00103 cp:r {{clip} {rect({|top}, {|right}, {|bottom}, {|left})}} 00104 rsz {{resize} {{|}}} 00105 rsz:n {{resize} {none}} 00106 rsz:b {{resize} {both}} 00107 rsz:h {{resize} {horizontal}} 00108 rsz:v {{resize} {vertical}} 00109 cur {{cursor} {{|pointer}}} 00110 cur:a {{cursor} {auto}} 00111 cur:d {{cursor} {default}} 00112 cur:c {{cursor} {crosshair}} 00113 cur:ha {{cursor} {hand}} 00114 cur:he {{cursor} {help}} 00115 cur:m {{cursor} {move}} 00116 cur:p {{cursor} {pointer}} 00117 cur:t {{cursor} {text}} 00118 m {{margin} {{|}}} 00119 m:a {{margin} {auto}} 00120 mt {{margin-top} {{|}}} 00121 mt:a {{margin-top} {auto}} 00122 mr {{margin-right} {{|}}} 00123 mr:a {{margin-right} {auto}} 00124 mb {{margin-bottom} {{|}}} 00125 mb:a {{margin-bottom} {auto}} 00126 ml {{margin-left} {{|}}} 00127 ml:a {{margin-left} {auto}} 00128 p {{padding} {{|}}} 00129 pt {{padding-top} {{|}}} 00130 pr {{padding-right} {{|}}} 00131 pb {{padding-bottom} {{|}}} 00132 pl {{padding-left} {{|}}} 00133 bxz {{box-sizing} {{|border-box}}} 00134 bxz:cb {{box-sizing} {content-box}} 00135 bxz:bb {{box-sizing} {border-box}} 00136 bxsh {{box-shadow} {{|inset} {|hoff} {|voff} {|blur} {|color}}} 00137 bxsh:r {{box-shadow} {{|inset} {|hoff} {|voff} {|blur} {|spread} rgb({|0}, {|0}, {|0})}} 00138 bxsh:ra {{box-shadow} {{|inset} {|h} {|v} {|blur} {|spread} rgba({|0}, {|0}, {|0}, {|.5})}} 00139 bxsh:n {{box-shadow} {none}} 00140 w {{width} {{|}}} 00141 w:a {{width} {auto}} 00142 h {{height} {{|}}} 00143 h:a {{height} {auto}} 00144 maw {{max-width} {{|}}} 00145 maw:n {{max-width} {none}} 00146 mah {{max-height} {{|}}} 00147 mah:n {{max-height} {none}} 00148 miw {{min-width} {{|}}} 00149 mih {{min-height} {{|}}} 00150 f {{font} {{|}}} 00151 f+ {{font} {{|1em} {|Arial,sans-serif}}} 00152 fw {{font-weight} {{|}}} 00153 fw:n {{font-weight} {none}} 00154 fw:b {{font-weight} {bold}} 00155 fw:br {{font-weight} {bolder}} 00156 fw:lr {{font-weight} {lighter}} 00157 fs {{font-style} {{|italic}}} 00158 fs:n {{font-style} {normal}} 00159 fs:i {{font-style} {italic}} 00160 fs:o {{font-style} {oblique}} 00161 fv {{font-variant} {{|}}} 00162 fv:sc {{font-variant} {small-caps}} 00163 fz {{font-size} {{|}}} 00164 fza {{font-size-adjust} {{|}}} 00165 fza:n {{font-size-adjust} {none}} 00166 ff {{font-family} {{|}}} 00167 ff:s {{font-family} {serif}} 00168 ff:ss {{font-family} {sans-serif}} 00169 ff:c {{font-family} {cursive}} 00170 ff:f {{font-family} {fantasy}} 00171 ff:m {{font-family} {monospace}} 00172 ff:a {{font-family} {Arial, "Helvetica Neue", Helvetica, sans-serif}} 00173 fef {{font-effect} {{|}}} 00174 fef:n {{font-effect} {none}} 00175 fef:eg {{font-effect} {engrave}} 00176 fef:eb {{font-effect} {emboss}} 00177 fef:o {{font-effect} {outline}} 00178 fem {{font-emphasize} {{|}}} 00179 femp {{font-emphasize-position} {{|}}} 00180 femp:b {{font-emphasize-position} {before}} 00181 femp:a {{font-emphasize-position} {after}} 00182 fems {{font-emphasize-style} {{|}}} 00183 fems:n {{font-emphasize-style} {none}} 00184 fems:ac {{font-emphasize-style} {accent}} 00185 fems:dt {{font-emphasize-style} {dot}} 00186 fems:c {{font-emphasize-style} {circle}} 00187 fems:ds {{font-emphasize-style} {disc}} 00188 fsm {{font-smooth} {{|}}} 00189 fsm:a {{font-smooth} {auto}} 00190 fsm:n {{font-smooth} {never}} 00191 fsm:aw {{font-smooth} {always}} 00192 fst {{font-stretch} {{|}}} 00193 fst:n {{font-stretch} {normal}} 00194 fst:uc {{font-stretch} {ultra-condensed}} 00195 fst:ec {{font-stretch} {extra-condensed}} 00196 fst:c {{font-stretch} {condensed}} 00197 fst:sc {{font-stretch} {semi-condensed}} 00198 fst:se {{font-stretch} {semi-expanded}} 00199 fst:e {{font-stretch} {expanded}} 00200 fst:ee {{font-stretch} {extra-expanded}} 00201 fst:ue {{font-stretch} {ultra-expanded}} 00202 va {{vertical-align} {top}} 00203 va:sup {{vertical-align} {super}} 00204 va:t {{vertical-align} {top}} 00205 va:tt {{vertical-align} {text-top}} 00206 va:m {{vertical-align} {middle}} 00207 va:bl {{vertical-align} {baseline}} 00208 va:b {{vertical-align} {bottom}} 00209 va:tb {{vertical-align} {text-bottom}} 00210 va:sub {{vertical-align} {sub}} 00211 ta {{text-align} {{|left}}} 00212 ta:l {{text-align} {left}} 00213 ta:c {{text-align} {center}} 00214 ta:r {{text-align} {right}} 00215 ta:j {{text-align} {justify}} 00216 ta-lst {{text-align-last} {{|}}} 00217 tal:a {{text-align-last} {auto}} 00218 tal:l {{text-align-last} {left}} 00219 tal:c {{text-align-last} {center}} 00220 tal:r {{text-align-last} {right}} 00221 td {{text-decoration} {{|none}}} 00222 td:n {{text-decoration} {none}} 00223 td:u {{text-decoration} {underline}} 00224 td:o {{text-decoration} {overline}} 00225 td:l {{text-decoration} {line-through}} 00226 te {{text-emphasis} {{|}}} 00227 te:n {{text-emphasis} {none}} 00228 te:ac {{text-emphasis} {accent}} 00229 te:dt {{text-emphasis} {dot}} 00230 te:c {{text-emphasis} {circle}} 00231 te:ds {{text-emphasis} {disc}} 00232 te:b {{text-emphasis} {before}} 00233 te:a {{text-emphasis} {after}} 00234 th {{text-height} {{|}}} 00235 th:a {{text-height} {auto}} 00236 th:f {{text-height} {font-size}} 00237 th:t {{text-height} {text-size}} 00238 th:m {{text-height} {max-size}} 00239 ti {{text-indent} {{|}}} 00240 ti:- {{text-indent} {-9999px}} 00241 tj {{text-justify} {{|}}} 00242 tj:a {{text-justify} {auto}} 00243 tj:iw {{text-justify} {inter-word}} 00244 tj:ii {{text-justify} {inter-ideograph}} 00245 tj:ic {{text-justify} {inter-cluster}} 00246 tj:d {{text-justify} {distribute}} 00247 tj:k {{text-justify} {kashida}} 00248 tj:t {{text-justify} {tibetan}} 00249 to {{text-outline} {{|}}} 00250 to+ {{text-outline} {0 0 #000}} 00251 to:n {{text-outline} {none}} 00252 tr {{text-replace} {{|}}} 00253 tr:n {{text-replace} {none}} 00254 tt {{text-transform} {{|uppercase}}} 00255 tt:n {{text-transform} {none}} 00256 tt:c {{text-transform} {capitalize}} 00257 tt:u {{text-transform} {uppercase}} 00258 tt:l {{text-transform} {lowercase}} 00259 tw {{text-wrap} {{|}}} 00260 tw:n {{text-wrap} {normal}} 00261 tw:no {{text-wrap} {none}} 00262 tw:u {{text-wrap} {unrestricted}} 00263 tw:s {{text-wrap} {suppress}} 00264 tsh {{text-shadow} {{|hoff} {|voff} {|blur} {|#000}}} 00265 tsh:r {{text-shadow} {{|h} {|v} {|blur} rgb({|0}, {|0}, {|0})}} 00266 tsh:ra {{text-shadow} {{|h} {|v} {|blur} rgb({|0}, {|0}, {|0}, {|.5})}} 00267 tsh+ {{text-shadow} {{|0} {|0} {|0} {|#000}}} 00268 tsh:n {{text-shadow} {none}} 00269 lh {{line-height} {{|}}} 00270 lts {{letter-spacing} {{|}}} 00271 whs {{white-space} {{|}}} 00272 whs:n {{white-space} {normal}} 00273 whs:p {{white-space} {pre}} 00274 whs:nw {{white-space} {nowrap}} 00275 whs:pw {{white-space} {pre-wrap}} 00276 whs:pl {{white-space} {pre-line}} 00277 whsc {{white-space-collapse} {{|}}} 00278 whsc:n {{white-space-collapse} {normal}} 00279 whsc:k {{white-space-collapse} {keep-all}} 00280 whsc:l {{white-space-collapse} {loose}} 00281 whsc:bs {{white-space-collapse} {break-strict}} 00282 whsc:ba {{white-space-collapse} {break-all}} 00283 wob {{word-break} {{|}}} 00284 wob:n {{word-break} {normal}} 00285 wob:k {{word-break} {keep-all}} 00286 wob:l {{word-break} {loose}} 00287 wob:bs {{word-break} {break-strict}} 00288 wob:ba {{word-break} {break-all}} 00289 wos {{word-spacking} {{|}}} 00290 wow {{word-wrap} {{|}}} 00291 wow:nm {{word-wrap} {normal}} 00292 wow:n {{word-wrap} {none}} 00293 wow:u {{word-wrap} {unrestricted}} 00294 wow:s {{word-wrap} {suppress}} 00295 wow:b {{word-wrap} {break-word}} 00296 bg {{background} {{|}}} 00297 bg+ {{background} {{|#fff} url({|}) {|0} {|0} {|no-repeat}}} 00298 bg:n {{background} {none}} 00299 bgc {{background-color} {{|#fff}}} 00300 bgc:t {{background-color} {transparent}} 00301 bgi {{background-image} {url({|})}} 00302 bgi:n {{background-image} {none}} 00303 bgr {{background-repeat} {{|}}} 00304 bgr:n {{background-repeat} {no-repeat}} 00305 bgr:x {{background-repeat} {repeat-x}} 00306 bgr:y {{background-repeat} {repeat-y}} 00307 bgr:sp {{background-repeat} {space}} 00308 bgr:rd {{background-repeat} {round}} 00309 bga {{background-attachment} {{|}}} 00310 bga:f {{background-attachment} {fixed}} 00311 bga:s {{background-attachment} {scroll}} 00312 bgp {{background-position} {{|0} {|0}}} 00313 bgpx {{background-position-x} {{|}}} 00314 bgpy {{background-position-y} {{|}}} 00315 bgbk {{background-break} {{|}}} 00316 bgbk:bb {{background-break} {bounding-box}} 00317 bgbk:eb {{background-break} {each-box}} 00318 bgbk:c {{background-break} {continuous}} 00319 bgcp {{background-clip} {{|padding-box}}} 00320 bgcp:bb {{background-clip} {border-box}} 00321 bgcp:pb {{background-clip} {padding-box}} 00322 bgcp:cb {{background-clip} {content-box}} 00323 bgcp:nc {{background-clip} {no-clip}} 00324 bgo {{background-origin} {{|}}} 00325 bgo:pb {{background-origin} {padding-box}} 00326 bgo:bb {{background-origin} {border-box}} 00327 bgo:cb {{background-origin} {content-box}} 00328 bgsz {{background-size} {{|}}} 00329 bgsz:a {{background-size} {auto}} 00330 bgsz:ct {{background-size} {contain}} 00331 bgsz:cv {{background-size} {cover}} 00332 c {{color} {{|#000}}} 00333 c:r {{color} {rgb({|0}, {|0}, {|0})}} 00334 c:ra {{color} {rgb({|0}, {|0}, {|0}, {|.5})}} 00335 op {{opacity} {{|}}} 00336 cnt {{content} {'{|}'}} 00337 cnt:n {{content} {normal}} 00338 ct:n {{content} {normal}} 00339 cnt:oq {{content} {open-quote}} 00340 ct:oq {{content} {open-quote}} 00341 cnt:noq {{content} {no-open-quote}} 00342 ct:noq {{content} {no-open-quote}} 00343 cnt:cq {{content} {close-quote}} 00344 ct:cq {{content} {close-quote}} 00345 cnt:ncq {{content} {no-close-quote}} 00346 ct:ncq {{content} {no-close-quote}} 00347 cnt:a {{content} {attr({|})}} 00348 ct:a {{content} {attr({|})}} 00349 cnt:c {{content} {counter({|})}} 00350 ct:c {{content} {counter({|})}} 00351 cnt:cs {{content} {counters({|})}} 00352 ct:cs {{content} {counters({|})}} 00353 ct {{content} {{|}}} 00354 q {{quotes} {{|}}} 00355 q:n {{quotes} {none}} 00356 q:ru {{quotes} {'\00AB' '\00BB' '\201E' '\201C'}} 00357 q:en {{quotes} {'\201C' '\201D' '\2018' '\2019'}} 00358 coi {{counter-increment} {{|}}} 00359 cor {{counter-reset} {{|}}} 00360 ol {{outline} {{|}}} 00361 ol:n {{outline} {none}} 00362 olo {{outline-offset} {{|}}} 00363 olw {{outline-width} {{|}}} 00364 ols {{outline-style} {{|}}} 00365 olc {{outline-color} {#{|000}}} 00366 olc:i {{outline-color} {invert}} 00367 tbl {{table-layout} {{|}}} 00368 tbl:a {{table-layout} {auto}} 00369 tbl:f {{table-layout} {fixed}} 00370 cps {{caption-side} {{|}}} 00371 cps:t {{caption-side} {top}} 00372 cps:b {{caption-side} {bottom}} 00373 ec {{empty-cells} {{|}}} 00374 ec:s {{empty-cells} {show}} 00375 ec:h {{empty-cells} {hide}} 00376 bd {{border} {{|}}} 00377 bd+ {{border} {{|1px} {|solid} {|#000}}} 00378 bd:n {{border} {none}} 00379 bdbk {{border-break} {{|close}}} 00380 bdbk:c {{border-break} {close}} 00381 bdcl {{border-collapse} {{|}}} 00382 bdcl:c {{border-collapse} {collapse}} 00383 bdcl:s {{border-collapse} {separate}} 00384 bdc {{border-color} {#{|000}}} 00385 bdc:t {{border-color} {transparent}} 00386 bdi {{border-image} {url({|})}} 00387 bdi:n {{border-image} {none}} 00388 bdti {{border-top-image} {url({|})}} 00389 bdti:n {{border-top-image} {none}} 00390 bdri {{border-right-image} {url({|})}} 00391 bdri:n {{border-right-image} {none}} 00392 bdbi {{border-bottom-image} {url({|})}} 00393 bdbi:n {{border-bottom-image} {none}} 00394 bdli {{border-left-image} {url({|})}} 00395 bdli:n {{border-left-image} {none}} 00396 bdci {{border-corner-image} {url({|})}} 00397 bdci:n {{border-corner-image} {none}} 00398 bdci:c {{border-corner-image} {continue}} 00399 bdtli {{border-top-left-image} {url({|})}} 00400 bdtli:n {{border-top-left-image} {none}} 00401 bdtli:c {{border-top-left-image} {continue}} 00402 bdtri {{border-top-right-image} {url({|})}} 00403 bdtri:n {{border-top-right-image} {none}} 00404 bdtri:c {{border-top-right-image} {continue}} 00405 bdbri {{border-bottom-right-image} {url({|})}} 00406 bdbri:n {{border-bottom-right-image} {none}} 00407 bdbri:c {{border-bottom-right-image} {continue}} 00408 bdbli {{border-bottom-left-image} {url({|})}} 00409 bdbli:n {{border-bottom-left-image} {none}} 00410 bdbli:c {{border-bottom-left-image} {continue}} 00411 bdf {{border-fit} {{|repeat}}} 00412 bdf:c {{border-fit} {clip}} 00413 bdf:r {{border-fit} {repeat}} 00414 bdf:sc {{border-fit} {scale}} 00415 bdf:st {{border-fit} {stretch}} 00416 bdf:ow {{border-fit} {overwrite}} 00417 bdf:of {{border-fit} {overflow}} 00418 bdf:sp {{border-fit} {space}} 00419 bdlen {{border-length} {{|}}} 00420 bdlen:a {{border-length} {auto}} 00421 bdsp {{border-spacing} {{|}}} 00422 bds {{border-style} {{|}}} 00423 bds:n {{border-style} {none}} 00424 bds:h {{border-style} {hidden}} 00425 bds:dt {{border-style} {dotted}} 00426 bds:ds {{border-style} {dashed}} 00427 bds:s {{border-style} {solid}} 00428 bds:db {{border-style} {double}} 00429 bds:dtds {{border-style} {dot-dash}} 00430 bds:dtdtds {{border-style} {dot-dot-dash}} 00431 bds:w {{border-style} {wave}} 00432 bds:g {{border-style} {groove}} 00433 bds:r {{border-style} {ridge}} 00434 bds:i {{border-style} {inset}} 00435 bds:o {{border-style} {outset}} 00436 bdw {{border-width} {{|}}} 00437 bdt {{border-top} {{|}}} 00438 bt {{border-top} {{|}}} 00439 bdt+ {{border-top} {{|1px} {|solid} {|#000}}} 00440 bdt:n {{border-top} {none}} 00441 bdtw {{border-top-width} {{|}}} 00442 bdts {{border-top-style} {{|}}} 00443 bdts:n {{border-top-style} {none}} 00444 bdtc {{border-top-color} {#{|000}}} 00445 bdtc:t {{border-top-color} {transparent}} 00446 bdr {{border-right} {{|}}} 00447 br {{border-right} {{|}}} 00448 bdr+ {{border-right} {{|1px} {|solid} {|#000}}} 00449 bdr:n {{border-right} {none}} 00450 bdrw {{border-right-width} {{|}}} 00451 bdrst {{border-right-style} {{|}}} 00452 bdrst:n {{border-right-style} {none}} 00453 bdrc {{border-right-color} {#{|000}}} 00454 bdrc:t {{border-right-color} {transparent}} 00455 bdb {{border-bottom} {{|}}} 00456 bb {{border-bottom} {{|}}} 00457 bdb+ {{border-bottom} {{|1px} {|solid} {|#000}}} 00458 bdb:n {{border-bottom} {none}} 00459 bdbw {{border-bottom-width} {{|}}} 00460 bdbs {{border-bottom-style} {{|}}} 00461 bdbs:n {{border-bottom-style} {none}} 00462 bdbc {{border-bottom-color} {#{|000}}} 00463 bdbc:t {{border-bottom-color} {transparent}} 00464 bdl {{border-left} {{|}}} 00465 bl {{border-left} {{|}}} 00466 bdl+ {{border-left} {{|1px} {|solid} {|#000}}} 00467 bdl:n {{border-left} {none}} 00468 bdlw {{border-left-width} {{|}}} 00469 bdls {{border-left-style} {{|}}} 00470 bdls:n {{border-left-style} {none}} 00471 bdlc {{border-left-color} {#{|000}}} 00472 bdlc:t {{border-left-color} {transparent}} 00473 bdrs {{border-radius} {{|}}} 00474 bdtrrs {{border-top-right-radius} {{|}}} 00475 bdtlrs {{border-top-left-radius} {{|}}} 00476 bdbrrs {{border-bottom-right-radius} {{|}}} 00477 bdblrs {{border-bottom-left-radius} {{|}}} 00478 lis {{list-style} {{|}}} 00479 lis:n {{list-style} {none}} 00480 lisp {{list-style-position} {{|}}} 00481 lisp:i {{list-style-position} {inside}} 00482 lisp:o {{list-style-position} {outside}} 00483 list {{list-style-type} {{|}}} 00484 list:n {{list-style-type} {none}} 00485 list:d {{list-style-type} {disc}} 00486 list:c {{list-style-type} {circle}} 00487 list:s {{list-style-type} {square}} 00488 list:dc {{list-style-type} {decimal}} 00489 list:dclz {{list-style-type} {decimal-leading-zero}} 00490 list:lr {{list-style-type} {lower-roman}} 00491 list:ur {{list-style-type} {upper-roman}} 00492 lisi {{list-style-image} {{|}}} 00493 lisi:n {{list-style-image} {none}} 00494 pgbb {{page-break-before} {{|}}} 00495 pgbb:au {{page-break-before} {auto}} 00496 pgbb:al {{page-break-before} {always}} 00497 pgbb:l {{page-break-before} {left}} 00498 pgbb:r {{page-break-before} {right}} 00499 pgbi {{page-break-inside} {{|}}} 00500 pgbi:au {{page-break-inside} {auto}} 00501 pgbi:av {{page-break-inside} {avoid}} 00502 pgba {{page-break-after} {{|}}} 00503 pgba:au {{page-break-after} {auto}} 00504 pgba:al {{page-break-after} {always}} 00505 pgba:l {{page-break-after} {left}} 00506 pgba:r {{page-break-after} {right}} 00507 orp {{orphans} {{|}}} 00508 wid {{widows} {{|}}} 00509 anim {{animation} {{|}}} 00510 anim- {{animation} {{|name} {|duration} {|timing-function} {|delay} {|iteration} {|direction} {|fill-mode}}} 00511 animdel {{animation-delay} {{|time}}} 00512 animdir {{animation-direction} {{|normal}}} 00513 animdir:a {{animation-direction} {alternate}} 00514 animdir:ar {{animation-direction} {alternate-reverse}} 00515 animdir:n {{animation-direction} {normal}} 00516 animdir:r {{animation-direction} {reverse}} 00517 animdur {{animation-duration} {{|0}s}} 00518 animfm {{animation-fill-mode} {{|both}}} 00519 animfm:b {{animation-fill-mode} {backwards}} 00520 animfm:bt {{animation-fill-mode} {both}} 00521 animfm:bh {{animation-fill-mode} {both}} 00522 animfm:f {{animation-fill-mode} {forwards}} 00523 animic {{animation-iteration-count} {{|1}}} 00524 animic:i {{animation-iteration-count} {infinite}} 00525 animn {{animation-name} {{|none}}} 00526 animps {{animation-play-state} {{|running}}} 00527 animps:p {{animation-play-state} {paused}} 00528 animps:r {{animation-play-state} {running}} 00529 animtf {{animation-timing-function} {{|linear}}} 00530 animtf:cb {{animation-timing-function} {cubic-bezier({|0.1}, {|0.7}, {|1.0}, {|0.1})}} 00531 animtf:e {{animation-timing-function} {ease}} 00532 animtf:ei {{animation-timing-function} {ease-in}} 00533 animtf:eio {{animation-timing-function} {ease-in-out}} 00534 animtf:eo {{animation-timing-function} {ease-out}} 00535 animtf:l {{animation-timing-function} {linear}} 00536 ap {{appearance} {${none}}} 00537 bg:ie {{filter:progid} {DXImateTransform.Microsoft.AlphaImageLoader(src='{|x}.png', sizingMethod='{|crop}')}} 00538 colm {{columns} {{|}}} 00539 colmc {{column-count} {{|}}} 00540 colmf {{column-fill} {{|}}} 00541 colmg {{column-gap} {{|}}} 00542 colmr {{column-rule} {{|}}} 00543 colmrc {{column-rule-color} {{|}}} 00544 colmrs {{column-rule-style} {{|}}} 00545 colmrw {{column-rule-width} {{|}}} 00546 colms {{column-span} {{|}}} 00547 colmw {{column-width} {{|}}} 00548 mar {{max-resolution} {{|res}}} 00549 mir {{min-resolution} {{|res}}} 00550 op:ie {{filter:progid} {DXImageTransform.Microsoft.Alpha(Opacity=100)}} 00551 op:ms {{-ms-filter} {'progid:DXImageTransform.Microsoft.Alpha(Opacity=100)'}} 00552 ori {{orientation} {{|}}} 00553 ori:l {{orientation} {landscape}} 00554 ori:p {{orientation} {portrait}} 00555 tov {{text-overflow} {{|ellipsis}}} 00556 tov:c {{text-overflow} {clip}} 00557 tov:e {{text-overflow} {ellipsis}} 00558 trf {{transform} {{|}}} 00559 trf:r {{transform} {rotate({|angle})}} 00560 trf:sc {{transform} {scale({|x}, {|y})}} 00561 trf:scx {{transform} {scaleX({|x})}} 00562 trf:scy {{transform} {scaleY({|y})}} 00563 trf:skx {{transform} {skewX({|angle})}} 00564 trf:sky {{transform} {skewY({|angle})}} 00565 trf:t {{transform} {translate({|x}, {|y})}} 00566 trf:tx {{transform} {translateX({|x})}} 00567 trf:ty {{transform} {translateY({|y})}} 00568 trfo {{transform-origin} {{|}}} 00569 trfs {{transform-style} {{|preserve-3d}}} 00570 trs {{transition} {{|prop} {|time}}} 00571 trsde {{transition-delay} {{|time}}} 00572 trsdu {{transition-duration} {{|time}}} 00573 trsp {{transition-property} {{|prop}}} 00574 trstf {{transition-timing-function} {{|tfunc}}} 00575 us {{user-select} {${none}}} 00576 wfsm {{-webkit-font-smoothing} {{|antialiased}}} 00577 wfsm:a {{-webkit-font-smoothing} {antialiased}} 00578 wfsm:n {{-webkit-font-smoothing} {none}} 00579 wfsm:s {{-webkit-font-smoothing} {subpixel-antialiased}} 00580 wfsm:sa {{-webkit-font-smoothing} {subpixel-antialiased}} 00581 } 00582 00583 array set vendor_props { 00584 accelerator {s} 00585 accesskey {o} 00586 animation {wo} 00587 animation-delay {wmo} 00588 animation-direction {wmo} 00589 animation-duration {wmo} 00590 animation-fill-mode {wmo} 00591 animation-iteration-count {wmo} 00592 animation-name {wmo} 00593 animation-play-state {wmo} 00594 animation-timing-function {wmo} 00595 appearance {wm} 00596 backface-visibility {wms} 00597 background-clip {wm} 00598 background-composite {w} 00599 background-inline-policy {m} 00600 background-origin {w} 00601 background-position-y {s} 00602 background-size {w} 00603 behavior {s} 00604 binding {m} 00605 block-progression {s} 00606 border-bottom-colors {m} 00607 border-fit {w} 00608 border-horizontal-spacing {w} 00609 border-image {wmo} 00610 border-left-colors {m} 00611 border-radius {wm} 00612 border-right-colors {m} 00613 border-top-colors {m} 00614 border-vertical-spacing {w} 00615 box-align {wms} 00616 box-direction {wms} 00617 box-flex {wms} 00618 box-flex-group {w} 00619 box-line-progression {s} 00620 box-lines {ws} 00621 box-ordinal-group {wms} 00622 box-orient {wms} 00623 box-pack {wms} 00624 box-reflect {w} 00625 box-shadow {wm} 00626 box-sizing {wm} 00627 color-correction {w} 00628 column-break-after {w} 00629 column-break-before {w} 00630 column-break-inside {w} 00631 column-count {wm} 00632 column-gap {wm} 00633 column-rule-color {wm} 00634 column-rule-style {wm} 00635 column-rule-width {wm} 00636 column-span {w} 00637 column-width {wm} 00638 content-zoom-boundary {s} 00639 content-zoom-boundary-max {s} 00640 content-zoom-boundary-min {s} 00641 content-zoom-chaining {s} 00642 content-zoom-snap {s} 00643 content-zoom-snap-points {s} 00644 content-zoom-snap-type {s} 00645 content-zooming {s} 00646 dashboard-region {wo} 00647 filter {s} 00648 float-edge {m} 00649 flow-from {s} 00650 flow-into {s} 00651 font-feature-settings {ms} 00652 font-language-override {m} 00653 font-smooting {w} 00654 force-broken-image-icon {m} 00655 grid-column {s} 00656 grid-column-align {s} 00657 grid-column-span {s} 00658 grid-columns {s} 00659 grid-layer {s} 00660 grid-row {s} 00661 grid-row-align {s} 00662 grid-row-span {s} 00663 grid-rows {s} 00664 high-contrast-adjust {s} 00665 highlight {w} 00666 hyphenate-character {w} 00667 hyphenate-limit-after {w} 00668 hyphenate-limit-before {w} 00669 hyphenate-limit-chars {s} 00670 hyphenate-limit-lines {s} 00671 hyphenate-limit-zone {s} 00672 hyphens {wms} 00673 image-region {m} 00674 ime-mode {s} 00675 input-format {o} 00676 input-required {o} 00677 interpolation-mode {s} 00678 layout-flow {s} 00679 layout-grid {s} 00680 layout-grid-char {s} 00681 layout-grid-line {s} 00682 layout-grid-mode {s} 00683 layout-grid-type {s} 00684 line-box-contain {w} 00685 line-break {ws} 00686 line-clamp {w} 00687 link {o} 00688 link-source {o} 00689 locale {w} 00690 margin-after-collapse {w} 00691 margin-before-collapse {w} 00692 marquee-dir {o} 00693 marquee-direction {w} 00694 marquee-increment {w} 00695 marquee-loop {o} 00696 marquee-repetition {w} 00697 marquee-speed {o} 00698 marquee-style {wo} 00699 mask-attachment {w} 00700 mask-box-image {w} 00701 mask-box-image-outset {w} 00702 mask-box-image-repeat {w} 00703 mask-box-image-slice {w} 00704 mask-box-image-source {w} 00705 mask-box-image-width {w} 00706 mask-clip {w} 00707 mask-composite {w} 00708 mask-image {w} 00709 mask-origin {w} 00710 mask-position {w} 00711 mask-repeat {w} 00712 mask-size {w} 00713 nbsp-mode {w} 00714 object-fit {o} 00715 object-position {o} 00716 orient {m} 00717 outline-radius-bottomleft {m} 00718 outline-radius-bottomright {m} 00719 outline-radius-topleft {m} 00720 outline-radius-topright {m} 00721 overflow-style {s} 00722 perspective {wms} 00723 perspective-origin {wms} 00724 perspective-origin-x {s} 00725 perspective-origin-y {s} 00726 rtl-ordering {w} 00727 scroll-boundary {s} 00728 scroll-boundary-bottom {s} 00729 scroll-boundary-left {s} 00730 scroll-boundary-right {s} 00731 scroll-boundary-top {s} 00732 scroll-chaining {s} 00733 scroll-rails {s} 00734 scroll-snap-points-x {s} 00735 scroll-snap-points-y {s} 00736 scroll-snap-type {s} 00737 scroll-snap-x {s} 00738 scroll-snap-y {s} 00739 scrollbar-arrow-color {s} 00740 scrollbar-base-color {s} 00741 scrollbar-darkshadow-color {s} 00742 scrollbar-face-color {s} 00743 scrollbar-highlight-color {s} 00744 scrollbar-shadow-color {s} 00745 scrollbar-track-color {s} 00746 stack-sizing {m} 00747 svg-shadow {w} 00748 tab-size {mo} 00749 table-baseline {o} 00750 text-align-last {s} 00751 text-autospace {s} 00752 text-blink {m} 00753 text-combine {w} 00754 text-decoration-color {m} 00755 text-decoration-line {m} 00756 text-decoration-style {m} 00757 text-decorations-in-effect {w} 00758 text-emphasis-color {w} 00759 text-emphasis-position {w} 00760 text-emphasis-style {w} 00761 text-fill-color {w} 00762 text-justify {s} 00763 text-kashida-space {s} 00764 text-orientation {w} 00765 text-security {w} 00766 text-size-adjust {ms} 00767 text-stroke-color {w} 00768 text-stroke-width {w} 00769 text-overflow {s} 00770 text-underline-position {s} 00771 touch-action {s} 00772 transform {wmso} 00773 transform-origin {wmso} 00774 transform-origin-x {s} 00775 transform-origin-y {s} 00776 transform-origin-z {s} 00777 transform-style {wms} 00778 transition {wmso} 00779 transition-delay {wmso} 00780 transition-duration {wmso} 00781 transition-property {wmso} 00782 transition-timing-function {wmso} 00783 user-drag {w} 00784 user-focus {m} 00785 user-input {m} 00786 user-modify {wm} 00787 user-select {wms} 00788 window-shadow {m} 00789 word-break {s} 00790 wrap-flow {s} 00791 wrap-margin {s} 00792 wrap-through {s} 00793 writing-mode {ws} 00794 00795 } 00796 00797 array set unitless { 00798 z-index 1 00799 line-height 1 00800 opacity 1 00801 font-weight 1 00802 } 00803 00804 array set prefixes { 00805 w -webkit- 00806 m -moz- 00807 s -ms- 00808 o -o- 00809 } 00810 00811 array set keyword_aliases { 00812 a auto 00813 i inherit 00814 s solid 00815 da dashed 00816 do dotted 00817 t transparent 00818 } 00819 00820 ###################################################################### 00821 # Parses the given Emmet string and returns the generated code version. 00822 proc parse {str} { 00823 00824 set lines [list] 00825 set line [list] 00826 00827 # Set the string to lowercase 00828 set str [string tolower $str] 00829 00830 while {[string length $str] > 0} { 00831 if {[regexp {^-([wmso]+)-([a-z:]+\+?|[a-z]+:-)(.*)$} $str -> prefix word str]} { 00832 lappend line word $word prefix $prefix 00833 } elseif {[regexp {^-([a-z:]+\+?|[a-z]+:-)(.*)$} $str -> word str]} { 00834 lappend line hyphen 1 word $word 00835 } elseif {[regexp {^([a-z:]+\+?|[a-z]+:-)(.*)$} $str -> word str]} { 00836 lappend line word $word 00837 } elseif {[regexp {^(-?[0-9]+\.[0-9]+)(.*)$} $str -> num str]} { 00838 lappend line float $num 00839 } elseif {[regexp {^(-?[0-9]+)(.*)$} $str -> num str]} { 00840 lappend line number $num 00841 } elseif {[regexp {^#([0-9a-fA-F]+)(.*)$} $str -> color str]} { 00842 switch [string length $color] { 00843 1 { lappend line color #[string repeat $color 6] } 00844 2 { lappend line color #[string repeat $color 3] } 00845 3 { lappend line color #[string repeat [string index $color 0] 2][string repeat [string index $color 1] 2][string repeat [string index $color 2] 2] } 00846 6 { lappend line color #$color } 00847 } 00848 } elseif {[regexp {^!(.*)$} $str -> str]} { 00849 lappend line important {} 00850 } else { 00851 if {$line ne [list]} { 00852 lappend lines [generate_line $line] 00853 } 00854 set line [list] 00855 set str [string range $str 1 end] 00856 } 00857 } 00858 00859 if {$line ne ""} { 00860 lappend lines [generate_line $line] 00861 } 00862 00863 return [join $lines \n] 00864 00865 } 00866 00867 ###################################################################### 00868 # Returns the CSS that is generates from the given line list. 00869 proc generate_line {line_list} { 00870 00871 variable lookup 00872 variable unitless 00873 variable prefixes 00874 variable keyword_aliases 00875 00876 set line [list] 00877 set important 0 00878 set property "" 00879 set values "" 00880 set val "" 00881 set suffix "" 00882 set suffix_needed 0 00883 set prefix_list [list] 00884 set hyphen 0 00885 00886 foreach {type value} $line_list { 00887 switch $type { 00888 number - 00889 float { 00890 set val $value 00891 if {($property eq "") || ![info exists unitless($property)]} { 00892 if {$type eq "number"} { 00893 set suffix [preferences::get {Emmet/CSSIntUnit}] 00894 } else { 00895 set suffix [preferences::get {Emmet/CSSFloatUnit}] 00896 } 00897 set suffix_needed 1 00898 } else { 00899 set values [insert_value $values $val] 00900 } 00901 } 00902 hyphen { 00903 set hyphen 1 00904 } 00905 prefix { 00906 set prefix_list [list] 00907 foreach prefix [split $value {}] { 00908 if {[info exists prefixes($prefix)]} { 00909 lappend prefix_list $prefixes($prefix) 00910 } 00911 } 00912 } 00913 word { 00914 if {$suffix_needed} { 00915 switch $value { 00916 - { set suffix "px" } 00917 p { set suffix "%" } 00918 e { set suffix "em" } 00919 x { set suffix "ex" } 00920 r { set suffix "rem" } 00921 default { set suffix $value } 00922 } 00923 set suffix_needed 0 00924 if {$property ne ""} { 00925 set values [insert_value $values $val$suffix] 00926 } else { 00927 lappend line $value$suffix 00928 } 00929 } elseif {[info exists lookup($value)]} { 00930 lassign $lookup($value) property values 00931 set prefix_list [get_prefix_list $property $hyphen] 00932 } elseif {[preferences::get {Emmet/CSSFuzzySearch}] && \ 00933 [set tmp [lsearch -glob -inline [lsort [array names lookup]] [join [split $value {}] *]]] ne ""} { 00934 lassign $lookup($tmp) property values 00935 set prefix_list [get_prefix_list $property $hyphen] 00936 } elseif {[info exists keyword_aliases($value)]} { 00937 set values [insert_value $values $keyword_aliases($value)] 00938 } elseif {$property ne ""} { 00939 set values [insert_value $values $value] 00940 } else { 00941 lappend line $value 00942 } 00943 } 00944 color { 00945 if {$suffix_needed} { 00946 if {$property ne ""} { 00947 set values [insert_value $values $val$suffix] 00948 } else { 00949 lappend line $val$suffix 00950 } 00951 set suffix_needed 0 00952 } 00953 switch [string tolower [preferences::get {Emmet/CSSColorCase}]] { 00954 upper { set value [string toupper $value] } 00955 lower { set value [string tolower $value] } 00956 } 00957 if {[preferences::get {Emmet/CSSColorShort}]} { 00958 set value [shorten_color $value] 00959 } 00960 if {$property ne ""} { 00961 set values [insert_value $values $value] 00962 } else { 00963 lappend line $value 00964 } 00965 } 00966 important { 00967 set important 1 00968 } 00969 } 00970 } 00971 00972 if {$suffix_needed} { 00973 if {$property ne ""} { 00974 set values [insert_value $values $val$suffix] 00975 } else { 00976 lappend line $val$suffix 00977 } 00978 } 00979 00980 if {$important} { 00981 if {$property ne ""} { 00982 set values [insert_value $values "!important"] 00983 } else { 00984 lappend line "!important" 00985 } 00986 } 00987 00988 if {$property ne ""} { 00989 set index 1 00990 while {[regexp {(.*?)\{\|(.*?)\}(.*)$} $values -> before value after]} { 00991 if {$value eq ""} { 00992 set values "$before\$$index$after" 00993 } else { 00994 set values "$before\${$index:$value}$after" 00995 } 00996 incr index 00997 } 00998 set lines [list] 00999 set endstr [preferences::get {Emmet/CSSPropertyEnd}] 01000 set separator [preferences::get {Emmet/CSSValueSeparator}] 01001 lappend prefix_list "" 01002 foreach prefix $prefix_list { 01003 lappend lines "$prefix$property$separator$values$endstr" 01004 } 01005 return [join $lines \n] 01006 } else { 01007 return [join $line " "] 01008 } 01009 01010 } 01011 01012 ###################################################################### 01013 # Inserts the given value into the given value list. 01014 proc insert_value {values value} { 01015 01016 if {[regexp {^(.*)\{\|.*?\}(.*)$} $values -> before after]} { 01017 return $before$value$after 01018 } 01019 01020 return "$values $value" 01021 01022 } 01023 01024 ###################################################################### 01025 # Returns the prefix_list for the given property. 01026 proc get_prefix_list {property hyphen} { 01027 01028 variable vendor_props 01029 variable prefixes 01030 01031 set prefix_list [list] 01032 01033 if {[preferences::get {Emmet/CSSAutoInsertVendorPrefixes}] || $hyphen} { 01034 01035 # Get the override values from preferences 01036 set overrides(w) [preferences::get {Emmet/CSSWebkitPropertiesAddon}] 01037 set overrides(m) [preferences::get {Emmet/CSSMozPropertiesAddon}] 01038 set overrides(s) [preferences::get {Emmet/CSSMSPropertiesAddon}] 01039 set overrides(o) [preferences::get {Emmet/CSSOPropertiesAddon}] 01040 01041 # If the value is in vender_props and its not removed via preferences 01042 if {[info exists vendor_props($property)]} { 01043 foreach prefix [split $vendor_props($property) {}] { 01044 if {[lsearch $overrides($prefix) -$property] == -1} { 01045 lappend prefix_list $prefixes($prefix) 01046 } 01047 } 01048 01049 # Otherwise, check to see if the property was added by the user 01050 } else { 01051 foreach prefix [list w m s o] { 01052 if {[lsearch $overrides($prefix) $property] != -1} { 01053 lappend prefix_list $prefixes($prefix) 01054 } 01055 } 01056 } 01057 01058 # If there are no matching prefixes, use them all 01059 if {([llength $prefix_list] == 0) && $hyphen} { 01060 foreach prefix [list w m s o] { 01061 lappend prefix_list $prefixes($prefix) 01062 } 01063 } 01064 01065 } 01066 01067 return $prefix_list 01068 01069 } 01070 01071 ###################################################################### 01072 # Shortens the given color value to a three character color (if possible). 01073 proc shorten_color {value} { 01074 01075 if {[string repeat [string index $value 0] 6] eq $value} { 01076 return [string range $value 0 2] 01077 } elseif {[string range $value 0 2] eq [string range $value 3 5]} { 01078 return [string range $value 0 2] 01079 } 01080 01081 return $value 01082 01083 } 01084 01085 ###################################################################### 01086 # Returns a list structure containing positional information for the next 01087 # or previous ruleset. This procedure returns a Tcl list containing the 01088 # following contents: 01089 # 01090 # - starting index of selector 01091 # - index of curly bracket starting the properties 01092 # - index of curly bracket ending the properties 01093 # - index of the beginning of the ruleset 01094 proc get_ruleset {txt args} { 01095 01096 array set opts { 01097 -dir "next" 01098 -startpos "insert" 01099 } 01100 array set opts $args 01101 01102 # Find the starting position 01103 if {$opts(-dir) eq "prev"} { 01104 if {[$txt compare $opts(-startpos) == 1.0]} { 01105 return "" 01106 } elseif {[set start_index [lindex [$txt tag prevrange __curlyR $opts(-startpos)-1c] 1]] eq ""} { 01107 set start_index 1.0 01108 } 01109 } else { 01110 if {[set start_index [lindex [$txt tag nextrange __curlyR $opts(-startpos)] 1]] eq ""} { 01111 return "" 01112 } 01113 } 01114 01115 # Find the first non-commented, non-whitespace character 01116 set start $start_index 01117 while {($start ne "") && ([set start [$txt search -forwards -regexp -- {\S} $start end]] ne "") && [$txt is incomment $start_index]} { 01118 set comment_tag [lsearch -inline [$txt tag names $start] __comstr*] 01119 set start [lindex [$txt tag prevrange $comment_tag $start+1c] 1] 01120 } 01121 01122 if {($start ne "") && ([set end_index [lindex [$txt tag nextrange __curlyR $start] 1]] ne "")} { 01123 set curly_index [lindex [$txt tag nextrange __curlyL $start_index] 0] 01124 return [list $start $curly_index $end_index $start_index] 01125 } 01126 01127 return "" 01128 01129 } 01130 01131 ###################################################################### 01132 # Returns the current ruleset positional information if we are currently 01133 # within a ruleset; otherwise, returns the empty string. 01134 proc in_ruleset {txt} { 01135 01136 # Returns the previous ruleset 01137 if {([set ruleset [get_ruleset $txt -dir prev -startpos "insert+1c"]] ne "") && [$txt compare insert < [lindex $ruleset 2]]} { 01138 return $ruleset 01139 } 01140 01141 return "" 01142 01143 } 01144 01145 ###################################################################### 01146 # Returns the CSS selector portion of the given ruleset. The ruleset must 01147 # be a valid location within the text widget. 01148 proc get_selector {txt ruleset} { 01149 01150 set str [string trim [$txt get {*}[lrange $ruleset 0 1]]] 01151 01152 if {[set index [$txt search -forward -count lengths -- $str [lindex $ruleset 0]]] ne ""} { 01153 return [list $index [$txt index "$index+[lindex $lengths 0]c"]] 01154 } 01155 01156 return "" 01157 01158 } 01159 01160 ###################################################################### 01161 # Given the starting position of the property name and its corresponding 01162 # colon index, return a list containing the starting/ending index of the 01163 # property name and the starting/ending index of the property value. 01164 proc get_property_retval {txt namepos colonpos endpos} { 01165 01166 set name [string trim [string range [$txt get $namepos $colonpos] 0 end-1]] 01167 set endpos [$txt search -forward -- {;} $colonpos $endpos] 01168 set full_value [$txt get $colonpos+1c $endpos] 01169 set start_offset [expr ([string length $full_value] - [string length [string trimleft $full_value]]) + 1] 01170 01171 return [list $namepos [$txt index "$namepos+[string length $name]c"] [$txt index "$colonpos+${start_offset}c"] $endpos] 01172 01173 } 01174 01175 ###################################################################### 01176 # Returns a list containing all of the properties of the given ruleset. 01177 proc get_properties {txt ruleset} { 01178 01179 set props [list] 01180 set i 0 01181 foreach index [$txt search -all -forward -count lengths -regexp -- {[a-zA-Z0-9_-]+\s*:} {*}[lrange $ruleset 1 2]] { 01182 lappend props [get_property_retval $txt $index [$txt index "$index+[lindex $lengths $i]c"] [lindex $ruleset 2]] 01183 incr i 01184 } 01185 01186 return $props 01187 01188 } 01189 01190 ###################################################################### 01191 # Get the positional information for the ruleset property in the given 01192 # direction. 01193 proc get_property {txt ruleset args} { 01194 01195 array set opts { 01196 -dir "next" 01197 } 01198 array set opts $args 01199 01200 # Get the positional information of the property name 01201 if {$opts(-dir) eq "next"} { 01202 set start [expr {[$txt compare insert < [lindex $ruleset 1]] ? [lindex $ruleset 1] : "insert"}] 01203 set index [$txt search -forward -count lengths -regexp -- {[a-zA-Z0-9_-]+\s*:} $start [lindex $ruleset 2]] 01204 } elseif {[$txt compare insert < [lindex $ruleset 1]]} { 01205 return "" 01206 } else { 01207 set start [expr {[$txt compare [lindex $ruleset 2] < insert] ? [lindex $ruleset 2] : "insert"}] 01208 set index [$txt search -backward -count lengths -regexp -- {[a-zA-Z0-9_-]+\s*:} $start [lindex $ruleset 1]] 01209 } 01210 01211 if {$index ne ""} { 01212 return [get_property_retval $txt $index [$txt index "$index+[lindex $lengths 0]c"] [lindex $ruleset 2]] 01213 } 01214 01215 return "" 01216 01217 } 01218 01219 ###################################################################### 01220 # Returns true if the insertion cursor is within a url() call. 01221 proc in_url {txt} { 01222 01223 if {[set ruleset [in_ruleset $txt]] ne ""} { 01224 if {[set index [$txt search -forward -count lengths -regexp -- {url\(.+?\)} {*}[lrange $ruleset 2 3]]] ne ""} { 01225 return [expr {[$txt compare "$index+4c" <= insert] && [$txt compare insert < "$index+[expr [lindex $lengths 0] - 1]c"]}] 01226 } 01227 } 01228 01229 return 0 01230 01231 } 01232 01233 ###################################################################### 01234 proc select_property_token {txt dir selected startpos endpos} { 01235 01236 set select 0 01237 set pattern [expr {($dir eq "next") ? {^\s*(\S+)} : {(\S+)\s*$}}] 01238 set value [$txt get "$startpos+1c" "$endpos-1c"] 01239 01240 01241 01242 } 01243 01244 ###################################################################### 01245 # Returns the number of items that are found in the value string that 01246 # will be parsed. 01247 proc get_item_count {dir str depth} { 01248 01249 if {$dir eq "next"} { 01250 if {$depth == 0} { 01251 set retval [regexp -all -- {\S+(\(.*?\))?} $str] 01252 return $retval 01253 } else { 01254 set retval [llength [split $str ,]] 01255 return $retval 01256 } 01257 } else { 01258 if {[string map {, {} { } {} \( {}} $str] ne $str} { 01259 return 2 01260 } 01261 return 1 01262 } 01263 01264 } 01265 01266 ###################################################################### 01267 # Select the next thing in the property list. 01268 proc select_property_value {txt dir depth selected startpos endpos} { 01269 01270 set select 0 01271 set pattern [expr {($dir eq "next") ? {^\s*(\S+(\(.*?\))?)} : {(\S+(\(.*?\))?)\s*$}}] 01272 set value [$txt get $startpos $endpos] 01273 01274 # Figure out if we need to select the first selectable item in the value list 01275 if {((($dir eq "next") && ($selected eq [list $startpos $endpos])) || \ 01276 (($dir eq "prev") && ($selected ne "") && [$txt compare [lindex $selected 0] > $endpos])) && \ 01277 ([get_item_count $dir $value $depth] > 1)} { 01278 set select 1 01279 } 01280 01281 while {[regexp -indices $pattern $value -> match fnargs]} { 01282 set value_start [$txt index "$startpos+[lindex $match 0]c"] 01283 set value_end [$txt index "$startpos+[expr [lindex $match 1] + 1]c"] 01284 if {[lindex $fnargs 0] != -1} { 01285 set fnargs_start [$txt index "$startpos+[expr [lindex $fnargs 0] + 1]c"] 01286 set fnargs_end [$txt index "$startpos+[lindex $fnargs 1]c"] 01287 } 01288 if {$dir eq "next"} { 01289 01290 if {$select} { 01291 ::tk::TextSetCursor $txt $value_end 01292 $txt tag add sel $value_start $value_end 01293 return 1 01294 } elseif {$selected eq [list $value_start $value_end]} { 01295 if {[lindex $fnargs 0] != -1} { 01296 ::tk::TextSetCursor $txt $fnargs_end 01297 $txt tag add sel $fnargs_start $fnargs_end 01298 return 1 01299 } 01300 set select 1 01301 } elseif {([lindex $fnargs 0] != -1) && ($selected ne "") && \ 01302 [$txt compare $fnargs_start <= [lindex $selected 0]] && \ 01303 [$txt compare [lindex $selected 1] <= $fnargs_end]} { 01304 if {[select_property_value $txt $dir [expr $depth + 1] $selected $fnargs_start $fnargs_end]} { 01305 return 1 01306 } else { 01307 set select 1 01308 } 01309 } 01310 set value [string range $value [expr [lindex $match 1] + 1] end] 01311 set startpos [$txt index "$startpos+[expr [lindex $match 1] + 1]c"] 01312 01313 } else { 01314 01315 # If the current item is a function call 01316 if {([lindex $fnargs 0] != -1) && ($selected ne "")} { 01317 if {[$txt compare $fnargs_start == [lindex $selected 0]] && \ 01318 [$txt compare $fnargs_end == [lindex $selected 1]]} { 01319 ::tk::TextSetCursor $txt $value_end 01320 $txt tag add sel $value_start $value_end 01321 return 1 01322 } elseif {$select || \ 01323 ([$txt compare $fnargs_start <= [lindex $selected 0]] && \ 01324 [$txt compare [lindex $selected 1] <= $fnargs_end])} { 01325 if {[select_property_value $txt $dir [expr $depth + 1] $selected $fnargs_start $fnargs_end]} { 01326 return 1 01327 } else { 01328 ::tk::TextSetCursor $txt $fnargs_end 01329 $txt tag add sel $fnargs_start $fnargs_end 01330 return 1 01331 } 01332 } 01333 } elseif {$select} { 01334 ::tk::TextSetCursor $txt $value_end 01335 $txt tag add sel $value_start $value_end 01336 return 1 01337 } elseif {$selected eq [list $value_start $value_end]} { 01338 set select 1 01339 } 01340 set value [string range $value 0 [expr [lindex $match 0] - 1]] 01341 01342 } 01343 } 01344 01345 if {$select} { 01346 return 0 01347 } else { 01348 ::tk::TextSetCursor $txt $endpos 01349 $txt tag add sel $startpos $endpos 01350 return 1 01351 } 01352 01353 } 01354 01355 ###################################################################### 01356 # Selects the next/previous CSS item. 01357 proc select_item {txt dir} { 01358 01359 # Get the proper ruleset 01360 if {[set ruleset [in_ruleset $txt]] eq ""} { 01361 if {[set ruleset [get_ruleset $txt -dir $dir]] eq ""} { 01362 return 01363 } 01364 } 01365 01366 # Check to see if anything is selected 01367 if {[llength [set selected [$txt tag ranges sel]]] != 2} { 01368 set selected "" 01369 } 01370 01371 if {$dir eq "next"} { 01372 01373 while {$ruleset ne ""} { 01374 01375 lassign [get_selector $txt $ruleset] selector_start selector_end 01376 01377 if {[$txt compare insert <= $selector_start]} { 01378 ::tk::TextSetCursor $txt.t $selector_end 01379 $txt tag add sel $selector_start $selector_end 01380 return 01381 01382 } else { 01383 foreach prop [get_properties $txt $ruleset] { 01384 if {[$txt compare insert > [lindex $prop 3]]} { 01385 continue 01386 } 01387 if {[$txt compare insert < [lindex $prop 2]]} { 01388 ::tk::TextSetCursor $txt [lindex $prop 3] 01389 $txt tag add sel [lindex $prop 0] [lindex $prop 3] 01390 return 01391 } elseif {($selected eq [list [lindex $prop 0] [lindex $prop 3]]) || ($selected eq "")} { 01392 ::tk::TextSetCursor $txt [lindex $prop 3] 01393 $txt tag add sel [lindex $prop 2] [lindex $prop 3] 01394 return 01395 } elseif {[select_property_value $txt next 0 $selected {*}[lrange $prop 2 3]]} { 01396 return 01397 } 01398 } 01399 } 01400 01401 # Get the next ruleset 01402 set ruleset [get_ruleset $txt -dir next -startpos [lindex $ruleset 0]] 01403 01404 } 01405 01406 } else { 01407 01408 while {$ruleset ne ""} { 01409 01410 foreach prop [lreverse [get_properties $txt $ruleset]] { 01411 if {($selected eq [list [lindex $prop 0] [lindex $prop 3]]) || [$txt compare insert < [lindex $prop 0]]} { 01412 continue 01413 } 01414 if {($selected eq [list [lindex $prop 2] [$txt index [lindex $prop 3]]]) || \ 01415 (($selected eq "") && [$txt compare insert > [lindex $prop 0]])} { 01416 ::tk::TextSetCursor $txt [lindex $prop 3] 01417 $txt tag add sel [lindex $prop 0] [lindex $prop 3] 01418 return 01419 } elseif {[select_property_value $txt prev 0 $selected {*}[lrange $prop 2 3]]} { 01420 return 01421 } elseif {[$txt compare insert > [lindex $prop 2]]} { 01422 ::tk::TextSetCursor $txt [lindex $prop 3] 01423 $txt tag add sel [lindex $prop 2] [lindex $prop 3] 01424 return 01425 } 01426 } 01427 01428 lassign [get_selector $txt $ruleset] selector_start selector_end 01429 01430 if {(($selected ne [list $selector_start $selector_end]) && [$txt compare insert > [lindex $ruleset 0]]) || \ 01431 ($selected eq [list [lindex $prop 0] [lindex $prop 3]])} { 01432 ::tk::TextSetCursor $txt $selector_end 01433 $txt tag add sel $selector_start $selector_end 01434 return 01435 } 01436 01437 # Get the previous ruleset 01438 set ruleset [get_ruleset $txt -dir prev -startpos [lindex $ruleset 3]-1c] 01439 01440 } 01441 01442 } 01443 01444 } 01445 01446 ###################################################################### 01447 # Toggles comment of ruleset or property. 01448 proc toggle_comment {txt} { 01449 01450 if {[ctext::inBlockComment $txt insert]} { 01451 01452 set tag [lsearch -inline [$txt tag names insert] __comstr1c*] 01453 lassign [$txt tag prevrange $tag "insert+1c"] startpos endpos 01454 01455 if {[$txt get $endpos-3c] eq " "} { 01456 $txt delete "$endpos-3c" $endpos 01457 } else { 01458 $txt delete "$endpos-2c" $endpos 01459 } 01460 01461 if {[$txt get $startpos+2c] eq " "} { 01462 $txt delete $startpos "$startpos+3c" 01463 } else { 01464 $txt delete $startpos "$startpos+2c" 01465 } 01466 01467 } else { 01468 01469 # We will only comment something if we are within a ruleset 01470 if {[set ruleset [in_ruleset $txt]] eq ""} { 01471 return 01472 } 01473 01474 # If the cursor is within the selector area, comment the entire ruleset 01475 if {[$txt compare [lindex $ruleset 0] <= insert] && [$txt compare insert <= [lindex $ruleset 1]]} { 01476 $txt insert [lindex $ruleset 2] " */" 01477 $txt insert [lindex $ruleset 0] "/* " 01478 } elseif {[set prop [get_property $txt $ruleset -dir prev]] ne ""} { 01479 $txt insert "[lindex $prop 3]+1c" " */" 01480 $txt insert [lindex $prop 0] "/* " 01481 } 01482 01483 } 01484 01485 } 01486 01487 ###################################################################### 01488 # If the cursor is within a url() call inside of a ruleset property 01489 # value, adds/updates the height and width properties to match the 01490 # image size. 01491 proc update_image_size {txt} { 01492 01493 if {[set ruleset [in_ruleset $txt]] eq ""} { 01494 return 01495 } 01496 01497 # Get the list of properties associated with the ruleset 01498 set props [get_properties $txt $ruleset] 01499 01500 # Check to see if the insertion cursor is within a url() call 01501 foreach prop $props { 01502 if {[set index [$txt search -count lengths -regexp -- {url\(.+?\)} {*}[lrange $prop 2 3]]] ne ""} { 01503 if {[$txt compare "$index+4c" <= insert] && [$txt compare insert < "$index+[lindex $lengths 0]c"]} { 01504 set url [string trim [$txt get "$index+4c" "$index+[expr [lindex $lengths 0] - 1]c"]] 01505 if {![catch { exec php [file join $::tke_dir lib image_size.php] $url } rc]} { 01506 lassign $rc width height 01507 if {![string is integer $width]} { 01508 return 01509 } 01510 set found(url) $prop 01511 } 01512 } 01513 } else { 01514 set name [$txt get {*}[lrange $prop 0 1]] 01515 if {($name eq "height") || ($name eq "width")} { 01516 set found($name) $prop 01517 } 01518 } 01519 } 01520 01521 # If we didn't find our URL, just return 01522 if {![info exists found(url)]} { 01523 return 01524 } 01525 01526 # Replace/insert width/height values 01527 if {[info exists found(width)]} { 01528 $txt replace {*}[lrange $found(width) 2 3] " ${width}px" 01529 if {[info exists found(height)]} { 01530 $txt replace {*}[lrange $found(height) 2 3] " ${height}px" 01531 } else { 01532 set num_spaces [lindex [split [lindex $found(width) 0] .] 1] 01533 set spaces [expr {($num_spaces > 0) ? [string repeat " " $num_spaces] : ""}] 01534 $txt insert "[lindex $found(width) 3] lineend" "\n${spaces}height: ${height}px;" 01535 } 01536 } elseif {[info exists found(height)]} { 01537 set num_spaces [lindex [split [lindex $found(height) 0] .] 1] 01538 set spaces [expr {($num_spaces > 0) ? [string repeat " " $num_spaces] : ""}] 01539 $txt replace {*}[lrange $found(height) 2 3] " ${height}px" 01540 $txt insert "[lindex $found(height) 0] linestart" "${spaces}width: ${width}px;\n" 01541 } else { 01542 set num_spaces [lindex [split [lindex $found(url) 0] .] 1] 01543 set spaces [expr {($num_spaces > 0) ? [string repeat " " $num_spaces] : ""}] 01544 $txt insert "[lindex $found(url) 3] lineend" "\n${spaces}width: ${width}px;\n${spaces}height: ${height}px;" 01545 } 01546 01547 } 01548 01549 ###################################################################### 01550 # Returns the basename of the given property name. 01551 proc get_basename {name} { 01552 01553 regexp {^-(webkit|moz|ms|o)-(.*)$} [set basename $name] -> dummy basename 01554 01555 return $basename 01556 01557 } 01558 01559 ###################################################################### 01560 # Attempt to reflect the current value. 01561 proc reflect_css_value {} { 01562 01563 # Get the current text widget 01564 set txt [gui::current_txt] 01565 01566 # Get the current ruleset 01567 if {[set ruleset [in_ruleset $txt]] eq ""} { 01568 return 01569 } 01570 01571 # Get the current property 01572 if {[set prop [get_property $txt $ruleset -dir prev]] eq ""} { 01573 return 01574 } 01575 01576 if {[$txt compare [lindex $prop 0] < insert] && [$txt compare insert < [lindex $prop 3]]} { 01577 set name [$txt get {*}[lrange $prop 0 1]] 01578 set basename [get_basename $name] 01579 set value [$txt get {*}[lrange $prop 2 3]] 01580 foreach prop [lreverse [get_properties $txt $ruleset]] { 01581 set pname [$txt get {*}[lrange $prop 0 1]] 01582 if {($name ne $pname) && ([get_basename $pname] eq $basename)} { 01583 $txt replace {*}[lrange $prop 2 3] $value 01584 } 01585 } 01586 } 01587 01588 } 01589 01590 ###################################################################### 01591 # Runs encode/decode image to data:URL in CSS. 01592 proc encode_decode_image_to_data_url {txt args} { 01593 01594 # Get the current ruleset 01595 if {[set ruleset [in_ruleset $txt]] eq ""} { 01596 return 01597 } 01598 01599 # Update the URL 01600 if {[set ruleset [in_ruleset $txt]] ne ""} { 01601 if {[set index [$txt search -forward -count lengths -regexp -- {url\(.+?\)} {*}[lrange $ruleset 2 3]]] ne ""} { 01602 if {[$txt compare "$index+4c" <= insert] && [$txt compare insert < "$index+[expr [lindex $lengths 0] - 1]c"]} { 01603 set startpos "$index+4c" 01604 set endpos "$index+[expr [lindex $lengths 0] - 1]c" 01605 set url [$txt get $startpos $endpos] 01606 emmet::replace_data_url $txt $startpos $endpos $url {*}$args 01607 } 01608 } 01609 } 01610 01611 } 01612 01613 }