Skip to content

Commit

Permalink
[CSS] Highlight operator inside math function with different style.
Browse files Browse the repository at this point in the history
  • Loading branch information
zufuliu committed May 11, 2024
1 parent bee0824 commit 578fa93
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 49 deletions.
9 changes: 5 additions & 4 deletions scintilla/lexers/LexCSS.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum {
KeywordIndex_AtRule = 1,
KeywordIndex_PseudoClass = 2,
KeywordIndex_PseudoElement = 3,
KeywordIndex_MathFunction = 4,
};
//KeywordIndex--Autogenerated -- end of section automatically generated

Expand Down Expand Up @@ -84,7 +85,7 @@ void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSty
int variableInterpolation = 0;

int parenCount = 0; // function
int calcLevel = 0; // calc() function
int calcLevel = 0; // math function
int selectorLevel = 0; // nested selector
int chBefore = 0;
int chPrevNonWhite = 0;
Expand Down Expand Up @@ -166,10 +167,10 @@ void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSty
const int chNext = sc.GetDocNextChar(sc.ch == '(');
if (sc.ch == '(') {
sc.ChangeState(SCE_CSS_FUNCTION);
if (StrEqual(s, "calc")) {
if (keywordLists[KeywordIndex_MathFunction].InListPrefixed(s, '(')) {
calcFunc = true;
} else if (StrEqualsAny(s, "url", "url-prefix")
&& !(chNext == '\'' || chNext == '\"' || (chNext == '$' && preprocessor == Preprocessor::Scss))) {
&& !AnyOf(chNext, '\'', '\"', ')') && (chNext != '$' || preprocessor != Preprocessor::Scss)) {
levelNext++;
parenCount++;
sc.SetState(SCE_CSS_OPERATOR);
Expand Down Expand Up @@ -386,7 +387,7 @@ void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSty
case '*':
case '/':
if (calcLevel != 0 && (chPrevNonWhite == ')' || AnyOf(stylePrevNonWhite, SCE_CSS_NUMBER, SCE_CSS_DIMENSION))) {
sc.ChangeState(SCE_CSS_OPERATOR2); // operator inside calc() function
sc.ChangeState(SCE_CSS_OPERATOR2); // operator inside math function
}
break;
}
Expand Down
2 changes: 1 addition & 1 deletion scintilla/lexers/LexPHP.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ bool PHPLexer::ClassifyCssWord() {
const int chNext = sc.GetDocNextChar(sc.ch == '(');
if (sc.ch == '(') {
sc.ChangeState(css_style(SCE_CSS_FUNCTION));
if (StrEqual(s, "url") && !(chNext == '\'' || chNext == '\"')) {
if (StrEqual(s, "url") && !AnyOf(chNext, '\'', '\"', ')')) {
parenCount++;
sc.SetState(css_style(SCE_CSS_OPERATOR));
sc.ForwardSetState(css_style(SCE_CSS_URL));
Expand Down
6 changes: 5 additions & 1 deletion src/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ int AddStyleSeparator(LPCEDITLEXER pLex, int ch, int chPrev, int style) noexcept
// a++ + ++b, a + +1, a-- - --b, a - -1
if (ch == '+' || ch == '-') {
if (style == SCE_CSS_OPERATOR2 && pLex->iLexer == SCLEX_CSS) {
// '+' and '-' inside calc() function requires space on both side
// '+' and '-' inside math function requires space on both side
return SpaceOption_SpaceBefore | SpaceOption_SpaceAfter;
}
if (ch == chPrev) {
Expand All @@ -1017,6 +1017,7 @@ int AddStyleSeparator(LPCEDITLEXER pLex, int ch, int chPrev, int style) noexcept
// var name; return .5; CSS property: 1 #1 .5 --name;
if (BitTestEx(DefaultWordCharSet, chPrev)) {
if (BitTestEx(DefaultWordCharSet, ch) || ch == '$' || ch == '#' || (ch == '-' && pLex->iLexer == SCLEX_CSS)) {
// TODO: improve CSS An+B when B is negative, https://www.w3.org/TR/css-syntax-3/#anb-microsyntax
return SpaceOption_SpaceBefore;
}
if (ch == '.' && style != pLex->operatorStyle && style != pLex->operatorStyle2) {
Expand Down Expand Up @@ -1126,6 +1127,9 @@ std::string CodePretty(LPCEDITLEXER pLex, const char *styledText, size_t textLen
braceTop = ch;
if (ch == '{') {
spaceOption |= SpaceOption_NewLineAfter | SpaceOption_IndentAfter;
if (stylePrev >= SCE_JS_IDENTIFIER) {
spaceOption |= SpaceOption_SpaceBefore;
}
}
}
} else if (ch == '{' || pLex->iLexer == SCLEX_JSON) {
Expand Down
52 changes: 28 additions & 24 deletions src/EditLexers/stlCSS.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,10 @@ static KEYWORDLIST Keywords_CSS = {{
"nth-fragment( part( placeholder postfix prefix region selection shadow slot( spelling-error target-text "
"view-transition view-transition-group( view-transition-image-pair( view-transition-new( view-transition-old( "

, // 4 color names
, // 4 math functions
"abs( acos( asin( atan( atan2( calc( clamp( cos( exp( hypot( log( max( min( mod( pow( rem( round( sign( sin( sqrt( tan( "

, // 5 color names
"aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood "
"cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan "
"darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid "
Expand All @@ -176,32 +179,32 @@ static KEYWORDLIST Keywords_CSS = {{
"webgray webgreen webgrey webmaroon webpurple wheat white whitesmoke x11gray x11green x11grey x11maroon x11purple "
"yellow yellowgreen "

, // 5 values
, // 6 values
"ActiveText ButtonBorder ButtonFace ButtonText CSS( Canvas CanvasText Field FieldText GrayText Highlight HighlightText "
"LinkText Mark MarkText NaN VisitedText "
"above abs( absolute absolute-colorimetric accumulate acos( add additive adjust( alias "
"above absolute absolute-colorimetric accumulate add additive adjust( alias "
"all-petite-caps all-scroll all-small-caps allow-discrete allow-end alpha alpha( alphabetic alphamix( "
"alternate alternate-reverse always anchor( anchor-size( and annotation( anywhere append( arcs argb( arguments armenian "
"as asin( at atan( atan2( attr( audio aural auto auto-flow auto-phrase "
"as at attr( audio aural auto auto-flow auto-phrase "
"average( avoid avoid-column avoid-flex avoid-line avoid-page avoid-region "
"back backwards balance balance-all bar baseline behind below bevel bidi-override bitmap "
"blackness( blink block block-end block-start blue( blur( bold bolder boolean( border-box both both-edges bounding-box "
"braille break break-all break-spaces break-word brightness( browser bullets butt button "
"calc( calc-args( calc-name( call( cap cap-height capitalize caption ceil( cell center center-left center-right central "
"ch-width change( character-variant( checkbox child child( circle circle( clamp( clone close-quote coarse code "
"col-resize collapse collection "
"calc-args( calc-name( call( cap cap-height capitalize caption ceil( cell center center-left center-right central "
"ch-width change( character-variant( checkbox child child( circle circle( clone close-quote coarse code col-resize "
"collapse collection "
"color( color-CBDT color-COLRv0 color-COLRv1 color-SVG color-burn color-contrast( color-dodge color-mix( color-sbix "
"column column-reverse common-ligatures compact compatible( complement( compress condensed conic-gradient( "
"content( content-box content-exists( contents context-menu contextual continuous contrast( contrast-color( convert( "
"copy cos( counter( counters( cover create crisp-edges crispEdges crop cross cross-fade( crosshair css "
"copy counter( counters( cover create crisp-edges crispEdges crop cross cross-fade( crosshair css "
"cubic-bezier( currentColor cursive custom cyclic "
"dark darken darken( dashed dashes data-uri( "
"decimal decimal-leading-zero deep-merge( deep-remove( default( dense desaturate( device-cmyk( "
"diagonal-fractions difference difference( digits disc discard discard-after discard-before discretionary-ligatures div( "
"domain( dot dotted double double-circle down drop drop-shadow( "
"e-resize each( each-line ease ease-in ease-in-out ease-out economy element( ellipse( ellipsis "
"embed embed( embedded-opentype embossed emoji escape( evenodd ew-resize "
"ex ex-height exact exclude exclusion exclusion( exp( expanded extends extra-condensed extra-expanded extract( "
"ex ex-height exact exclude exclusion exclusion( expanded extends extra-condensed extra-expanded extract( "
"fade fade( fade-in( fade-out( fadein( fadeout( false fangsong fantasy far-left far-right fast faster "
"feature-aat feature-exists( feature-graphite feature-opentype female "
"fill-box filled fine first-baseline fit-content( fixed flat flex-end flex-start flip floor( flow-root "
Expand All @@ -211,7 +214,7 @@ static KEYWORDLIST Keywords_CSS = {{
"grab grabbing grayscale( green( greyscale( groove "
"handheld hanging hard-light hardlight( has-key( help hidden hide high high-quality higher historical-ligatures "
"horizontal horizontal-tb hsl( hsla( hss-height hss-width hsv( hsva( hsvhue( hsvsaturation( hsvvalue( "
"hue hue( hue-rotate( hwb( hypot( "
"hue hue( hue-rotate( hwb( "
"ic-height ic-width icon ideograph-alpha ideograph-numeric ideographic ideographic-ink ideographic-space ie-hex-str( if( "
"image( image-height( image-set( image-size( image-width( implicit important in increment incremental index( "
"infinite infinity inherit initial initial-only "
Expand All @@ -223,14 +226,14 @@ static KEYWORDLIST Keywords_CSS = {{
"lab( landscape large larger last last-baseline layer( layout lch( "
"leader( leading left-side leftwards legacy length( less level light lighten lighten( lighter lightness( "
"line line-through linear linear-gradient( linearRGB lining-nums list list-item listbox literal-punctuation "
"load-css( local local( log( loose loud low lower lower-alpha lower-greek lower-latin lower-roman lowercase ltr "
"load-css( local local( loose loud low lower lower-alpha lower-greek lower-latin lower-roman lowercase ltr "
"luma( luminance luminance( luminosity "
"male mandatory manipulation manual map margin-box "
"match-parent match-self match-source math mathematical matrix( matrix3d( max( max-content maximum "
"match-parent match-self match-source math mathematical matrix( matrix3d( max-content maximum "
"media( media-document( medium menu menulist menulist-button merge merge( message-box meta meter middle "
"min( min-color-index min-content min-monochrome minimal-ui minimum minmax( miter miter-clip "
"mix mix( mixed mixin-exists( mod( moderate module-functions( module-variables( monospace more "
"most-block-size most-height most-inline-size most-width move multiple multiply multiply( "
"min-color-index min-content min-monochrome minimal-ui minimum minmax( miter miter-clip mix mix( mixed mixin-exists( "
"moderate module-functions( module-variables( monospace more most-block-size most-height most-inline-size most-width "
"move multiple multiply multiply( "
"n-resize name( narrow ne-resize nearest negation( nest( nesw-resize neutral never nherit no-autospace "
"no-clip no-close-quote no-common-ligatures no-compress no-contextual no-discretionary-ligatures no-drop "
"no-historical-ligature no-limit no-open-quote no-preference no-punctuation no-repeat nonzero normal not not-allowed "
Expand All @@ -240,29 +243,29 @@ static KEYWORDLIST Keywords_CSS = {{
"outer outset outside outside-shape over overlay overlay( overline "
"p3 padding-box paged paginate paint painted palette-mix( palettes pan-down pan-left pan-right pan-up pan-x pan-y "
"parent parse( path( percentage( perceptual perspective( petite-caps pi pi( pinch-zoom pixelated plaintext "
"polygon( portrait pow( "
"polygon( portrait "
"pre pre-line pre-wrap preserve preserve-3d preserve-breaks preserve-parent-color preserve-spaces pretty print "
"progress progress-bar progressive projection proportional-nums proportional-width proximity punctuation push-button "
"quote( "
"radial-gradient( radio raise random( range( ray( rec2020 rect rect( red( reduce reduced reference regexp( "
"relative relative-colorimetric rem( remove( "
"relative relative-colorimetric remove( "
"repeat repeat-x repeat-y repeating-conic-gradient( repeating-linear-gradient( repeating-radial-gradient( "
"replace replace( reverse revert revert-layer rgb( rgba( ridge right-side rightwards "
"rotate( rotate-left rotate-right rotate3d( rotateX( rotateY( rotateZ( round round( row row-resize row-reverse rtl "
"rotate( rotate-left rotate-right rotate3d( rotateX( rotateY( rotateZ( round row row-resize row-reverse rtl "
"ruby ruby-base ruby-base-container ruby-text ruby-text-container run-in running( "
"s-resize sRGB safe same sans-serif saturate( saturation saturation( "
"scale( scale-down scale3d( scaleX( scaleY( scaleZ( screen screen( scroll scroll( scroll-position se-resize searchfield "
"select( selector selector( self-end self-start semi-condensed semi-expanded separate separator( sepia( serif sesame "
"set( set-nth( shade( show sideways sideways-lr sideways-rl sign( silent simple-selectors( simplified sin( size( "
"set( set-nth( shade( show sideways sideways-lr sideways-rl silent simple-selectors( simplified size( "
"skew( skewX( skewY( slash( slashed-zero slice slice( slider-horizontal slow slower "
"small small-caps small-caption smaller smooth snap snap-block snap-inline soft soft-light softlight( solid "
"space space-adjacent space-all space-around space-between space-end space-evenly space-first space-start spaces span "
"speech spell-out spin( spread sqrt( square square-button srgb "
"speech spell-out spin( spread square square-button srgb "
"stable stacked-fractions standalone standard start state static status-bar step-end step-start steps( sticky "
"stretch strict string string( stripes( stroke-box strong stupid style style( styleset( stylistic( "
"sub subgrid subtract subtractive super supports( svg svg-gradient( sw-resize swap swash( symbolic symbols( system-ui "
"table table-caption table-cell table-column table-column-group table-footer-group table-header-group "
"table-row table-row-group tabular-nums tactile tan( target-counter( target-counters( target-text( "
"table-row table-row-group tabular-nums tactile target-counter( target-counters( target-text( "
"techn( text text-bottom text-top textarea textfield thick thin through tint( titling-caps "
"to to-lower-case( to-upper-case( traditional translate( translate3d( translateX( translateY( translateZ( "
"triangle trim-adjacent trim-all trim-auto trim-end trim-inner trim-start true truetype tty tv type( type-of( "
Expand All @@ -275,7 +278,7 @@ static KEYWORDLIST Keywords_CSS = {{
"x-fast x-high x-large x-loud x-low x-slow x-small x-soft x-strong x-weak xx-large xx-small xywh( young "
"zero-if-extrinsic zero-if-scroll zip( zoom-in zoom-out "

, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
//--Autogenerated -- end of section automatically generated
}};

Expand Down Expand Up @@ -321,8 +324,9 @@ EDITLEXER lexCSS = {
| KeywordAttr32(1, KeywordAttr_PreSorted) // at rules
| KeywordAttr32(2, KeywordAttr_PreSorted) // pseudo classes
| KeywordAttr32(3, KeywordAttr_PreSorted) // pseudo elements
| KeywordAttr32(4, KeywordAttr_NoLexer) // color names
| KeywordAttr32(5, KeywordAttr_NoLexer) // values
| KeywordAttr32(4, KeywordAttr_PreSorted) // math functions
| KeywordAttr32(5, KeywordAttr_NoLexer) // color names
| KeywordAttr32(6, KeywordAttr_NoLexer) // values
, SCE_CSS_CDO_CDC,
SCE_CSS_ESCAPECHAR, SCE_CSS_URL,
//Settings--Autogenerated -- end of section automatically generated
Expand Down
17 changes: 11 additions & 6 deletions tools/KeywordCore.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,23 +779,27 @@ def parse_css_api_file(pathList):
}

values = []
functions = []
for path in pathList:
for line in read_file(path).splitlines():
line = line.strip()
if not line or line.startswith('//'):
continue
if line[0] == '@':
marker = line[0]
if marker == '@':
rule = line.split()[0][1:]
keywordMap['at rules'].append(rule)
elif line[0] == '!':
elif marker == '!':
values.append(line[1:])
elif line[0] == ':':
elif marker == ':':
line = line.rstrip(')')
if line[1] == ':':
keywordMap['pseudo elements'].append(line[2:])
else:
keywordMap['pseudo classes'].append(line[1:])
elif line[0].isalpha():
elif marker == '=':
functions.extend(item[:-1] for item in line[1:].split())
elif marker.isalpha():
line = re.sub(r'\(.*?\)', '(', line)
index = line.find(':')
if index > 0:
Expand All @@ -808,14 +812,15 @@ def parse_css_api_file(pathList):
items = []
for value in keywordMap.values():
items.extend(value)
keywordMap['values'] = set(values) - ColorNameList - set(items)
values = set(values) - ColorNameList - set(items) - set(functions)
return [
('properties', keywordMap['properties'], KeywordAttr.Default),
('at rules', keywordMap['at rules'], KeywordAttr.Special),
('pseudo classes', keywordMap['pseudo classes'], KeywordAttr.Special),
('pseudo elements', keywordMap['pseudo elements'], KeywordAttr.Special),
('math functions', functions, KeywordAttr.Default),
('color names', ColorNameList, KeywordAttr.NoLexer),
('values', keywordMap['values'], KeywordAttr.NoLexer),
('values', values, KeywordAttr.NoLexer),
]

def parse_dlang_api_file(path):
Expand Down
26 changes: 13 additions & 13 deletions tools/lang/CSS.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// https://www.w3.org/TR/css-syntax-3/ 24 December 2021
!important

// CSS Anchor Positioning https://www.w3.org/TR/css-anchor-position-1/ 14 March 2024
// CSS Anchor Positioning https://www.w3.org/TR/css-anchor-position-1/ 26 March 2024
{
anchor-name: none;
anchor-scope: none | all;
Expand Down Expand Up @@ -131,8 +131,8 @@ from to
input-security: auto | none;
}

// CSS Box Model Module Level 4 https://www.w3.org/TR/css-box-4/ 3 November 2022
// CSS Box Model Module Level 3 https://www.w3.org/TR/css-box-3/ 6 April 2023
// CSS Box Model Module Level 4 https://www.w3.org/TR/css-box-4/ 1 April 2024
// CSS Box Model Module Level 3 https://www.w3.org/TR/css-box-3/ 11 April 2024
// Box model https://www.w3.org/TR/CSS22/box.html
{
margin-top: auto;
Expand Down Expand Up @@ -236,7 +236,7 @@ initial inherit unset revert revert-layer
color-adjust:;
}

// Compositing and Blending Level 1 https://www.w3.org/TR/compositing-1/ 13 January 2015
// Compositing and Blending Level 1 https://www.w3.org/TR/compositing-1/ 21 March 2024
{
mix-blend-mode: normal | multiply | screen | overlay | darken | lighten | color-dodge | color-burn | hard-light | soft-light | difference | exclusion | hue | saturation | color | luminosity;
isolation: auto | isolate;
Expand Down Expand Up @@ -357,7 +357,7 @@ step-start step-end steps()
stroke-opacity:;
}

// Filter Effects Module Level 2 https://drafts.fxtf.org/filter-effects-2/ 5 March 2024
// Filter Effects Module Level 2 https://drafts.fxtf.org/filter-effects-2/ 11 March 2024
// Filter Effects Module Level 1 https://www.w3.org/TR/filter-effects-1/ 18 December 2018
{
filter: none | blur() | brightness() | contrast() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | sepia() | saturate();
Expand Down Expand Up @@ -885,7 +885,7 @@ all continuous paged visual audio speech tactile grid bitmap interactive static
presentation-level: same | increment;
}

// CSS Properties and Values API Level 1 https://www.w3.org/TR/css-properties-values-api-1/ 13 October 2020
// CSS Properties and Values API Level 1 https://www.w3.org/TR/css-properties-values-api-1/ 26 March 2024
@property {
syntax:;
inherits: true | false;
Expand Down Expand Up @@ -1287,18 +1287,18 @@ view()
@starting-style {}

// CSS Values and Units Module Level 4 https://www.w3.org/TR/css-values-4/ 12 March 2024
// CSS Values and Units Module Level 3 https://www.w3.org/TR/css-values-3/ 01 December 2022
// CSS Values and Units Module Level 3 https://www.w3.org/TR/css-values-3/ 22 March 2024
mix()
initial nherit unset
url()
left center right top center bottom
calc()
attr()
min() max() clamp()
round() mod() rem()
sin() cos() tan() asin() acos() atan() atan2()
pow() sqrt() hypot() log() exp()
abs() sign()
//! math function that requires space on both side of '+' and '-', https://www.w3.org/TR/css-values-4/#calc-syntax
= calc() min() max() clamp()
= round() mod() rem()
= sin() cos() tan() asin() acos() atan() atan2()
= pow() sqrt() hypot() log() exp()
= abs() sign()
pi infinity NaN

// CSS Viewport Module Level 1 https://www.w3.org/TR/css-viewport-1/ 25 January 2024
Expand Down

0 comments on commit 578fa93

Please sign in to comment.