diff --git a/Cargo.lock b/Cargo.lock index a17bc31..496c4b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,7 +411,7 @@ dependencies = [ [[package]] name = "mkbook" -version = "0.1.0" +version = "0.2.0" dependencies = [ "askama 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index ccb280a..b90019d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mkbook" -version = "0.1.0" +version = "0.2.0" authors = ["Kenton Hamaluik "] edition = "2018" build = "build.rs" diff --git a/assets/icons.svg b/assets/icons.svg index 8ec8e56..2988103 100644 --- a/assets/icons.svg +++ b/assets/icons.svg @@ -12,5 +12,9 @@ arrow-up + +list-ol + + diff --git a/assets/syntaxes/SCSS.sublime-syntax b/assets/syntaxes/SCSS.sublime-syntax new file mode 100644 index 0000000..5e9bfab --- /dev/null +++ b/assets/syntaxes/SCSS.sublime-syntax @@ -0,0 +1,631 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: SCSS +file_extensions: + - scss +scope: source.scss + +variables: + unicode: '\\\h{1,6}[ \t\n\f]?' + escape: '(?:{{unicode}}|\\[^\n\f\h])' + nonascii: '[\p{L}\p{M}\p{S}\p{N}&&[^[:ascii:]]]' + nmstart: '(?:[[_a-zA-Z]{{nonascii}}]|{{escape}})' + nmchar: '(?:[[-\w]{{nonascii}}]|{{escape}})' + ident: '(?:--{{nmchar}}+|-?{{nmstart}}{{nmchar}}*)' + + combinators: '(?:>{1,3}|[~+])' + + element_names: '\b(a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdi|bdo|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|content|data|datalist|dd|del|details|dfn|dir|dialog|div|dl|dt|element|em|embed|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|h[1-6]|head|header|hgroup|hr|html|i|iframe|img|input|ins|isindex|kbd|keygen|label|legend|li|link|main|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|rtc|s|samp|script|section|select|shadow|small|source|span|strike|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video|wbr|xmp|circle|clipPath|defs|ellipse|filter|foreignObject|g|glyph|glyphRef|image|line|linearGradient|marker|mask|path|pattern|polygon|polyline|radialGradient|rect|stop|switch|symbol|text|textPath|tref|tspan|use)\b' + + custom_element_chars: |- + (?x: + [-_a-z0-9\x{00B7}] + | \\\. + | [\x{00C0}-\x{00D6}] + | [\x{00D8}-\x{00F6}] + | [\x{00F8}-\x{02FF}] + | [\x{0300}-\x{037D}] + | [\x{037F}-\x{1FFF}] + | [\x{200C}-\x{200D}] + | [\x{203F}-\x{2040}] + | [\x{2070}-\x{218F}] + | [\x{2C00}-\x{2FEF}] + | [\x{3001}-\x{D7FF}] + | [\x{F900}-\x{FDCF}] + | [\x{FDF0}-\x{FFFD}] + | [\x{10000}-\x{EFFFF}] + ) + custom_elements: '\b([a-z](?:{{custom_element_chars}})*-(?:{{custom_element_chars}})*)\b(?!{{ident}})' + + pseudo_elements: |- + (?x: + (:{1,2})(?:before|after|first-line|first-letter) # CSS1 & CSS2 require : or :: + | (::)(-(?:moz|ms|webkit)-)?(?:{{ident}}) # CSS3 requires :: + )\b + + regular_pseudo_classes: '\b(active|any-link|blank|checked|current|default|defined|disabled|drop|empty|enabled|first|first-child|first-of-type|fullscreen|future|focus|focus-visible|focus-within|host|hover|indeterminate|in-range|invalid|last-child|last-of-type|left|link|local-link|only-child|only-of-type|optional|out-of-range|past|placeholder-shown|read-only|read-write|required|right|root|scope|target|target-within|user-invalid|valid|visited)\b(?![-])' + functional_pseudo_classes: '\b(dir|lang|matches|not|has|drop|nth-last-child|nth-child|nth-last-of-type|nth-of-type)\b' + + +contexts: + main: + - include: Sass.sublime-syntax#frontmatter + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#selectors + - include: properties + - include: Sass.sublime-syntax#keyframe-operators + - include: Sass.sublime-syntax#interpolated-selectors + - include: Sass.sublime-syntax#custom-element-selectors + - include: at-rules + - include: curly-braces + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + + + properties: + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#comment-block + - match: '\b(font-family|font|family)\b(?=\s*:)' + scope: meta.property-name.css support.type.property-name.css + push: + - match: '(\s*)(;)' + pop: true + captures: + 1: meta.property-value.css + 2: punctuation.terminator.rule.css + - match: '(?=\s*[;})])' + pop: true + - match: ':' + scope: punctuation.separator.key-value.css + push: + - meta_content_scope: meta.property-value.css + - match: '(?=\s*([;})]))' + pop: true + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#numeric-values + - include: Sass.sublime-syntax#property-value-constants + - include: Sass.sublime-syntax#var-function + - include: Sass.sublime-syntax#sass-maps + - include: Sass.sublime-syntax#sass-variables + - include: Sass.sublime-syntax#sass-functions + - include: Sass.sublime-syntax#sass-custom-functions + - match: '{{ident}}(\s+{{ident}})*\b(?!:)' + scope: string.unquoted.css + - include: Sass.sublime-syntax#literal-string + - include: Sass.sublime-syntax#unquoted-concatenated-string + - include: Sass.sublime-syntax#sass-operators + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + - match: '(?={)' + pop: true + - match: '' + pop: true + - match: |- + \b(?x)( + display|width|background-color|height|position|font-family|font-weight + | top|opacity|cursor|background-image|right|visibility|box-sizing + | user-select|left|float|margin-left|margin-top|line-height + | padding-left|z-index|margin-bottom|margin-right|margin + | vertical-align|padding-top|white-space|border-radius|padding-bottom + | padding-right|padding|bottom|clear|max-width|box-shadow|content + | border-color|min-height|min-width|font-style|border-width + | border-collapse|background-size|text-overflow|max-height|text-transform + | text-shadow|text-indent|border-style|overflow-y|list-style-type + | word-wrap|border-spacing|appearance|zoom|overflow-x|border-top-left-radius + | border-bottom-left-radius|border-top-color|pointer-events + | border-bottom-color|align-items|justify-content|letter-spacing + | border-top-right-radius|border-bottom-right-radius|border-right-width + | font-smoothing|border-bottom-width|border-right-color|direction + | border-top-width|src|border-left-color|border-left-width + | tap-highlight-color|table-layout|background-clip|word-break + | transform-origin|resize|filter|backdrop-filter|backface-visibility|text-rendering + | box-orient|transition-property|transition-duration|word-spacing + | quotes|outline-offset|animation-timing-function|animation-duration + | animation-name|transition-timing-function|border-bottom-style + | border-bottom|transition-delay|transition|unicode-bidi|border-top-style + | border-top|unicode-range|list-style-position|orphans|outline-width + | line-clamp|order|flex-direction|box-pack|animation-fill-mode + | outline-color|list-style-image|list-style|touch-action|flex-grow + | border-left-style|border-left|animation-iteration-count + | page-break-inside|box-flex|box-align|page-break-after|animation-delay + | widows|border-right-style|border-right|flex-align|outline-style + | outline|background-origin|animation-direction|fill-opacity + | background-attachment|flex-wrap|transform-style|counter-increment + | overflow-wrap|counter-reset|animation-play-state|animation + | will-change|box-ordinal-group|image-rendering|mask-image|flex-flow + | background-position-y|stroke-width|background-position-x|background-position + | background-blend-mode|flex-shrink|flex-basis|flex-order|flex-item-align + | flex-line-pack|flex-negative|flex-pack|flex-positive|flex-preferred-size + | flex|user-drag|font-stretch|column-count|empty-cells|align-self + | caption-side|mask-size|column-gap|mask-repeat|box-direction + | font-feature-settings|mask-position|align-content|object-fit + | columns|text-fill-color|clip-path|stop-color|font-kerning + | page-break-before|stroke-dasharray|size|fill-rule|border-image-slice + | column-width|break-inside|column-break-before|border-image-width + | stroke-dashoffset|border-image-repeat|border-image-outset|line-break + | stroke-linejoin|stroke-linecap|stroke-miterlimit|stroke-opacity + | stroke|shape-rendering|border-image-source|border-image|border + | tab-size|writing-mode|perspective-origin-y|perspective-origin-x + | perspective-origin|perspective|text-align-last|text-align|clip-rule + | clip|text-anchor|column-rule-color|box-decoration-break|column-fill + | fill|column-rule-style|mix-blend-mode|text-emphasis-color + | baseline-shift|dominant-baseline|page|alignment-baseline + | column-rule-width|column-rule|break-after|font-variant-ligatures + | transform-origin-y|transform-origin-x|transform|object-position + | break-before|column-span|isolation|shape-outside|all + | color-interpolation-filters|marker|marker-end|marker-start + | marker-mid|color-rendering|color-interpolation|background-repeat-x + | background-repeat-y|background-repeat|background|mask-type + | flood-color|flood-opacity|text-orientation|mask-composite + | text-emphasis-style|paint-order|lighting-color|shape-margin + | text-emphasis-position|text-emphasis|shape-image-threshold + | mask-clip|mask-origin|mask|font-variant-caps|font-variant-alternates + | font-variant-east-asian|font-variant-numeric|font-variant-position + | font-variant|font-size-adjust|font-size|font-language-override + | font-display|font-synthesis|font|line-box-contain|text-justify + | text-decoration-color|text-decoration-style|text-decoration-line + | text-decoration|text-underline-position|grid-template-rows + | grid-template-columns|grid-template-areas|grid-template|rotate|scale + | translate|scroll-behavior|grid-column-start|grid-column-end + | grid-column-gap|grid-row-start|grid-row-end|grid-auto-rows + | grid-area|grid-auto-flow|grid-auto-columns|image-orientation + | hyphens|overflow-scrolling|overflow|color-profile|kerning + | nbsp-mode|color|image-resolution|grid-row-gap|grid-row|grid-column + | blend-mode|azimuth|pause-after|pause-before|pause|pitch-range|pitch + | text-height|system|negative|prefix|suffix|range|pad|fallback + | additive-symbols|symbols|speak-as|speak|grid-gap + )\b(?=\s*:) + scope: meta.property-name.css support.type.property-name.css + push: + - include: property-value-wrapper + - match: '(-(?:webkit|moz|ms|o)-)({{ident}})(?=\s*:)' + captures: + 0: meta.property-name.css + 1: support.type.vendor-prefix.css + 2: support.type.property-name.css + push: + - include: property-value-wrapper + - match: '(\$)([a-zA-Z0-9_-][\w-]*)' + captures: + 0: variable.declaration.sass + 1: punctuation.definition.variable.sass + push: + - include: property-value-wrapper + - match: '(--)({{nmchar}}+)' + captures: + 0: meta.property-name.css support.type.custom-property.css + 1: punctuation.definition.custom-property.css + 2: support.type.custom-property.name.css + push: + - include: property-value-wrapper + # Partial property names, split at "-" + # http://sass-lang.com/documentation/file.SASS_REFERENCE.html#nested_properties + - match: '\b(z|y|x|writing|wrap|word|will|width|white|weight|visibility|vertical|variant-position|variant-numeric|variant-ligatures|variant-east-asian|variant-caps|variant-alternates|variant|user|unicode|underline-position|underline|type|transition|transform|touch|top-width|top-style|top-right-radius|top-left-radius|top-color|top|timing-function|timing|threshold|text|template-rows|template-columns|template-areas|template|tap|table|tab|synthesis|symbols|style-type|style-position|style-image|style|stroke|stretch|stop|state|start|speak|span|spacing|space|source|smoothing|slice|sizing|size-adjust|size|side|shrink|shift|shape|shadow|settings|self|select|scrolling|scroll|rule-width|rule-style|rule-color|rule|rows|row-start|row-gap|row-end|row|right-width|right-style|right-radius|right-color|right|resolution|reset|repeat-y|repeat-x|repeat|rendering|range|radius|property|profile|preferred-size|preferred|positive|position-y|position-x|position|pointer|play-state|play|pitch|perspective|pause|path|paint|page|padding|pack|override|overflow|outside|outset|outline|origin-y|origin-x|origin|orientation|orient|ordinal-group|ordinal|order|opacity|offset|object|numeric|negative|nbsp|name|mode|mix|miterlimit|min|mid|max|mask|marker|margin|list|linejoin|linecap|line-pack|line|lighting|ligatures|letter|left-width|left-style|left-radius|left-color|left|layout|last|language-override|language|kerning|justify|iteration-count|iteration|items|item-align|item|interpolation-filters|interpolation|inside|index|indent|increment|image-width|image-threshold|image-source|image-slice|image-repeat|image-outset|image|highlight-color|highlight|height|grow|group|grid|gap|function|font|flow|flood|flex|fit|filters|fill-mode|fill-color|fill|feature-settings|feature|family|events|end|empty|emphasis-style|emphasis-position|emphasis-color|emphasis|duration|drag|dominant|display|direction|delay|decoration-style|decoration-line|decoration-color|decoration-break|decoration|dashoffset|dasharray|counter|count|content|contain|composite|columns|column-start|column-gap|column-end|column|color|collapse|clip|clamp|change|cells|caption|caps|break-inside|break-before|break-after|break|box-contain|box|bottom-width|bottom-style|bottom-color|bottom|border|blend-mode|blend|bidi|behavior|before|basis|baseline|background|backface|auto-rows|auto-flow|auto-columns|auto|attachment|as|areas|area|animation|anchor|alternates|alignment|align-last|align|after|adjust|additive|action)\b' + scope: meta.property-name.css support.type.property-name.css + push: + - include: property-value-wrapper + - match: '[a-zA-Z0-9_-]*((#)({)((\$)([a-zA-Z0-9_-][\w-]*))(}))[a-zA-Z0-9_-]*' + captures: + 0: meta.property-name.css support.type.property-name + 1: meta.group.interpolation.sass + 2: punctuation.definition.variable.sass + 3: punctuation.definition.group.begin.sass + 4: variable.other.sass + 5: punctuation.definition.variable.sass + 7: punctuation.definition.group.end.sass + push: + - include: property-value-wrapper + + property-value-wrapper: + - match: '(\s*)(;)' + pop: true + captures: + 1: meta.property-value.css + 2: punctuation.terminator.rule.css + - match: '(?=\s*[;})])' + pop: true + - match: '\s*(:)' + captures: + 1: punctuation.separator.key-value.css + push: + - meta_content_scope: meta.property-value.css + - match: '(?=\s*[;})])' + pop: true + - include: Sass.sublime-syntax#property-values + - match: '(?={)' + pop: true + - match: '' + pop: true + + + at-rules: + - match: '(@)(each)\b' + scope: keyword.control.flow.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.each.sass + - include: Sass.sublime-syntax#sass-variables + - include: Sass.sublime-syntax#comma-delimiter + - match: '(?={)' + pop: true + - match: '\b(in)\b' + scope: keyword.operator.sass + push: + - match: '(?={)' + pop: true + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#comma-delimiter + - include: Sass.sublime-syntax#var-function + - include: Sass.sublime-syntax#sass-variables + - include: Sass.sublime-syntax#sass-functions + - include: Sass.sublime-syntax#sass-custom-functions + - include: Sass.sublime-syntax#sass-interpolation + - include: Sass.sublime-syntax#sass-maps + - include: Sass.sublime-syntax#unquoted-string + - include: Sass.sublime-syntax#sass-operators + - match: '(@)(for|while)\b' + scope: keyword.control.flow.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '(?={)' + pop: true + - include: Sass.sublime-syntax#sass-script-expression + - match: '(@)(if|else if|else)\b' + scope: keyword.control.flow.conditional.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '(?={)' + pop: true + - include: Sass.sublime-syntax#sass-script-expression + - match: '(@)(debug|warn|error)\b' + scope: keyword.control.at-rule.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '(;)' + scope: punctuation.terminator.rule.sass + pop: true + - include: Sass.sublime-syntax#sass-script-expression + - match: '(@)(at-root)\b' + scope: keyword.control.at-rule.at-root.sass + captures: + 1: punctuation.definition.keyword.sass + - match: '(@)(extend)\b' + scope: keyword.control.at-rule.extend.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.extend.sass + - match: '(;)' + scope: punctuation.terminator.rule.sass + pop: true + - match: \!\s*(default|global|optional) + scope: keyword.other.sass + - include: Sass.sublime-syntax#selectors + - include: Sass.sublime-syntax#custom-element-selectors + + - match: '((@)(mixin|function))\s+([\w-]+)' + captures: + 1: keyword.control.at-rule.sass + 2: punctuation.definition.keyword.sass + 4: entity.name.function.sass + push: + - meta_scope: meta.function.declaration.sass + - match: '\s*(?=[\{;])' + pop: true + - match: '\(' + scope: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.function.parameters.sass + - match: '\)' + scope: punctuation.definition.group.end.sass + pop: true + - include: Sass.sublime-syntax#comma-delimiter + - match: '(\$)([a-zA-Z0-9_-][\w-]*)' + scope: variable.parameter.sass + captures: + 1: punctuation.definition.variable.sass + push: + - match: '(?=[,\)])' + pop: true + - match: ':' + scope: punctuation.separator.key-value.css + - match: '\b(false|true|null)\b' + scope: constant.language.sass + - include: Sass.sublime-syntax#property-values + - match: '\{' + scope: punctuation.section.property-list.begin.sass + push: + - match: '\}' + scope: punctuation.section.property-list.end.sass + pop: true + - include: main + - match: '((@)(include))\s+([\w-]+)' + captures: + 0: variable.function.sass + 1: keyword.control.at-rule.sass + 2: punctuation.definition.keyword.sass + push: + - meta_scope: meta.function-call.sass + - match: '\s*(;)' + captures: + 1: punctuation.terminator.rule.sass + pop: true + - match: '\s*(?=[\{;])' + pop: true + - match: '\(' + scope: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.function-call.arguments.sass + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#sass-variables + - include: Sass.sublime-syntax#sass-functions + - include: Sass.sublime-syntax#sass-operators + - include: Sass.sublime-syntax#comma-delimiter + - include: Sass.sublime-syntax#property-values + - include: Sass.sublime-syntax#literal-string + - match: '{{ident}}' + scope: string.unquoted.sass + - include: Sass.sublime-syntax#selectors + - include: Sass.sublime-syntax#custom-element-selectors + - match: '\)' + scope: punctuation.definition.group.end.sass + pop: true + - match: '(@)(return)\b' + scope: keyword.control.at-rule.return.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '\s*(;)' + captures: + 1: punctuation.terminator.rule.css + pop: true + - include: Sass.sublime-syntax#property-values + - match: '((@)(?:-(?:webkit|moz|o)-)?(charset|namespace|font-face)\b)' + captures: + 1: keyword.control.at-rule.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.css + - match: '\s*(;)' + captures: + 1: punctuation.terminator.rule.sass + pop: true + - match: '\s*(?=[\{;])' + pop: true + - match: (url)(\() + captures: + 1: meta.function-call.css support.function.url.css + 2: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: Sass.sublime-syntax#literal-string + - include: Sass.sublime-syntax#unquoted-string + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#literal-string + - match: '\s*((@)counter-style\b)\s+(?:(?i:\b(decimal|none)\b)|({{ident}}))?\s*(?=\{|$)' + captures: + 1: keyword.control.at-rule.counter-style.css + 2: punctuation.definition.keyword.css + 3: invalid.illegal.counter-style-name.css + 4: entity.other.counter-style-name.css + push: + - meta_scope: meta.at-rule.counter-style.css + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - match: '(?=\{)' + pop: true + - match: '(?=\s*@custom-media\b)' + push: + - match: ; + scope: punctuation.terminator.css + pop: true + - match: \s*((@)custom-media) + captures: + 1: keyword.control.at-rule.custom-media.css + 2: punctuation.definition.keyword.css + 3: support.constant.custom-media.css + push: + - meta_scope: meta.at-rule.custom-media.css + - match: \s*(?=;) + pop: true + - include: media-query + - match: '((@)document)' + captures: + 1: keyword.control.at-rule.document.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.document.css + - match: '(?=[\{;])' + pop: true + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#url-function + - include: Sass.sublime-syntax#url-prefix-function + - include: Sass.sublime-syntax#domain-function + - include: Sass.sublime-syntax#regexp-function + - include: Sass.sublime-syntax#comma-delimiter + - match: '\s*((@)import\b)\s*' + captures: + 1: keyword.control.at-rule.import.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.import.css + - match: ';' + scope: punctuation.terminator.rule.sass + pop: true + - match: '(\()(reference|inline|less|css|once|multiple|optional)(\))' + captures: + 0: meta.at-rule.arguments.sass + 1: punctuation.definition.group.begin.sass + 2: constant.other.sass + 3: punctuation.definition.group.end.sass + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#literal-string + - include: Sass.sublime-syntax#url-function + - include: media-query + - match: '\s*((@)(-webkit-|-moz-|-o-)?keyframes)' + captures: + 1: keyword.control.at-rule.keyframe.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.keyframe.css + - match: '\s*(?=[\{;])' + pop: true + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: Sass.sublime-syntax#sass-interpolation + - match: '\s*({{ident}})?' + captures: + 1: entity.other.animation-name.css + - match: '\s*(?:(,)|(?=[{;]))' + captures: + 1: punctuation.definition.arbitrary-repetition.css + - match: '\s*((@)media)\b' + captures: + 1: keyword.control.at-rule.media.css + 2: punctuation.definition.keyword.css + 3: support.constant.media.css + push: + - meta_scope: meta.at-rule.media.css + - include: media-query + - match: '(?=\{)' + pop: true + - match: '\s*((@)namespace)\s+({{ident}}(?!{{nmchar}}|\())?' + captures: + 1: keyword.control.at-rule.namespace.css + 2: punctuation.definition.keyword.css + 3: entity.other.namespace-prefix.css + push: + - meta_scope: meta.at-rule.namespace.css + - include: at-rule-punctuation + - include: Sass.sublime-syntax#literal-string + - include: Sass.sublime-syntax#url-function + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - match: '\s*((@)page)\s*(?:(:)(first|left|right))?\s*' + captures: + 1: keyword.control.at-rule.page.css + 2: punctuation.definition.keyword.css + 3: punctuation.definition.entity.css + 4: entity.other.pseudo-class.css + push: + - meta_scope: meta.at-rule.page.css + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - match: '\s*(?=\{)' + pop: true + - match: '((@)supports)' + captures: + 1: keyword.control.at-rule.supports.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.supports.css + - match: '(?=\{)' + pop: true + - include: Sass.sublime-syntax#at-supports-operators + - include: at-supports-parens + - match: '((@)content)' + captures: + 1: keyword.control.at-rule.content.sass + 2: punctuation.definition.keyword.sass + push: + - match: ';' + scope: punctuation.terminator.rule.sass + pop: true + - match: '(?=$)' + pop: true + + at-supports-parens: + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: Sass.sublime-syntax#at-supports-operators + - include: at-supports-parens + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - include: properties + + at-rule-punctuation: + - match: ';' + scope: punctuation.terminator.rule.css + - match: '(?=;|$)' + pop: true + + media-query: + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - match: \b(?i:all|aural|braille|embossed|handheld|print|projection|screen|speech|tty|tv)\b + scope: support.constant.media.css + - match: '\b(?i:and|or|not|only)\b' + scope: keyword.operator.logic.media.css + - match: ',' + scope: punctuation.definition.arbitrary-repetition.css + - match: \( + scope: punctuation.definition.group.begin.css + push: + - match: \) + scope: punctuation.definition.group.end.css + pop: true + - include: Sass.sublime-syntax#comment-block + - include: Sass.sublime-syntax#comment-line + - match: |- + (?x) + ( + (-webkit-|-o-)? + ((min|max)-)? + (-moz-)? + ( + ((device-)?(height|width|aspect-ratio|pixel-ratio))| + (color(-index)?)|monochrome|resolution + ) + )|grid|scan|orientation + \s*(?=[:)]) + captures: + 0: support.type.property-name.media.css + 2: support.type.vendor-prefix.css + 5: support.type.vendor-prefix.css + push: + - match: (:)|(?=\)) + captures: + 1: punctuation.separator.key-value.css + pop: true + - match: \b(portrait|landscape|progressive|interlace) + scope: support.constant.property-value.css + - match: \s*(\d+)(/)(\d+) + captures: + 1: constant.numeric.css + 2: keyword.operator.arithmetic.css + 3: constant.numeric.css + - include: Sass.sublime-syntax#numeric-values + - include: Sass.sublime-syntax#sass-value-expression + + + curly-braces: + - match: '\{' + scope: punctuation.section.property-list.begin.css + - match: '\}' + scope: punctuation.section.property-list.end.css diff --git a/assets/syntaxes/Sass.sublime-syntax b/assets/syntaxes/Sass.sublime-syntax new file mode 100644 index 0000000..9eda17c --- /dev/null +++ b/assets/syntaxes/Sass.sublime-syntax @@ -0,0 +1,2597 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +name: Sass +file_extensions: + - sass +scope: source.sass + + +variables: + unicode: '\\\h{1,6}[ \t\n\f]?' + escape: '(?:{{unicode}}|\\[^\n\f\h])' + nonascii: '[\p{L}\p{M}\p{S}\p{N}&&[^[:ascii:]]]' + nmstart: '(?:[[_a-zA-Z]{{nonascii}}]|{{escape}})' + nmchar: '(?:[[-\w]{{nonascii}}]|{{escape}})' + ident: '(?:--{{nmchar}}+|-?{{nmstart}}{{nmchar}}*)' + + integer: '(?:[-+]?\d+)' + number: '[-+]?(?:(?:\d*\.\d+(?:[eE]{{integer}})*)|\b{{integer}})' + + font_relative_lengths: '(?i:em|ex|ch|rem)' + viewport_percentage_lengths: '(?i:vw|vh|vmin|vmax)' + absolute_lengths: '(?i:cm|mm|q|in|pt|pc|px|fr)' + angle_units: '(?i:deg|grad|rad|turn)' + duration_units: '(?i:s|ms)' + frequency_units: '(?i:Hz|kHz)' + resolution_units: '(?i:dpi|dpcm|dppx)' + + combinators: '(?:>{1,3}|[~+])' + + element_names: '\b(a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdi|bdo|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|content|data|datalist|dd|del|details|dfn|dir|dialog|div|dl|dt|element|em|embed|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|h[1-6]|head|header|hgroup|hr|html|i|iframe|img|input|ins|isindex|kbd|keygen|label|legend|li|link|main|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|rtc|s|samp|script|section|select|shadow|small|source|span|strike|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video|wbr|xmp|circle|clipPath|defs|ellipse|filter|foreignObject|g|glyph|glyphRef|image|line|linearGradient|marker|mask|path|pattern|polygon|polyline|radialGradient|rect|stop|switch|symbol|text|textPath|tref|tspan|use)\b' + + counter_styles: |- + (?xi: + arabic-indic | armenian | bengali | cambodian | circle + | cjk-decimal | cjk-earthly-branch | cjk-heavenly-stem | decimal-leading-zero + | decimal | devanagari | disclosure-closed | disclosure-open | disc + | ethiopic-numeric | georgian | gujarati | gurmukhi | hebrew + | hiragana-iroha | hiragana | japanese-formal | japanese-informal + | kannada | katakana-iroha | katakana | khmer + | korean-hangul-formal | korean-hanja-formal | korean-hanja-informal | lao + | lower-alpha | lower-armenian | lower-greek | lower-latin | lower-roman + | malayalam | mongolian | myanmar | oriya | persian + | simp-chinese-formal | simp-chinese-informal + | square | tamil | telugu | thai | tibetan + | trad-chinese-formal | trad-chinese-informal + | upper-alpha | upper-armenian | upper-latin | upper-roman + ) + + custom_element_chars: |- + (?x: + [-_a-z0-9\x{00B7}] + | \\\. + | [\x{00C0}-\x{00D6}] + | [\x{00D8}-\x{00F6}] + | [\x{00F8}-\x{02FF}] + | [\x{0300}-\x{037D}] + | [\x{037F}-\x{1FFF}] + | [\x{200C}-\x{200D}] + | [\x{203F}-\x{2040}] + | [\x{2070}-\x{218F}] + | [\x{2C00}-\x{2FEF}] + | [\x{3001}-\x{D7FF}] + | [\x{F900}-\x{FDCF}] + | [\x{FDF0}-\x{FFFD}] + | [\x{10000}-\x{EFFFF}] + ) + custom_elements: '\b([a-z](?:{{custom_element_chars}})*-(?:{{custom_element_chars}})*)\b(?!{{ident}})' + + pseudo_elements: |- + (?x: + (:{1,2})(?:before|after|first-line|first-letter) # CSS1 & CSS2 require : or :: + | (::)(-(?:moz|ms|webkit)-)?(?:{{ident}}) # CSS3 requires :: + )\b + + regular_pseudo_classes: '\b(active|any-link|blank|checked|current|default|defined|disabled|drop|empty|enabled|first|first-child|first-of-type|fullscreen|future|focus|focus-visible|focus-within|host|hover|indeterminate|in-range|invalid|last-child|last-of-type|left|link|local-link|only-child|only-of-type|optional|out-of-range|past|placeholder-shown|read-only|read-write|required|right|root|scope|target|target-within|user-invalid|valid|visited)\b(?![-])' + functional_pseudo_classes: '\b(dir|lang|matches|not|has|drop|nth-last-child|nth-child|nth-last-of-type|nth-of-type)\b' + + property_names: |- + \b(?x)( + display|width|background-color|height|position|font-family|font-weight + | top|opacity|cursor|background-image|right|visibility|box-sizing + | user-select|left|float|margin-left|margin-top|line-height + | padding-left|z-index|margin-bottom|margin-right|margin + | vertical-align|padding-top|white-space|border-radius|padding-bottom + | padding-right|padding|bottom|clear|max-width|box-shadow|content + | border-color|min-height|min-width|font-style|border-width + | border-collapse|background-size|text-overflow|max-height|text-transform + | text-shadow|text-indent|border-style|overflow-y|list-style-type + | word-wrap|border-spacing|appearance|zoom|overflow-x|border-top-left-radius + | border-bottom-left-radius|border-top-color|pointer-events + | border-bottom-color|align-items|justify-content|letter-spacing + | border-top-right-radius|border-bottom-right-radius|border-right-width + | font-smoothing|border-bottom-width|border-right-color|direction + | border-top-width|src|border-left-color|border-left-width + | tap-highlight-color|table-layout|background-clip|word-break + | transform-origin|resize|filter|backdrop-filter|backface-visibility|text-rendering + | box-orient|transition-property|transition-duration|word-spacing + | quotes|outline-offset|animation-timing-function|animation-duration + | animation-name|transition-timing-function|border-bottom-style + | border-bottom|transition-delay|transition|unicode-bidi|border-top-style + | border-top|unicode-range|list-style-position|orphans|outline-width + | line-clamp|order|flex-direction|box-pack|animation-fill-mode + | outline-color|list-style-image|list-style|touch-action|flex-grow + | border-left-style|border-left|animation-iteration-count + | page-break-inside|box-flex|box-align|page-break-after|animation-delay + | widows|border-right-style|border-right|flex-align|outline-style + | outline|background-origin|animation-direction|fill-opacity + | background-attachment|flex-wrap|transform-style|counter-increment + | overflow-wrap|counter-reset|animation-play-state|animation + | will-change|box-ordinal-group|image-rendering|mask-image|flex-flow + | background-position-y|stroke-width|background-position-x|background-position + | background-blend-mode|flex-shrink|flex-basis|flex-order|flex-item-align + | flex-line-pack|flex-negative|flex-pack|flex-positive|flex-preferred-size + | flex|user-drag|font-stretch|column-count|empty-cells|align-self + | caption-side|mask-size|column-gap|mask-repeat|box-direction + | font-feature-settings|mask-position|align-content|object-fit + | columns|text-fill-color|clip-path|stop-color|font-kerning + | page-break-before|stroke-dasharray|size|fill-rule|border-image-slice + | column-width|break-inside|column-break-before|border-image-width + | stroke-dashoffset|border-image-repeat|border-image-outset|line-break + | stroke-linejoin|stroke-linecap|stroke-miterlimit|stroke-opacity + | stroke|shape-rendering|border-image-source|border-image|border + | tab-size|writing-mode|perspective-origin-y|perspective-origin-x + | perspective-origin|perspective|text-align-last|text-align|clip-rule + | clip|text-anchor|column-rule-color|box-decoration-break|column-fill + | fill|column-rule-style|mix-blend-mode|text-emphasis-color + | baseline-shift|dominant-baseline|page|alignment-baseline + | column-rule-width|column-rule|break-after|font-variant-ligatures + | transform-origin-y|transform-origin-x|transform|object-position + | break-before|column-span|isolation|shape-outside|all + | color-interpolation-filters|marker|marker-end|marker-start + | marker-mid|color-rendering|color-interpolation|background-repeat-x + | background-repeat-y|background-repeat|background|mask-type + | flood-color|flood-opacity|text-orientation|mask-composite + | text-emphasis-style|paint-order|lighting-color|shape-margin + | text-emphasis-position|text-emphasis|shape-image-threshold + | mask-clip|mask-origin|mask|font-variant-caps|font-variant-alternates + | font-variant-east-asian|font-variant-numeric|font-variant-position + | font-variant|font-size-adjust|font-size|font-language-override + | font-display|font-synthesis|font|line-box-contain|text-justify + | text-decoration-color|text-decoration-style|text-decoration-line + | text-decoration|text-underline-position|grid-template-rows + | grid-template-columns|grid-template-areas|grid-template|rotate|scale + | translate|scroll-behavior|grid-column-start|grid-column-end + | grid-column-gap|grid-row-start|grid-row-end|grid-auto-rows + | grid-area|grid-auto-flow|grid-auto-columns|image-orientation + | hyphens|overflow-scrolling|overflow|color-profile|kerning + | nbsp-mode|color|image-resolution|grid-row-gap|grid-row|grid-column + | blend-mode|azimuth|pause-after|pause-before|pause|pitch-range|pitch + | text-height|system|negative|prefix|suffix|range|pad|fallback + | additive-symbols|symbols|speak-as|speak|grid-gap + )\b + + +contexts: + main: + - match: '\{|\}|;' + scope: invalid.illegal.sass + - include: frontmatter + - include: comment-block + - include: comment-line + - include: sass-mixin-directives + - include: selectors + - include: properties + - include: keyframe-operators + - include: interpolated-selectors + - include: custom-element-selectors + - include: at-rules + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + + + frontmatter: + - match: '^---$' + scope: frontmatter.jekyll punctuation.section.frontmatter.begin.jekyll + embed: scope:source.yaml + embed_scope: frontmatter.jekyll + escape: '^---$' + escape_captures: + 0: frontmatter.jekyll punctuation.section.frontmatter.end.jekyll + + + selectors: + # wild card + - match: '\s*(\*)' + captures: + 1: entity.name.tag.wildcard.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + # ampersand + - match: '\s*(&)' + captures: + 1: keyword.operator.ampersand.sass + push: + - meta_scope: meta.selector.css + - match: '[-_]+' + scope: entity.other.attribute-name.css + push: + - match: '{{ident}}' + scope: entity.other.attribute-name.css + - include: sass-interpolation + - include: selector-parts + - include: selector-parts + # standard elements + pseudo elements + - match: '\s*({{element_names}})(?={{pseudo_elements}})' + captures: + 1: entity.name.tag.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + # standard elements + pseudoclasses + - match: '\s*({{element_names}})(?=:{{regular_pseudo_classes}})' + captures: + 1: entity.name.tag.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + - match: '\s*({{element_names}})(?=:({{functional_pseudo_classes}})\()' + captures: + 1: entity.name.tag.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + - match: '\s*({{element_names}})(?=:(-(moz|ms|webkit)-){{ident}})' + captures: + 1: entity.name.tag.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + # standard elements + - match: '\s*({{element_names}})(?![-:])' + # stop this at word break and not -, plus : is for pseudos + captures: + 1: entity.name.tag.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + # classes + - match: '\s*(\.)(?={{ident}}|#)' + captures: + 1: entity.other.attribute-name.class.css punctuation.definition.entity.css + push: + - meta_scope: meta.selector.css + - match: '{{ident}}' + scope: entity.other.attribute-name.class.css + - include: sass-interpolation + - include: selector-parts + # id's + - match: '\s*(\#)(?={{ident}}|#)' + captures: + 1: entity.other.attribute-name.id.css punctuation.definition.entity.css + push: + - meta_scope: meta.selector.css + - match: '{{ident}}' + scope: entity.other.attribute-name.id.css + - include: sass-interpolation + - include: selector-parts + # extend-only selectors + - match: '\s*(%){{ident}}*' + captures: + 0: entity.other.attribute-name.placeholder.sass + 1: punctuation.definition.entity.sass + push: + - meta_scope: meta.selector.css + - match: '{{ident}}' + scope: entity.other.attribute-name.placeholder.css + - include: sass-interpolation + - include: selector-parts + # attributes + - match: '\s*(?=\[)' + push: + - meta_scope: meta.selector.css + - match: '\[' + scope: punctuation.definition.entity.css + push: + - meta_scope: meta.attribute-selector.css + - match: '\]' + scope: punctuation.definition.entity.css + pop: true + - include: qualified-name + - match: '({{ident}})' + scope: entity.other.attribute-name.css + - match: '\s*([~*|^$]?=)\s*' + captures: + 1: keyword.operator.attribute-selector.css + push: + - match: '[^\s\]\[''"]' + scope: string.unquoted.css + - include: literal-string + - match: '(?=(\s|\]))' + pop: true + - match: '(?:\s+([iI]))?' # case insensitive flag + captures: + 1: keyword.other.css + - include: selector-parts + - include: pseudo-elements + - include: pseudo-classes + - match: '^\s*({{combinators}})(?![>~+])\s*' + captures: + 0: meta.selector.css + 1: punctuation.separator.combinator.css + + + interpolated-selector-body: + - match: '({)' + scope: punctuation.definition.group.begin.sass + push: + - match: '(})' + scope: punctuation.definition.group.end.sass + pop: true + - include: Sass.sublime-syntax#sass-script-expression + - include: selector-parts + + interpolated-selectors: + - match: '\s*(#)(?={.*}{{pseudo_elements}})' + captures: + 1: punctuation.definition.variable.sass + push: + - meta_scope: meta.selector.css meta.group.interpolation.sass + - include: interpolated-selector-body + - match: '\s*(#)(?={.*}:{{regular_pseudo_classes}})' + captures: + 1: punctuation.definition.variable.sass + push: + - meta_scope: meta.selector.css meta.group.interpolation.sass + - include: interpolated-selector-body + - match: '\s*(#)(?={.*}:({{functional_pseudo_classes}})\()' + captures: + 1: punctuation.definition.variable.sass + push: + - meta_scope: meta.selector.css meta.group.interpolation.sass + - include: interpolated-selector-body + - match: '\s*(#)(?={.*}:(-(moz|ms|webkit)-){{ident}})' + captures: + 1: punctuation.definition.variable.sass + push: + - meta_scope: meta.selector.css meta.group.interpolation.sass + - include: interpolated-selector-body + - match: '\s*(#)(?={.*}(?![-:]))' + captures: + 1: punctuation.definition.variable.sass + push: + - meta_scope: meta.selector.css meta.group.interpolation.sass + - include: interpolated-selector-body + + custom-element-selectors: + # custom elements + pseudo elements + - match: '\s*({{custom_elements}})(?={{pseudo_elements}})' + captures: + 1: entity.name.tag.custom.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + # custom elements + pseudoclasses + - match: '\s*({{custom_elements}})(?=:{{regular_pseudo_classes}})' + captures: + 1: entity.name.tag.custom.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + - match: '\s*({{custom_elements}})(?=:({{functional_pseudo_classes}})\()' + captures: + 1: entity.name.tag.custom.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + - match: '\s*({{custom_elements}})(?=:(-(moz|ms|webkit)-){{ident}})' + captures: + 1: entity.name.tag.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + # custom elements + - match: '\s*({{custom_elements}})(?![-:])' + captures: + 1: entity.name.tag.custom.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + + selector-parts: + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + pop: true + - match: '\s*({{combinators}})(?![>~+])\s*' + captures: + 1: punctuation.separator.combinator.css + pop: true + - match: '\s*(?=\{)' # { of course only for scss, but doesn't hurt here + pop: true + - match: '(?=[.#\[&])' # look ahead for classes, id's and attr's + pop: true + - match: '(?=\))' # if passed as a parameter + pop: true + - include: comment-block + - include: pseudo-elements + - include: pseudo-classes + - match: '\s*(?=$|//|/\*)' + pop: true + - match: '\s*(?=\b)' + pop: true + + pseudo-elements: + - match: '\s*{{pseudo_elements}}' + scope: entity.other.pseudo-element.css + captures: + 1: punctuation.definition.entity.css + 2: punctuation.definition.entity.css + 3: support.type.vendor-prefix.css + + pseudo-classes: + - match: '\s*(:)(dir|lang)(?=\()' + scope: entity.other.pseudo-class.css + captures: + 1: punctuation.definition.entity.css + push: + - meta_scope: meta.selector.css meta.function-call.css + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: unquoted-string + - include: selector-parts + + - match: '\s*(:)(matches|not|has)(?=\()' + scope: entity.other.pseudo-class.css + captures: + 1: punctuation.definition.entity.css + push: + - meta_scope: meta.selector.css meta.function-call.css + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - match: ',' + scope: punctuation.separator.css + - include: selectors + - include: custom-element-selectors + - match: '' + pop: true + - include: selector-parts + + - match: '\s*(:)(drop)(?=\()' + scope: entity.other.pseudo-class.css + captures: + 1: punctuation.definition.entity.css + push: + - meta_scope: meta.selector.css meta.function-call.css + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - match: \b(active|valid|invalid)\b + scope: keyword.other.pseudo-class.css + - include: selector-parts + + - match: '\s*(:)(nth-last-child|nth-child|nth-last-of-type|nth-of-type)(?=\()' + scope: entity.other.pseudo-class.css + captures: + 1: punctuation.definition.entity.css + push: + - meta_scope: meta.selector.css meta.function-call.css + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - match: \b(even|odd)\b + scope: keyword.other.pseudo-class.css + - match: '(?:[-+]?(?:\d+)?(n)(\s*[-+]\s*\d+)?|[-+]?\s*\d+)' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + - include: selector-parts + + - match: '\s*(:)(-(moz|ms|webkit)-){{ident}}' + scope: entity.other.pseudo-class.css + captures: + 1: punctuation.definition.entity.css + 2: support.type.vendor-prefix.css + push: + - meta_scope: meta.selector.css + - include: selector-parts + + - match: '\s*(:)({{regular_pseudo_classes}})' + scope: meta.selector.css entity.other.pseudo-class.css + captures: + 1: punctuation.definition.entity.css + + + + properties: + - include: comment-line + - include: comment-block + - match: '^\s+(:)({{property_names}})(?=\s)' + captures: + 1: punctuation.separator.key-value.css + 2: meta.property-name.css support.type.property-name.css + push: + - meta_content_scope: meta.property-value.css + - match: '\s*(?=$)' + pop: true + - include: property-values + - match: '\b(font-family|font|family)\b(?=\s*:)' + scope: meta.property-name.css support.type.property-name.css + push: + - match: '(?=\s*[)])' + pop: true + - match: ':' + scope: punctuation.separator.key-value.css + push: + - meta_content_scope: meta.property-value.css + - match: '(?=\s*([)]))' + pop: true + - include: comment-line + - include: comment-block + - include: numeric-values + - include: property-value-constants + - include: var-function + - include: sass-maps + - include: sass-variables + - include: sass-functions + - include: sass-custom-functions + - match: '{{ident}}(\s+{{ident}})*\b(?!:)' + scope: string.unquoted.css + - include: literal-string + - include: unquoted-concatenated-string + - include: sass-operators + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + - match: '(?=$)' + pop: true + - match: '' + pop: true + - match: '{{property_names}}' + scope: meta.property-name.css support.type.property-name.css + push: + - include: property-value-wrapper + - match: '(-(?:webkit|moz|ms|o)-)({{ident}})(?=\s*:)' + captures: + 0: meta.property-name.css + 1: support.type.vendor-prefix.css + 2: support.type.property-name.css + push: + - include: property-value-wrapper + - match: '(\$)([a-zA-Z0-9_-][\w-]*)' + captures: + 0: variable.declaration.sass + 1: punctuation.definition.variable.sass + push: + - include: property-value-wrapper + - match: '(--)({{nmchar}}+)' + captures: + 0: meta.property-name.css support.type.custom-property.css + 1: punctuation.definition.custom-property.css + 2: support.type.custom-property.name.css + push: + - include: property-value-wrapper + # Partial property names, split at "-" + # http://sass-lang.com/documentation/file.SASS_REFERENCE.html#nested_properties + - match: '\b(z|y|x|writing|wrap|word|will|width|white|weight|visibility|vertical|variant-position|variant-numeric|variant-ligatures|variant-east-asian|variant-caps|variant-alternates|variant|user|unicode|underline-position|underline|type|transition|transform|touch|top-width|top-style|top-right-radius|top-left-radius|top-color|top|timing-function|timing|threshold|text|template-rows|template-columns|template-areas|template|tap|table|tab|synthesis|symbols|style-type|style-position|style-image|style|stroke|stretch|stop|state|start|speak|span|spacing|space|source|smoothing|slice|sizing|size-adjust|size|side|shrink|shift|shape|shadow|settings|self|select|scrolling|scroll|rule-width|rule-style|rule-color|rule|rows|row-start|row-gap|row-end|row|right-width|right-style|right-radius|right-color|right|resolution|reset|repeat-y|repeat-x|repeat|rendering|range|radius|property|profile|preferred-size|preferred|positive|position-y|position-x|position|pointer|play-state|play|pitch|perspective|pause|path|paint|page|padding|pack|override|overflow|outside|outset|outline|origin-y|origin-x|origin|orientation|orient|ordinal-group|ordinal|order|opacity|offset|object|numeric|negative|nbsp|name|mode|mix|miterlimit|min|mid|max|mask|marker|margin|list|linejoin|linecap|line-pack|line|lighting|ligatures|letter|left-width|left-style|left-radius|left-color|left|layout|last|language-override|language|kerning|justify|iteration-count|iteration|items|item-align|item|interpolation-filters|interpolation|inside|index|indent|increment|image-width|image-threshold|image-source|image-slice|image-repeat|image-outset|image|highlight-color|highlight|height|grow|group|grid|gap|function|font|flow|flood|flex|fit|filters|fill-mode|fill-color|fill|feature-settings|feature|family|events|end|empty|emphasis-style|emphasis-position|emphasis-color|emphasis|duration|drag|dominant|display|direction|delay|decoration-style|decoration-line|decoration-color|decoration-break|decoration|dashoffset|dasharray|counter|count|content|contain|composite|columns|column-start|column-gap|column-end|column|color|collapse|clip|clamp|change|cells|caption|caps|break-inside|break-before|break-after|break|box-contain|box|bottom-width|bottom-style|bottom-color|bottom|border|blend-mode|blend|bidi|behavior|before|basis|baseline|background|backface|auto-rows|auto-flow|auto-columns|auto|attachment|as|areas|area|animation|anchor|alternates|alignment|align-last|align|after|adjust|additive|action)\b' + scope: meta.property-name.css support.type.property-name.css + push: + - include: property-value-wrapper + - match: '[a-zA-Z0-9_-]*((#)({)((\$)([a-zA-Z0-9_-][\w-]*))(}))[a-zA-Z0-9_-]*' + captures: + 0: meta.property-name.css support.type.property-name + 1: meta.group.interpolation.sass + 2: punctuation.definition.variable.sass + 3: punctuation.definition.group.begin.sass + 4: variable.other.sass + 5: punctuation.definition.variable.sass + 7: punctuation.definition.group.end.sass + push: + - include: property-value-wrapper + + property-value-wrapper: + - match: '(\s*)($)' + pop: true + captures: + 1: meta.property-value.css + - match: '(?=\s*\))' + pop: true + - match: '\s*(:)' + captures: + 1: punctuation.separator.key-value.css + push: + - meta_content_scope: meta.property-value.css + - match: '(?=\s*(\)|$))' + pop: true + - include: property-values + - match: '' + pop: true + + property-values: + - match: ';' + scope: invalid.illegal.sass + - match: '\!\s*important' + scope: keyword.other.important.css + captures: + 1: punctuation.definition.keyword.css + - match: '\!\s*(default|global|optional)' + scope: keyword.other.sass + - include: vendor-prefix + - include: comment-line + - include: comment-block + - include: builtin-functions + - include: line-names + - include: unicode-range + - include: numeric-values + - include: color-values + - include: property-value-constants + - include: literal-string + - include: sass-maps + - include: sass-variables + - include: sass-functions + - include: sass-custom-functions + - include: sass-interpolation + - include: unquoted-concatenated-string + - include: sass-operators + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + - match: '{{ident}}' # e.g. animation-name + scope: string.unquoted.css + + at-rules: + - match: '(@)(each)\b' + scope: keyword.control.flow.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.each.sass + - include: sass-variables + - include: comma-delimiter + - match: '(?=$)' + pop: true + - match: \b(in)\b + scope: keyword.operator.sass + push: + - match: '(?=$)' + pop: true + - include: comment-block + - include: comment-line + - include: comma-delimiter + - include: var-function + - include: sass-variables + - include: sass-functions + - include: sass-custom-functions + - include: sass-interpolation + - include: sass-maps + - include: unquoted-string + - include: sass-operators + - match: '(@)(for|while)\b' + scope: keyword.control.flow.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '(?=$)' + pop: true + - include: sass-script-expression + - match: '(@)(if|else if|else)\b' + scope: keyword.control.flow.conditional.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '(?=$)' + pop: true + - include: sass-script-expression + - match: '(@)(debug|warn|error)\b' + scope: keyword.control.at-rule.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '(?=$)' + pop: true + - include: sass-script-expression + - match: '(@)(at-root)\b' + scope: keyword.control.at-rule.at-root.sass + captures: + 1: punctuation.definition.keyword.sass + - match: '(@)(extend)\b' + scope: keyword.control.at-rule.extend.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.extend.sass + - match: '(?=$)' + pop: true + - match: \!\s*(default|global|optional) + scope: keyword.other.sass + - include: selectors + - include: custom-element-selectors + + - match: '((@)(mixin|function))\s+([\w-]+)' + captures: + 1: keyword.control.at-rule.sass + 2: punctuation.definition.keyword.sass + 4: entity.name.function.sass + push: + - meta_scope: meta.function.declaration.sass + - match: '\s*(?=$)' + pop: true + - match: '\(' + scope: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.function.parameters.sass + - match: '\)' + scope: punctuation.definition.group.end.sass + pop: true + - include: comma-delimiter + - match: '(\$)([a-zA-Z0-9_-][\w-]*)' + scope: variable.parameter.sass + captures: + 1: punctuation.definition.variable.sass + push: + - match: '(?=[,\)])' + pop: true + - match: ':' + scope: punctuation.separator.key-value.css + - match: '\b(false|true|null)\b' + scope: constant.language.sass + - include: property-values + - match: '((@)(include))\s+([\w-]+)' + captures: + 0: variable.function.sass + 1: keyword.control.at-rule.sass + 2: punctuation.definition.keyword.sass + push: + - meta_scope: meta.function-call.sass + - match: '\s*(?=$)' + pop: true + - match: '\(' + scope: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.function-call.arguments.sass + - include: comment-block + - include: comment-line + - include: sass-variables + - include: sass-functions + - include: sass-operators + - include: comma-delimiter + - include: property-values + - include: literal-string + - match: '{{ident}}' + scope: string.unquoted.sass + - include: selectors + - include: custom-element-selectors + - match: '\)' + scope: punctuation.definition.group.end.sass + pop: true + - match: '(@)(return)\b' + scope: keyword.control.at-rule.return.sass + captures: + 1: punctuation.definition.keyword.sass + push: + - meta_scope: meta.at-rule.sass + - match: '\s*(?=$)' + pop: true + - include: property-values + - match: '((@)(?:-(?:webkit|moz|o)-)?(charset|namespace|font-face)\b)' + captures: + 1: keyword.control.at-rule.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.css + - match: '\s*(?=$)' + pop: true + - match: '(url)(\()' + captures: + 1: meta.function-call.css support.function.url.css + 2: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: literal-string + - include: unquoted-string + - include: comment-block + - include: comment-line + - include: literal-string + - match: '\s*((@)counter-style\b)\s+(?:(?i:\b(decimal|none)\b)|({{ident}}))?\s*(?=\{|$)' + captures: + 1: keyword.control.at-rule.counter-style.css + 2: punctuation.definition.keyword.css + 3: invalid.illegal.counter-style-name.css + 4: entity.other.counter-style-name.css + push: + - meta_scope: meta.at-rule.counter-style.css + - include: comment-block + - include: comment-line + - match: '(?=$)' + pop: true + - match: '(?=\s*@custom-media\b)' + push: + - match: '(?=$)' + pop: true + - match: '\s*((@)custom-media)' + captures: + 1: keyword.control.at-rule.custom-media.css + 2: punctuation.definition.keyword.css + 3: support.constant.custom-media.css + push: + - meta_scope: meta.at-rule.custom-media.css + - match: '\s*(?=$)' + pop: true + - include: media-query + - match: '((@)document)' + captures: + 1: keyword.control.at-rule.document.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.document.css + - match: '(?=$)' + pop: true + - include: comment-block + - include: comment-line + - include: url-function + - include: url-prefix-function + - include: domain-function + - include: regexp-function + - include: comma-delimiter + - match: '\s*((@)import\b)\s*' + captures: + 1: keyword.control.at-rule.import.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.import.css + - match: '(?=$)' + pop: true + - match: '(\()(reference|inline|less|css|once|multiple|optional)(\))' + captures: + 0: meta.at-rule.arguments.sass + 1: punctuation.definition.group.begin.sass + 2: constant.other.sass + 3: punctuation.definition.group.end.sass + - include: comment-block + - include: comment-line + - include: literal-string + - include: url-function + - include: media-query + - match: '\s*((@)(-webkit-|-moz-|-o-)?keyframes)' + captures: + 1: keyword.control.at-rule.keyframe.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.keyframe.css + - match: '\s*(?=$)' + pop: true + - include: comment-block + - include: comment-line + - include: sass-interpolation + - match: '\s*({{ident}})?' + captures: + 1: entity.other.animation-name.css + - match: '\s*(?:(,)|(?=[{]))' + captures: + 1: punctuation.definition.arbitrary-repetition.css + - match: '\s*((@)media)\b' + captures: + 1: keyword.control.at-rule.media.css + 2: punctuation.definition.keyword.css + 3: support.constant.media.css + push: + - meta_scope: meta.at-rule.media.css + - include: media-query + - match: '(?=$)' + pop: true + - match: '\s*((@)namespace)\s+({{ident}}(?!{{nmchar}}|\())?' + captures: + 1: keyword.control.at-rule.namespace.css + 2: punctuation.definition.keyword.css + 3: entity.other.namespace-prefix.css + push: + - meta_scope: meta.at-rule.namespace.css + - match: '(?=$)' + pop: true + - include: literal-string + - include: url-function + - include: comment-block + - include: comment-line + - match: '\s*((@)page)\s*(?:(:)(first|left|right))?\s*' + captures: + 1: keyword.control.at-rule.page.css + 2: punctuation.definition.keyword.css + 3: punctuation.definition.entity.css + 4: entity.other.pseudo-class.css + push: + - meta_scope: meta.at-rule.page.css + - include: comment-block + - include: comment-line + - match: '\s*(?=$)' + pop: true + - match: '((@)supports)' + captures: + 1: keyword.control.at-rule.supports.css + 2: punctuation.definition.keyword.css + push: + - meta_scope: meta.at-rule.supports.css + - match: '(?=$)' + pop: true + - include: at-supports-operators + - include: at-supports-parens + - match: '((@)content)' + captures: + 1: keyword.control.at-rule.content.sass + 2: punctuation.definition.keyword.sass + push: + - match: '(?=$)' + pop: true + + at-supports-operators: + - match: '\b(?i:and|or|not)\b' + scope: keyword.operator.logic.css + + at-supports-parens: + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: at-supports-operators + - include: at-supports-parens + - include: comment-block + - include: comment-line + - include: properties + + keyframe-operators: + - include: numeric-values + - match: '\b(from|to)\b' + scope: keyword.keyframe-selector.css + + media-query: + - include: comment-block + - include: comment-line + - match: '\b(?i:all|aural|braille|embossed|handheld|print|projection|screen|speech|tty|tv)\b' + scope: support.constant.media.css + - match: '\b(?i:and|or|not|only)\b' + scope: keyword.operator.logic.media.css + - match: ',' + scope: punctuation.definition.arbitrary-repetition.css + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: comment-block + - include: comment-line + - match: |- + (?x) + ( + (-webkit-|-o-)? + ((min|max)-)? + (-moz-)? + ( + ((device-)?(height|width|aspect-ratio|pixel-ratio))| + (color(-index)?)|monochrome|resolution + ) + )|grid|scan|orientation + \s*(?=[:)]) + captures: + 0: support.type.property-name.media.css + 2: support.type.vendor-prefix.css + 5: support.type.vendor-prefix.css + push: + - match: '(:)|(?=\))' + captures: + 1: punctuation.separator.key-value.css + pop: true + - match: '\b(portrait|landscape|progressive|interlace)' + scope: support.constant.property-value.css + - match: '\s*(\d+)(/)(\d+)' + captures: + 1: constant.numeric.css + 2: keyword.operator.arithmetic.css + 3: constant.numeric.css + - include: sass-value-expression + - include: numeric-values + + + sass-custom-functions: + - match: '\b([a-z_-]+)(?=\()' + scope: support.function.custom.sass + push: + - meta_scope: meta.function-call.css + - include: function-arguments + + sass-script-expression: + - include: comment-line + - include: comment-block + - include: comma-delimiter + - include: sass-maps + - include: color-values + - include: numeric-values + - include: sass-variables + - include: sass-functions + - include: sass-custom-functions + - include: sass-operators + - include: sass-interpolation + - match: '\b(false|true|null)\b' + scope: constant.language.sass + - include: literal-string + - include: unquoted-string + + sass-value-expression: + - include: comment-line + - include: comment-block + - include: comma-delimiter + - include: var-function + - include: sass-variables + - include: sass-functions + - include: sass-custom-functions + - include: sass-interpolation + - include: sass-operators + + sass-maps: + - match: '\(' + captures: + 0: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.group.css meta.map.arguments.css + - match: '\)' + captures: + 0: punctuation.definition.group.end.sass + pop: true + - match: '(\$)([a-zA-Z0-9_-][\w-]*)\s*(:)' + captures: + 0: variable.other.sass + 1: punctuation.definition.variable.sass + 3: punctuation.separator.key-value.css + - match: '({{ident}})\s*(:)' + captures: + 1: variable.parameter.sass + 2: punctuation.separator.key-value.css + - include: property-values + + sass-variables: + - match: '(\$)([a-zA-Z0-9_-][\w-]*)' + scope: variable.other.sass + captures: + 1: punctuation.definition.variable.sass + - include: sass-interpolation + + sass-functions: + - match: '\b(zip|variable-exists|unquote|unitless|unit|unique-id|type-of|transparentize|to-upper-case|to-lower-case|tan|str-slice|str-length|str-insert|str-index|sqrt|spin|softlight|sin|simple-selectors|set-nth|selector-unify|selector-replace|selector-parse|selector-nest|selector-extend|selector-append|screen|scale-color|saturation|saturate|round|rgba|rgb|replace|red|random|quote|pow|pi|percentage|overlay|opacify|nth|negation|multiply|mod|mixin-exists|mix|min|max|map-values|map-remove|map-merge|map-keys|map-has-key|map-get|luma|list-separator|lightness|lighten|length|keywords|join|isnumber|is-superselector|is-bracketed|invert|inspect|index|if|ie-hex-str|hue|hsvvalue|hsvsaturation|hsvhue|hsva|hsv|hsla|hsl|hardlight|greyscale|green|grayscale|global-variable-exists|get-function|function-exists|format|floor|feature-exists|fadeout|fadein|fade|extract|exclusion|escape|e|difference|desaturate|data-uri|darken|cos|convert|contrast|content-exists|complement|comparable|color|change-color|ceil|call|calc|blue|average|atan|asin|argb|append|alpha|adjust-hue|adjust-color|acos|abs)(?=\()' + captures: + 1: support.function.sass + push: + - meta_scope: meta.function-call.sass + - include: function-arguments + + sass-interpolation: + - match: '(#)({)' + captures: + 1: punctuation.definition.variable.sass + 2: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.group.interpolation.sass + - match: '(})' + scope: punctuation.definition.group.end.sass + pop: true + - include: sass-script-expression + + sass-operators: + - match: /|$|%|\*|\-\-|\-|\+\+|\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|%=|\+=|\-=|&=|\bnot\b|\bor\b|\band\b|\bwhen\b + scope: keyword.operator.sass + - match: (?:\s*)\b(not|or|and|when|from|to|through|in)(?=\s) + captures: + 1: keyword.operator.sass + + sass-mixin-def: + - match: '\(' + scope: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.function.parameters.sass + - match: '\)' + scope: punctuation.definition.group.end.sass + pop: true + - include: comma-delimiter + - match: '(\$)([a-zA-Z0-9_-][\w-]*)' + scope: variable.parameter.sass + captures: + 1: punctuation.definition.variable.sass + push: + - match: '(?=[,\)])' + pop: true + - match: ':' + scope: punctuation.separator.key-value.css + - include: property-values + + sass-mixin-call: + - match: '\(' + scope: punctuation.definition.group.begin.sass + push: + - meta_scope: meta.function-call.arguments.sass + - include: sass-value-expression + - include: comma-delimiter + - include: property-values + - include: literal-string + - match: '{{ident}}' + scope: string.unquoted.sass + - include: selectors + - match: '\)' + scope: punctuation.definition.group.end.sass + pop: true + + sass-mixin-directives: + - match: '\s*((\=)([\w-]+))' + captures: + 1: entity.name.function.sass + 2: punctuation.definition.keyword.sass + push: + - meta_scope: meta.function.declaration.sass + - match: '(?=$)' + pop: true + - include: sass-mixin-def + - match: '\s*((\+)([\w-]+))' + captures: + 1: variable.function.sass + 2: punctuation.definition.keyword.sass + push: + - meta_scope: meta.function-call.sass + - match: '(?=$)' + pop: true + - include: sass-mixin-call + + + + property-value-constants: + - match: |- + (?x)\b( + absolute|active|add + | all(-(petite|small)-caps|-scroll)? + | alpha(betic)? + | alternate(-reverse)? + | always|annotation|antialiased|at + | auto(hiding-scrollbar|-flow)? + | avoid(-column|-page|-region)? + | background(-color|-image|-position|-size)? + | backwards|balance|baseline|below|bevel|bicubic|bidi-override|blink + | block(-line-height)? + | blur + | bold(er)? + | border(-bottom|-left|-right|-top)?-(color|radius|width|style) + | border-(bottom|top)-(left|right)-radius + | border-image(-outset|-repeat|-slice|-source|-width)? + | border(-bottom|-left|-right|-top|-collapse|-spacing|-box)? + | both|bottom + | box(-shadow)? + | break-(all|word) + | brightness + | butt(on)? + | capitalize + | cent(er|ral) + | char(acter-variant)? + | cjk-ideographic|clip|clone|close-quote + | closest-(corner|side) + | col-resize|collapse + | color(-stop|-burn|-dodge)? + | column((-count|-gap|-reverse|-rule(-color|-width)?|-width)|s)? + | common-ligatures|condensed|consider-shifts|contain + | content(-box|s)? + | contextual|contrast|cover + | crisp(-e|E)dges + | crop + | cross(hair)? + | da(rken|shed) + | default|dense|diagonal-fractions|difference|disabled + | discretionary-ligatures|disregard-shifts + | distribute(-all-lines|-letter|-space)? + | dotted|double|drop-shadow + | (nwse|nesw|ns|ew|sw|se|nw|ne|w|s|e|n)-resize + | ease(-in-out|-in|-out)? + | element|ellipsis|embed|end|EndColorStr|evenodd + | exclu(de(-ruby)?|sion) + | expanded + | (extra|semi|ultra)-(condensed|expanded) + | farthest-(corner|side)? + | fill(-box|-opacity)? + | filter|fixed|flat + | flex((-basis|-end|-grow|-shrink|-start)|box)? + | flip|flood-color + | font(-size(-adjust)?|-stretch|-weight)? + | forwards + | from(-image)? + | full-width|geometricPrecision|glyphs|gradient|grayscale + | grid(-height)? + | groove|hand|hanging|hard-light|height|help|hidden|hide + | historical-(forms|ligatures) + | horizontal(-tb)? + | hue + | ideograph(-alpha|-numeric|-parenthesis|-space|ic) + | inactive|include-ruby|infinite|inherit|initial + | inline(-block|-box|-flex(box)?|-line-height|-table)? + | inset|inside + | inter(-ideograph|-word|sect) + | invert|isolat(e|ion)|italic + | jis(04|78|83|90) + | justify(-all)? + | keep-all + | large[r]? + | last|left|letter-spacing + | light(e[nr]|ing-color) + | line(-edge|-height|-through)? + | linear(-gradient|RGB)? + | lining-nums|list-item|local|loose|lowercase|lr-tb|ltr + | lumin(osity|ance)|manual + | margin(-bottom|-box|-left|-right|-top)? + | marker(-offset|s)? + | mathematical + | max-(content|height|lines|size|width) + | medium|middle + | min-(content|height|width) + | miter|mixed|move|multiply|newspaper + | no-(change|clip|(close|open)-quote|(common|discretionary|historical)-ligatures|contextual|drop|repeat) + | none|nonzero|normal|not-allowed|nowrap|oblique + | offset(-after|-before|-end|-start)? + | oldstyle-nums|opacity|open-quote + | optimize(Legibility|Precision|Quality|Speed) + | order|ordinal|ornaments + | outline(-color|-offset|-width)? + | outset|outside|over(line|-edge|lay) + | padding(-bottom|-box|-left|-right|-top)? + | page|painted|paused + | perspective-origin + | petite-caps|pixelated|pointer + | pre(-line|-wrap)? + | preserve-3d + | progid:DXImageTransform.Microsoft.(Alpha|Blur|dropshadow|gradient|Shadow) + | progress + | proportional-(nums|width) + | radial-gradient|recto|region|relative + | repeat(-[xy])? + | repeating-(linear|radial)-gradient + | replaced|reset-size|reverse|ridge|right + | round + | row(-resize|-reverse)? + | run-in + | ruby(-base|-text)?(-container)? + | rtl|running|saturat(e|ion)|screen + | scroll(-position|bar)? + | separate|sepia + | scale-down + | shape-(image-threshold|margin|outside) + | show + | sideways(-lr|-rl)? + | simplified + | slashed-zero|slice + | small(-caps|er)? + | smooth|snap|solid|soft-light + | space(-around|-between)? + | span|sRGB + | stack(ed-fractions)? + | start(ColorStr)? + | static + | step-(end|start) + | sticky + | stop-(color|opacity) + | stretch|strict + | stroke(-box|-dash(array|offset)|-miterlimit|-opacity|-width)? + | style(set)? + | stylistic + | sub(grid|pixel-antialiased|tract)? + | super|swash + | table(-caption|-cell|(-column|-footer|-header|-row)-group|-column|-row)? + | tabular-nums|tb-rl + | text((-bottom|-(decoration|emphasis)-color|-indent|-(over|under|after|before)-edge|-shadow|-size(-adjust)?|-top)|field)? + | thi(ck|n) + | titling-ca(ps|se) + | to[p]? + | touch|traditional + | transform(-origin)? + | under(-edge|line)? + | unicase|unset|uppercase|upright + | use-(glyph-orientation|script) + | verso + | vertical(-align|-ideographic|-lr|-rl|-text)? + | view-box + | viewport-fill(-opacity)? + | visibility + | visible(Fill|Painted|Stroke)? + | wait|wavy|weight|whitespace|width|word-spacing + | wrap(-reverse)? + | x{1,2}-(large|small) + | z-index|zero + | zoom(-in|-out)? + | ({{counter_styles}}) + )\b(?=[\s;{),/]) + scope: support.constant.property-value.css + - match: \b(?i:sans-serif|serif|monospace|fantasy|cursive|system-ui)\b(?=\s*[;,\n}{]) + scope: support.constant.font-name.css + + + function-arguments: + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css meta.function-call.arguments.css + - match: '(?=\))' + pop: true + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '\)' + scope: punctuation.definition.group.end.css + pop: true + - include: sass-script-expression + - include: comment-block + - include: comment-line + - include: comma-delimiter + - match: ':' + scope: punctuation.separator.css + - include: var-function + - include: minmax-function + - include: color-adjuster-operators + - include: color-adjuster-functions # must be included before `color-values` + - include: color-functions + - include: color-hex-values + - include: numeric-values + - include: integer-type + - include: image-type + - include: literal-string + - include: sass-variables + - include: sass-functions + - include: sass-custom-functions + - include: sass-interpolation + - include: sass-operators + - match: '\b[^\s''"\(\)]+\b' + scope: string.unquoted.css + + builtin-functions: + - include: attr-function + - include: calc-function + - include: cross-fade-function + - include: filter-functions + - include: gradient-functions + - include: image-function + - include: image-set-function + - include: minmax-function + - include: url-function + - include: var-function + - include: color-adjuster-functions + + # filter() + # https://drafts.fxtf.org/filters/#funcdef-filter + - match: '\b(filter)(?=\()' + scope: support.function.filter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: image-type + - include: literal-string + - include: filter-functions + - include: sass-value-expression + + # counter() + # https://drafts.csswg.org/css-lists-3/#funcdef-counter + - match: '\b(counter)(?=\()' + scope: support.function.counter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: '({{ident}})' + scope: entity.other.counter-name.css string.unquoted.css + - match: '(?=,)' + push: + - match: '(?=\))' + pop: true + - include: comma-delimiter + - match: '\b({{counter_styles}}|none)\b' + scope: support.constant.property-value.counter-style.css + - include: sass-value-expression + + # counters() + # https://drafts.csswg.org/css-lists-3/#funcdef-counters + - match: '\b(counters)(?=\()' + scope: support.function.counter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: '({{ident}})' + scope: entity.other.counter-name.css string.unquoted.css + - match: '(?=,)' + push: + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: literal-string + - match: '\b({{counter_styles}}|none)\b' + scope: support.constant.property-value.counter-style.css + - include: sass-value-expression + + # symbols() + # https://drafts.csswg.org/css-counter-styles-3/#symbols-function + - match: '\b(symbols)(?=\()' + scope: support.function.counter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: '\b(cyclic|numeric|alphabetic|symbolic|fixed)\b' + scope: support.constant.symbol-type.css + - include: comma-delimiter + - include: literal-string + - include: image-type + - include: sass-value-expression + + # format() + # https://drafts.csswg.org/css-fonts-3/#descdef-src + # format() is also mentioned in `issue 2` at https://drafts.csswg.org/css-images-3/#issues-index + # but does not seem to be implemented in any manner + - match: '\b(format)(?=\()' + scope: support.function.font-face.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: literal-string + - include: sass-value-expression + + # local() + # https://drafts.csswg.org/css-fonts-3/#descdef-src + - match: '\b(local)(?=\()' + scope: support.function.font-face.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: sass-value-expression + - include: unquoted-string + + # Transform Functions + # https://www.w3.org/TR/css-transforms-1/#transform-functions + + # transform functions with comma separated types + # matrix(), scale(), matrix3d(), scale3d() + - match: '\b(matrix3d|scale3d|matrix|scale)(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: number-type + - include: var-function + - include: sass-value-expression + + # transform functions with comma separated or types + # translate(), translate3d() + - match: '\b(translate(3d)?)(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: percentage-type + - include: length-type + - include: number-type + - include: var-function + - include: sass-value-expression + + # transform functions with a single or type + # translateX(), translateY() + - match: '\b(translate[XY])(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: percentage-type + - include: length-type + - include: number-type + - include: sass-value-expression + + # transform functions with a single type + # rotate(), skewX(), skewY(), rotateX(), rotateY(), rotateZ() + - match: '\b(rotate[XYZ]?|skew[XY])(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: angle-type + - include: sass-value-expression + + # transform functions with comma separated types + # skew() + - match: '\b(skew)(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: angle-type + - include: sass-value-expression + + # transform functions with a single type + # translateZ(), perspective() + - match: '\b(translateZ|perspective)(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: length-type + - include: sass-value-expression + + # transform functions with a comma separated or types + # rotate3d() + - match: '\b(rotate3d)(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: angle-type + - include: number-type + - include: sass-value-expression + + # transform functions with a single type + # scaleX(), scaleY(), scaleZ() + - match: '\b(scale[XYZ])(?=\()' + scope: support.function.transform.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: number-type + - include: sass-value-expression + + # Timing Functions + # https://www.w3.org/TR/web-animations-1/#timing-functions + + # cubic-bezier() + # https://www.w3.org/TR/web-animations-1/#cubic-bzier-timing-function + - match: '\b(cubic-bezier)(?=\()' + scope: support.function.timing.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: number-type + - include: sass-value-expression + + # steps() + # https://www.w3.org/TR/web-animations-1/#step-timing-function + - match: '\b(steps)(?=\()' + scope: support.function.timing.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: integer-type + - match: (end|middle|start) + scope: support.keyword.timing-direction.css + - include: sass-value-expression + + # Shape Functions + # https://www.w3.org/TR/css-shapes-1/#typedef-basic-shape + + # rect() - Deprecated + # https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect + - match: '\b(rect)(?=\()' + scope: support.function.shape.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: \bauto\b + scope: support.constant.property-value.css + - include: length-type + - include: sass-value-expression + + # inset() + # https://www.w3.org/TR/css-shapes-1/#funcdef-inset + - match: '\b(inset)(?=\()' + scope: support.function.shape.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: '\bround\b' + scope: keyword.other.css + - include: length-type + - include: percentage-type + - include: sass-value-expression + + # circle() + # https://www.w3.org/TR/css-shapes-1/#funcdef-circle + # ellipse() + # https://www.w3.org/TR/css-shapes-1/#funcdef-ellipse + - match: '\b(circle|ellipse)(?=\()' + scope: support.function.shape.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: '\bat\b' + scope: keyword.other.css + - match: '\b(top|right|bottom|left|center|closest-side|farthest-side)\b' + scope: support.constant.property-value.css + - include: length-type + - include: percentage-type + - include: sass-value-expression + + # polygon() + # https://www.w3.org/TR/css-shapes-1/#funcdef-polygon + - match: '\b(polygon)(?=\()' + scope: support.function.shape.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - include: comment-block + - match: '(?=\))' + pop: true + - match: '\b(nonzero|evenodd)\b' + scope: support.constant.property-value.css + - include: length-type + - include: percentage-type + - include: calc-function + - match: ',' + scope: punctuation.separator.sequence.css + - include: sass-value-expression + + # toggle() + # https://www.w3.org/TR/css3-values/#toggle-notation + - match: '\b(toggle)(?=\()' + scope: support.function.toggle.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: vendor-prefix + - include: property-value-constants + - include: numeric-values + - include: color-values + - include: literal-string + - include: sass-value-expression + + # repeat() + # https://drafts.csswg.org/css-grid/#funcdef-repeat + - match: '\b(repeat)(?=\()' + scope: support.function.grid.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: length-type + - include: percentage-type + - include: minmax-function + - include: integer-type + - include: var-function + - include: line-names + - match: \b(auto-fill|auto-fit)\b + scope: support.keyword.repetitions.css + - match: \b(max-content|min-content|auto)\b + scope: support.constant.property-value.css + - include: sass-value-expression + + # var() + # https://drafts.csswg.org/css-variables/#funcdef-var + var-function: + - match: '\b(var)(?=\()' + scope: support.function.var.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: custom-property-name + - include: sass-value-expression + + # Filter Functions + # https://drafts.fxtf.org/filters/#typedef-filter-function + filter-functions: + # blur() + # https://drafts.fxtf.org/filters/#funcdef-filter-blur + - match: '\b(blur)(?=\()' + scope: support.function.filter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: length-type + - include: sass-value-expression + + # brightness(), contrast(), grayscale(), invert(), opacity(), saturate(), sepia() + # https://drafts.fxtf.org/filters/#funcdef-filter-brightness + - match: '\b(brightness|contrast|grayscale|invert|opacity|saturate|sepia)(?=\()' + scope: support.function.filter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: percentage-type + - include: number-type + - include: sass-value-expression + + # drop-shadow() + # https://drafts.fxtf.org/filters/#funcdef-filter-drop-shadow + - match: '\b(drop-shadow)(?=\()' + scope: support.function.filter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: length-type + - include: color-values + - include: sass-value-expression + + # hue-rotate() + # https://drafts.fxtf.org/filters/#funcdef-filter-hue-rotate + - match: '\b(hue-rotate)(?=\()' + scope: support.function.filter.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: angle-type + - include: sass-value-expression + + # calc() + # https://www.w3.org/TR/css3-values/#funcdef-calc + calc-function: + - match: '\b(calc)(?=\()' + scope: support.function.calc.css + push: + - meta_scope: meta.function-call.css + - match: '\(' + scope: punctuation.definition.group.begin.css + push: inside-calc-parens + - match: '' + pop: true + + inside-calc-parens: + - meta_scope: meta.group.css + - match: '(?=\))' + set: function-notation-terminator + - include: comment-block + - include: calc-function + - include: var-function + - include: numeric-values + - include: attr-function + - match: "[-/*+]" + scope: keyword.operator.css + - include: sass-value-expression + - match: '\(' + scope: punctuation.definition.group.begin.css + push: inside-calc-parens + + # attr() + # https://www.w3.org/TR/css3-values/#funcdef-attr + attr-function: + - match: '\b(attr)(?=\()' + scope: support.function.attr.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: qualified-name + - include: literal-string + - include: sass-value-expression + - match: '({{ident}})' + scope: entity.other.attribute-name.css + push: + - match: |- + (?x)\b( + {{font_relative_lengths}} + | {{viewport_percentage_lengths}} + | {{absolute_lengths}} + | {{angle_units}} + | {{duration_units}} + | {{frequency_units}} + | {{resolution_units}} + )\b + scope: keyword.other.unit.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: property-value-constants + - include: numeric-values + - include: color-values + - include: sass-value-expression + + # url() + # https://drafts.csswg.org/css-images-3/#url-notation + url-function: + - match: '\b(url)(?=\()' + scope: support.function.url.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: literal-string + - match: '(https?|ftp)://' + scope: string.unquoted.css + - include: sass-value-expression + - include: unquoted-string + + # url-prefix() + # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-prefix + url-prefix-function: + - match: '\b(url-prefix)(?=\()' + scope: support.function.url-prefix.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: literal-string + - match: '(https?|ftp)://' + scope: string.unquoted.css + - include: sass-value-expression + - include: unquoted-string + + # domain() + # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-domain + domain-function: + - match: '\b(domain)(?=\()' + scope: support.function.domain.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: literal-string + - match: '(https?|ftp)://' + scope: string.unquoted.css + - include: sass-value-expression + - include: unquoted-string + + # regexp() + # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-regexp + regexp-function: + - match: '\b(regexp)(?=\()' + scope: support.function.regexp.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: literal-string + - include: sass-value-expression + + # image() + # https://drafts.csswg.org/css-images-3/#funcdef-image + image-function: + - match: '\b(image)(?=\()' + scope: support.function.image.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: image-type + - include: literal-string + - include: color-values + - include: comma-delimiter + - include: sass-value-expression + - include: unquoted-string + + # image-set() + # https://drafts.csswg.org/css-images-3/#funcdef-image-set + image-set-function: + - match: '\b(image-set)(?=\()' + scope: support.function.image.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: literal-string + - include: color-values + - include: comma-delimiter + - include: resolution-type + - include: image-type + - match: '[0-9]+(x)' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + - include: sass-value-expression + - include: unquoted-string + + # Gradient Functions + # https://drafts.csswg.org/css-images-3/#gradients + gradient-functions: + # linear-gradient() + # https://drafts.csswg.org/css-images-3/#linear-gradients + # repeating-linear-gradient() + # https://drafts.csswg.org/css-images-3/#funcdef-repeating-linear-gradient + - match: '\b((?:repeating-)?linear-gradient)(?=\()' + scope: support.function.gradient.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: angle-type + - include: comma-delimiter + - include: color-values + - include: percentage-type + - include: length-type + - match: '\bto\b' + scope: keyword.other.css + - match: \b(top|right|bottom|left)\b + scope: support.constant.property-value.css + - include: sass-value-expression + + # radial-gradient() + # https://drafts.csswg.org/css-images-3/#radial-gradients + # repeating-radial-gradient() + # https://drafts.csswg.org/css-images-3/#funcdef-repeating-radial-gradient + - match: '\b((?:repeating-)?radial-gradient)(?=\()' + scope: support.function.gradient.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: color-values + - include: percentage-type + - include: length-type + - match: '\b(at|circle|ellipse)\b' + scope: keyword.other.css + - match: |- + (?x)\b( + left + | center + | right + | top + | bottom + | closest-corner + | closest-side + | farthest-corner + | farthest-side + )\b + scope: support.constant.property-value.css + - include: sass-value-expression + + # cross-fade() + # https://drafts.csswg.org/css-images-3/#cross-fade-function + cross-fade-function: + - match: '\b(cross-fade)(?=\()' + scope: support.function.image.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: percentage-type + - include: color-values + - include: image-type + - include: literal-string + - include: sass-value-expression + - include: unquoted-string + + # minmax() + # https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax + minmax-function: + - match: '\b(minmax)(?=\()' + scope: support.function.grid.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: percentage-type + - include: length-type + - match: \b(auto|max-content|min-content)\b + scope: support.constant.property-value.css + - include: sass-value-expression + + # Color Functions + # https://drafts.csswg.org/css-color + color-functions: + # rgb(), rgba() + # https://drafts.csswg.org/css-color/#rgb-functions + - match: '\b(rgba?)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: percentage-type + - include: number-type + # scss add overloads: + # https://sass-lang.com/documentation/Sass/Script/Functions.html#rgba-instance_method + - include: color-values + - include: sass-value-expression + + # hsl(), hsla() + # https://drafts.csswg.org/css-color/#the-hsl-notation + # hwb() - Not yet implemented by browsers + # https://drafts.csswg.org/css-color/#funcdef-hwb + - match: '\b(hsla?|hwb)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: angle-type + - include: percentage-type + - include: number-type + - include: sass-value-expression + + # gray() - Not yet implemented by browsers + # https://drafts.csswg.org/css-color/#funcdef-gray + - match: '\b(gray)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: percentage-type + - include: number-type + - include: sass-value-expression + + # device-cmyk() - Not yet implemented by browsers + # https://drafts.csswg.org/css-color/#funcdef-device-cmyk + - match: '\b(device-cmyk)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: color-adjuster-functions # must be included before `color-values` + - include: color-values + - include: percentage-type + - include: number-type + - include: sass-value-expression + + # color-mod() - Not yet implemented by browsers + # https://drafts.csswg.org/css-color/#funcdef-color-mod + - match: '\b(color)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: comma-delimiter + - include: color-adjuster-functions # must be included before `color-values` + - include: var-function + - include: color-values + - include: angle-type + - include: number-type + - include: sass-value-expression + + # Color Adjuster Functions - Not yet implemented by browsers + # https://www.w3.org/TR/css-color-4/#typedef-color-adjuster + color-adjuster-functions: + # red(), green(), blue(), alpha() - Not yet implemented by browsers + - match: '\b(red|green|blue|alpha|a)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: color-adjuster-operators + - include: percentage-type + - include: number-type + - include: sass-value-expression + + # hue() - Not yet implemented by browsers + - match: '\b(hue|h)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: color-adjuster-operators + - include: angle-type + - include: sass-value-expression + + # saturation(), lightness(), whiteness(), blackness() - Not yet implemented by browsers + - match: '\b(saturation|lightness|whiteness|blackness|[slwb])(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: color-adjuster-operators + - include: percentage-type + - include: sass-value-expression + + # tint(), shade(), contrast() - Not yet implemented by browsers + # contrast() interferes with the contrast() filter function; + # therefore, it is not yet implemented here + - match: '\b(tint|shade)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - include: percentage-type + - include: sass-value-expression + + # blend(), blenda() - Not yet implemented by browsers + - match: '\b(blenda|blend)(?=\()' + scope: support.function.color.css + push: + - meta_scope: meta.function-call.css + - include: function-notation-terminator + - match: '\(' + scope: punctuation.definition.group.begin.css + push: + - meta_scope: meta.group.css + - match: '(?=\))' + pop: true + - match: '\b(rgb|hsl|hwb)\b' + scope: keyword.other.color-space.css + - include: color-values + - include: percentage-type + - include: var-function + - include: sass-value-expression + + + + color-adjuster-operators: + - match: '[\-\+*](?=\s+)' + scope: keyword.operator.css + + color-hex-values: + - match: '(#)(\h{3}|\h{6})\b' + scope: constant.other.color.rgb-value.css + captures: + 1: punctuation.definition.constant.css + - match: '(#)(\h{4}|\h{8})\b' + scope: constant.other.color.rgba-value.css + captures: + 1: punctuation.definition.constant.css + + function-notation-terminator: + - match: '\)' + scope: meta.group.css punctuation.definition.group.end.css + pop: true + + comma-delimiter: + - match: '\s*(,)\s*' + captures: + 1: punctuation.separator.css + + vendor-prefix: + - match: "-(?:webkit|moz|ms|o)-" + scope: support.type.vendor-prefix.css + + unicode-range: + - match: |- + (?xi) + (u\+) + ([0-9a-f?]{1,6} + (?:(-)[0-9a-f]{1,6})?) + scope: support.unicode-range.css + captures: + 1: support.constant.unicode-range.prefix.css + 2: constant.codepoint-range.css + 3: punctuation.section.range.css + + qualified-name: + - match: '(?:({{ident}})|(\*))?([|])(?!=)' + captures: + 1: entity.other.namespace-prefix.css + 2: entity.name.namespace.wildcard.css + 3: punctuation.separator.namespace.css + + # Custom Properties + # https://drafts.csswg.org/css-variables/#typedef-custom-property-name + custom-property-name: + - match: '(--)({{nmchar}}+)' + scope: support.type.custom-property.css + captures: + 1: punctuation.definition.custom-property.css + 2: support.type.custom-property.name.css + + color-values: + - include: color-functions + - include: color-hex-values + - match: \b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b + scope: support.constant.color.w3c-standard-color-name.css + - match: \b(aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rebeccapurple|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen)\b + scope: support.constant.color.w3c-extended-color-keywords.css + - match: \b((?i)currentColor|transparent)\b + scope: support.constant.color.w3c-special-color-keyword.css + + numeric-values: + - include: angle-type + - include: frequency-type + - include: length-type + - include: resolution-type + - include: time-type + - include: percentage-type + - include: number-type + + integer-type: + - match: '{{integer}}' + scope: constant.numeric.css + + number-type: + - match: '{{number}}' + scope: constant.numeric.css + + percentage-type: + - match: '{{number}}(%)' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + + length-type: + - match: '{{number}}({{font_relative_lengths}}|{{viewport_percentage_lengths}}|{{absolute_lengths}})\b' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + - match: '0\b(?!%)' + scope: constant.numeric.css + + time-type: + - match: '{{number}}({{duration_units}})\b' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + + frequency-type: + - match: '{{number}}({{frequency_units}})\b' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + + resolution-type: + - match: '{{number}}({{resolution_units}})\b' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + + angle-type: + - match: '{{number}}({{angle_units}})\b' + scope: constant.numeric.css + captures: + 1: keyword.other.unit.css + - match: '0\b(?!%)' + scope: constant.numeric.css + + image-type: + - include: cross-fade-function + - include: gradient-functions + - include: image-function + - include: image-set-function + - include: url-function + + + # Named Grid Lines + # https://drafts.csswg.org/css-grid/#named-lines + line-names: + - match: '\[' + scope: punctuation.section.begin.css + push: + - match: '{{ident}}' + scope: string.unquoted.line-name.css + - match: '\]' + scope: punctuation.section.end.css + pop: true + + + unquoted-string: + - match: '\b[^\s''"]+\b' + scope: string.unquoted.css + + unquoted-concatenated-string: + # cases: + # unquoted string + + # + unquoted string + # unquoted string + unquoted string + - match: '([a-zA-Z_-]+)\s+(\+)\s+([a-zA-Z_-]+(?=\s|$|;))|(\+)\s+([a-zA-Z_-]+(?=\s|$|;))|([a-zA-Z_-]+)\s+(\+)' + captures: + 1: string.unquoted.css + 2: keyword.operator.sass + 3: string.unquoted.css + 4: keyword.operator.sass + 5: string.unquoted.css + 6: string.unquoted.css + 7: keyword.operator.sass + + literal-string: + - match: "'" + scope: punctuation.definition.string.begin.css + push: + - meta_scope: string.quoted.single.css + - match: (')|(\n) + captures: + 1: punctuation.definition.string.end.css + 2: invalid.illegal.newline.css + pop: true + - include: string-content + - match: '"' + scope: punctuation.definition.string.begin.css + push: + - meta_scope: string.quoted.double.css + - match: (")|(\n) + captures: + 1: punctuation.definition.string.end.css + 2: invalid.illegal.newline.css + pop: true + - include: string-content + + string-content: + - match: \\\s*\n + scope: constant.character.escape.newline.css + - match: '\\(\h{1,6}|.)' + scope: constant.character.escape.css + - include: sass-interpolation + + + + comment-block: + - match: /\* + scope: punctuation.definition.comment.css + push: + - meta_scope: comment.block.css + - match: \*/ + scope: punctuation.definition.comment.css + pop: true + + comment-line: + - match: // + scope: punctuation.definition.comment.css + push: + - meta_scope: comment.line.double-slash.sass + - match: \n + pop: true + diff --git a/docs-src/02-markdown.md b/docs-src/02-markdown.md deleted file mode 100644 index 93527fc..0000000 --- a/docs-src/02-markdown.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title = "Markdown" ---- - -_mkbook_ nominally utilizes [CommonMark](https://commonmark.org/) with some [GFM](https://github.github.com/gfm/) extensions through the use of the [comrak](https://crates.io/crates/comrak) crate. In using _comrak_, a specific set of options are used, which are listed here: - -```rust -let options: ComrakOptions = ComrakOptions { - hardbreaks: false, - smart: true, - github_pre_lang: false, - default_info_string: None, - unsafe_: true, - ext_strikethrough: true, - ext_tagfilter: false, - ext_table: true, - ext_autolink: true, - ext_tasklist: true, - ext_superscript: true, - ext_header_ids: Some("header".to_owned()), - ext_footnotes: true, - ext_description_lists: true, - ..ComrakOptions::default() -}; -``` - -Mostly, know that the following extensions are enabled: - -* [Strikethrough](https://github.github.com/gfm/#strikethrough-extension-) -* [Tables](https://github.github.com/gfm/#tables-extension-) -* [Autolinks](https://github.github.com/gfm/#autolinks-extension-) -* [Task Lists](https://github.github.com/gfm/#task-list-items-extension-) -* Superscripts (`e = mc^2^.` → `e = mc2.`) -* [Footnotes](https://kramdown.gettalong.org/syntax.html#footnotes) -* Description Lists: - ```md - First term - - : Details for the **first term** - - Second term - - : Details for the **second term** - - More details in second paragraph. - ``` - -## Syntax Highlight - -GFM syntax highlighting is also available by using fenced code tags with a label denoting the language, as such: - -~~~md -```c++ -#include - -int main() { - std::cout << "Hello, world!" << std::endl; - return 0; -} -``` -~~~ - -which results in: - -```c++ -#include - -int main() { - std::cout << "Hello, world!" << std::endl; - return 0; -} -``` - -To denote the language you can either use one the language's extensions as the label, or the full name of the language (which is **not** case-sensitive). - -The list of supported languages is currently as follows: - -| Language Name | Supported Tags / Extensions | -|:-|:-| -| ASP | `asa` | -| ActionScript | `as` | -| AppleScript | `applescript`, `script editor` | -| Batch File | `bat`, `cmd` | -| BibTeX | `bib` | -| Bourne Again Shell (bash) | `sh`, `bash`, `zsh`, `fish`, `.bash_aliases`, `.bash_completions`, `.bash_functions`, `.bash_login`, `.bash_logout`, `.bash_profile`, `.bash_variables`, `.bashrc`, `.profile`, `.textmate_init` | -| C | `c`, `h` | -| C# | `cs`, `csx` | -| C++ | `cpp`, `cc`, `cp`, `cxx`, `c++`, `C`, `h`, `hh`, `hpp`, `hxx`, `h++`, `inl`, `ipp` | -| CSS | `css`, `css.erb`, `css.liquid` | -| Cargo Build Results | `` | -| Clojure | `clj` | -| D | `d`, `di` | -| Diff | `diff`, `patch` | -| Erlang | `erl`, `hrl`, `Emakefile`, `emakefile` | -| Go | `go` | -| Graphviz (DOT) | `dot`, `DOT`, `gv` | -| Groovy | `groovy`, `gvy`, `gradle` | -| HTML (ASP) | `asp` | -| HTML (Erlang) | `yaws` | -| HTML (Rails) | `rails`, `rhtml`, `erb`, `html.erb` | -| HTML (Tcl) | `adp` | -| HTML | `html`, `htm`, `shtml`, `xhtml`, `inc`, `tmpl`, `tpl` | -| Haskell | `hs` | -| Haxe | `hx`, `hxsl`, `hscript` | -| Hxml | `hxml` | -| JSON | `json`, `sublime-settings`, `sublime-menu`, `sublime-keymap`, `sublime-mousemap`, `sublime-theme`, `sublime-build`, `sublime-project`, `sublime-completions`, `sublime-commands`, `sublime-macro`, `sublime-color-scheme` | -| Java Properties | `properties` | -| Java Server Page (JSP) | `jsp` | -| Java | `java`, `bsh` | -| JavaDoc | `` | -| JavaScript (Rails) | `js.erb` | -| JavaScript | `js`, `htc` | -| LaTeX Log | `` | -| LaTeX | `tex`, `ltx` | -| Lisp | `lisp`, `cl`, `clisp`, `l`, `mud`, `el`, `scm`, `ss`, `lsp`, `fasl` | -| Literate Haskell | `lhs` | -| Lua | `lua` | -| MATLAB | `matlab` | -| Make Output | `` | -| Makefile | `make`, `GNUmakefile`, `makefile`, `Makefile`, `OCamlMakefile`, `mak`, `mk` | -| Markdown | `md`, `mdown`, `markdown`, `markdn` | -| MultiMarkdown | `` | -| NAnt Build File | `build` | -| OCaml | `ml`, `mli` | -| OCamllex | `mll` | -| OCamlyacc | `mly` | -| Objective-C | `m`, `h` | -| Objective-C++ | `mm`, `M`, `h` | -| PHP Source | `` | -| PHP | `php`, `php3`, `php4`, `php5`, `php7`, `phps`, `phpt`, `phtml` | -| Pascal | `pas`, `p`, `dpr` | -| Perl | `pl`, `pm`, `pod`, `t`, `PL` | -| Plain Text | `txt` | -| Python | `py`, `py3`, `pyw`, `pyi`, `pyx`, `pyx.in`, `pxd`, `pxd.in`, `pxi`, `pxi.in`, `rpy`, `cpy`, `SConstruct`, `Sconstruct`, `sconstruct`, `SConscript`, `gyp`, `gypi`, `Snakefile`, `wscript` | -| R Console | `` | -| R | `R`, `r`, `s`, `S`, `Rprofile` | -| Rd (R Documentation) | `rd` | -| Regular Expression | `re` | -| Regular Expressions (Javascript) | `` | -| Regular Expressions (Python) | `` | -| Ruby Haml | `haml`, `sass` | -| Ruby on Rails | `rxml`, `builder` | -| Ruby | `rb`, `Appfile`, `Appraisals`, `Berksfile`, `Brewfile`, `capfile`, `cgi`, `Cheffile`, `config.ru`, `Deliverfile`, `Fastfile`, `fcgi`, `Gemfile`, `gemspec`, `Guardfile`, `irbrc`, `jbuilder`, `podspec`, `prawn`, `rabl`, `rake`, `Rakefile`, `Rantfile`, `rbx`, `rjs`, `ruby.rail`, `Scanfile`, `simplecov`, `Snapfile`, `thor`, `Thorfile`, `Vagrantfile` | -| Rust | `rs` | -| SQL (Rails) | `erbsql`, `sql.erb` | -| SQL | `sql`, `ddl`, `dml` | -| Scala | `scala`, `sbt` | -| Shell-Unix-Generic | `` | -| TOML | `toml`, `tml`, `Cargo.lock`, `Gopkg.lock`, `Pipfile` | -| Tcl | `tcl` | -| TeX | `sty`, `cls` | -| Textile | `textile` | -| XML | `xml`, `xsd`, `xslt`, `tld`, `dtml`, `rss`, `opml`, `svg` | -| YAML | `yaml`, `yml`, `sublime-syntax` | -| camlp4 | `` | -| commands-builtin-shell-bash | `` | -| reStructuredText | `rst`, `rest` | diff --git a/docs-src/02-markdown/01-commonmark.md b/docs-src/02-markdown/01-commonmark.md new file mode 100644 index 0000000..eeb114f --- /dev/null +++ b/docs-src/02-markdown/01-commonmark.md @@ -0,0 +1,46 @@ +--- +title = "Commonmark" +--- + +_mkbook_ nominally utilizes [CommonMark](https://commonmark.org/) with some [GFM](https://github.github.com/gfm/) extensions through the use of the [comrak](https://crates.io/crates/comrak) crate. In using _comrak_, a specific set of options are used, which are listed here: + +```rust +let options: ComrakOptions = ComrakOptions { + hardbreaks: false, + smart: true, + github_pre_lang: false, + default_info_string: None, + unsafe_: true, + ext_strikethrough: true, + ext_tagfilter: false, + ext_table: true, + ext_autolink: true, + ext_tasklist: true, + ext_superscript: true, + ext_header_ids: Some("header".to_owned()), + ext_footnotes: true, + ext_description_lists: true, + ..ComrakOptions::default() +}; +``` + +Mostly, know that the following extensions are enabled: + +* [Strikethrough](https://github.github.com/gfm/#strikethrough-extension-) +* [Tables](https://github.github.com/gfm/#tables-extension-) +* [Autolinks](https://github.github.com/gfm/#autolinks-extension-) +* [Task Lists](https://github.github.com/gfm/#task-list-items-extension-) +* Superscripts (`e = mc^2^.` → `e = mc2.`) +* [Footnotes](https://kramdown.gettalong.org/syntax.html#footnotes) +* Description Lists: + ```md + First term + + : Details for the **first term** + + Second term + + : Details for the **second term** + + More details in second paragraph. + ``` diff --git a/docs-src/02-markdown/02-syntax-highlighting.md b/docs-src/02-markdown/02-syntax-highlighting.md new file mode 100644 index 0000000..836c0b5 --- /dev/null +++ b/docs-src/02-markdown/02-syntax-highlighting.md @@ -0,0 +1,432 @@ +--- +title = "Syntax Highlighting" +--- + +# Syntax Highlighting + +GFM syntax highlighting is also available by using fenced code tags with a label denoting the language, as such: + +~~~md +```c++ +#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return 0; +} +``` +~~~ + +which results in: + +```c++ +#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return 0; +} +``` + +To denote the language you can either use one the language's extensions as the label, or the full name of the language (which is **not** case-sensitive). + +The list of supported languages is currently as follows: + +ASP + +: `asa` + + +ActionScript + +: `as` + + +AppleScript + +: `applescript`, `script editor` + + +Batch File + +: `bat`, `cmd` + + +BibTeX + +: `bib` + + +Bourne Again Shell (bash) + +: `sh`, `bash`, `zsh`, `fish`, `.bash_aliases`, `.bash_completions`, `.bash_functions`, `.bash_login`, `.bash_logout`, `.bash_profile`, `.bash_variables`, `.bashrc`, `.profile`, `.textmate_init` + + +C + +: `c`, `h` + + +C# + +: `cs`, `csx` + + +C++ + +: `cpp`, `cc`, `cp`, `cxx`, `c++`, `C`, `h`, `hh`, `hpp`, `hxx`, `h++`, `inl`, `ipp` + + +CSS + +: `css`, `css.erb`, `css.liquid` + + +Cargo Build Results + +: `` + + +Clojure + +: `clj` + + +D + +: `d`, `di` + + +Diff + +: `diff`, `patch` + + +Erlang + +: `erl`, `hrl`, `Emakefile`, `emakefile` + + +Go + +: `go` + + +Graphviz (DOT) + +: `dot`, `DOT`, `gv` + + +Groovy + +: `groovy`, `gvy`, `gradle` + + +HTML + +: `html`, `htm`, `shtml`, `xhtml`, `inc`, `tmpl`, `tpl` + + +HTML (ASP) + +: `asp` + + +HTML (Erlang) + +: `yaws` + + +HTML (Rails) + +: `rails`, `rhtml`, `erb`, `html.erb` + + +HTML (Tcl) + +: `adp` + + +Haskell + +: `hs` + + +Haxe + +: `hx`, `hxsl`, `hscript` + + +Hxml + +: `hxml` + + +JSON + +: `json`, `sublime-settings`, `sublime-menu`, `sublime-keymap`, `sublime-mousemap`, `sublime-theme`, `sublime-build`, `sublime-project`, `sublime-completions`, `sublime-commands`, `sublime-macro`, `sublime-color-scheme` + + +Java + +: `java`, `bsh` + + +Java Properties + +: `properties` + + +Java Server Page (JSP) + +: `jsp` + + +JavaDoc + +: `` + + +JavaScript + +: `js`, `htc` + + +JavaScript (Rails) + +: `js.erb` + + +LaTeX + +: `tex`, `ltx` + + +LaTeX Log + +: `` + + +Lisp + +: `lisp`, `cl`, `clisp`, `l`, `mud`, `el`, `scm`, `ss`, `lsp`, `fasl` + + +Literate Haskell + +: `lhs` + + +Lua + +: `lua` + + +MATLAB + +: `matlab` + + +Make Output + +: `` + + +Makefile + +: `make`, `GNUmakefile`, `makefile`, `Makefile`, `OCamlMakefile`, `mak`, `mk` + + +Markdown + +: `md`, `mdown`, `markdown`, `markdn` + + +MultiMarkdown + +: `` + + +NAnt Build File + +: `build` + + +OCaml + +: `ml`, `mli` + + +OCamllex + +: `mll` + + +OCamlyacc + +: `mly` + + +Objective-C + +: `m`, `h` + + +Objective-C++ + +: `mm`, `M`, `h` + + +PHP + +: `php`, `php3`, `php4`, `php5`, `php7`, `phps`, `phpt`, `phtml` + + +PHP Source + +: `` + + +Pascal + +: `pas`, `p`, `dpr` + + +Perl + +: `pl`, `pm`, `pod`, `t`, `PL` + + +Plain Text + +: `txt` + + +Python + +: `py`, `py3`, `pyw`, `pyi`, `pyx`, `pyx.in`, `pxd`, `pxd.in`, `pxi`, `pxi.in`, `rpy`, `cpy`, `SConstruct`, `Sconstruct`, `sconstruct`, `SConscript`, `gyp`, `gypi`, `Snakefile`, `wscript` + + +R + +: `R`, `r`, `s`, `S`, `Rprofile` + + +R Console + +: `` + + +Rd (R Documentation) + +: `rd` + + +Regular Expression + +: `re` + + +Regular Expressions (Javascript) + +: `` + + +Regular Expressions (Python) + +: `` + + +Ruby + +: `rb`, `Appfile`, `Appraisals`, `Berksfile`, `Brewfile`, `capfile`, `cgi`, `Cheffile`, `config.ru`, `Deliverfile`, `Fastfile`, `fcgi`, `Gemfile`, `gemspec`, `Guardfile`, `irbrc`, `jbuilder`, `podspec`, `prawn`, `rabl`, `rake`, `Rakefile`, `Rantfile`, `rbx`, `rjs`, `ruby.rail`, `Scanfile`, `simplecov`, `Snapfile`, `thor`, `Thorfile`, `Vagrantfile` + + +Ruby Haml + +: `haml`, `sass` + + +Ruby on Rails + +: `rxml`, `builder` + + +Rust + +: `rs` + + +SCSS + +: `scss` + + +SQL + +: `sql`, `ddl`, `dml` + + +SQL (Rails) + +: `erbsql`, `sql.erb` + + +Sass + +: `sass` + + +Scala + +: `scala`, `sbt` + + +Shell-Unix-Generic + +: `` + + +TOML + +: `toml`, `tml`, `Cargo.lock`, `Gopkg.lock`, `Pipfile` + + +Tcl + +: `tcl` + + +TeX + +: `sty`, `cls` + + +Textile + +: `textile` + + +XML + +: `xml`, `xsd`, `xslt`, `tld`, `dtml`, `rss`, `opml`, `svg` + + +YAML + +: `yaml`, `yml`, `sublime-syntax` + + +camlp4 + +: `` + + +commands-builtin-shell-bash + +: `` + + +reStructuredText + +: `rst`, `rest` diff --git a/docs-src/02-markdown/index.md b/docs-src/02-markdown/index.md new file mode 100644 index 0000000..48e8abb --- /dev/null +++ b/docs-src/02-markdown/index.md @@ -0,0 +1,5 @@ +--- +title = "Markdown" +--- + +_mkbook_ relies pretty extensively on [Markdown](https://daringfireball.net/projects/markdown/) for its ease of use. diff --git a/docs/01-introduction.html b/docs/01-introduction/index.html similarity index 68% rename from docs/01-introduction.html rename to docs/01-introduction/index.html index a028d4c..284c004 100644 --- a/docs/01-introduction.html +++ b/docs/01-introduction/index.html @@ -4,62 +4,94 @@ The mkbook Book | Introduction - - + + - + - +

mkbook is my simpler alternative to mdbook which is a great tool, but for which I really dislike some of the decisions they took, such as relying on javascript for highlighting and navigation, and including a lot of bells and whistles such as javascript-based search.

@@ -109,11 +141,11 @@
- + Next chapter: “Markdown” - + diff --git a/docs/02-markdown.html b/docs/02-markdown.html deleted file mode 100644 index 2cfd8cd..0000000 --- a/docs/02-markdown.html +++ /dev/null @@ -1,469 +0,0 @@ - - - - - - The mkbook Book | Markdown - - - - - - - - - - - - - -
-

mkbook nominally utilizes CommonMark with some GFM extensions through the use of the comrak crate. In using comrak, a specific set of options are used, which are listed here:

-
-let options: ComrakOptions = ComrakOptions {
-    hardbreaks: false,
-    smart: true,
-    github_pre_lang: false,
-    default_info_string: None,
-    unsafe_: true,
-    ext_strikethrough: true,
-    ext_tagfilter: false,
-    ext_table: true,
-    ext_autolink: true,
-    ext_tasklist: true,
-    ext_superscript: true,
-    ext_header_ids: Some("header".to_owned()),
-    ext_footnotes: true,
-    ext_description_lists: true,
-    ..ComrakOptions::default()
-};
-
-

Mostly, know that the following extensions are enabled:

-
    -
  • Strikethrough
  • -
  • Tables
  • -
  • Autolinks
  • -
  • Task Lists
  • -
  • Superscripts (e = mc^2^.e = mc<sup>2</sup>.)
  • -
  • Footnotes
  • -
  • Description Lists: -
    -First term
    -
    -: Details for the **first term**
    -
    -Second term
    -
    -: Details for the **second term**
    -
    -    More details in second paragraph.
    -
    -
  • -
-

Syntax Highlight

-

GFM syntax highlighting is also available by using fenced code tags with a label denoting the language, as such:

-
-```c++
-#include <stdio>
-
-int main() {
-    std::cout << "Hello, world!" << std::endl;
-    return 0;
-}
-```
-
-

which results in:

-
-#include <stdio>
-
-int main() {
-    std::cout << "Hello, world!" << std::endl;
-    return 0;
-}
-
-

To denote the language you can either use one the language’s extensions as the label, or the full name of the language (which is not case-sensitive).

-

The list of supported languages is currently as follows:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Language NameSupported Tags / Extensions
ASPasa
ActionScriptas
AppleScriptapplescript, script editor
Batch Filebat, cmd
BibTeXbib
Bourne Again Shell (bash)sh, bash, zsh, fish, .bash_aliases, .bash_completions, .bash_functions, .bash_login, .bash_logout, .bash_profile, .bash_variables, .bashrc, .profile, .textmate_init
Cc, h
C#cs, csx
C++cpp, cc, cp, cxx, c++, C, h, hh, hpp, hxx, h++, inl, ipp
CSScss, css.erb, css.liquid
Cargo Build Results``
Clojureclj
Dd, di
Diffdiff, patch
Erlangerl, hrl, Emakefile, emakefile
Gogo
Graphviz (DOT)dot, DOT, gv
Groovygroovy, gvy, gradle
HTML (ASP)asp
HTML (Erlang)yaws
HTML (Rails)rails, rhtml, erb, html.erb
HTML (Tcl)adp
HTMLhtml, htm, shtml, xhtml, inc, tmpl, tpl
Haskellhs
Haxehx, hxsl, hscript
Hxmlhxml
JSONjson, sublime-settings, sublime-menu, sublime-keymap, sublime-mousemap, sublime-theme, sublime-build, sublime-project, sublime-completions, sublime-commands, sublime-macro, sublime-color-scheme
Java Propertiesproperties
Java Server Page (JSP)jsp
Javajava, bsh
JavaDoc``
JavaScript (Rails)js.erb
JavaScriptjs, htc
LaTeX Log``
LaTeXtex, ltx
Lisplisp, cl, clisp, l, mud, el, scm, ss, lsp, fasl
Literate Haskelllhs
Lualua
MATLABmatlab
Make Output``
Makefilemake, GNUmakefile, makefile, Makefile, OCamlMakefile, mak, mk
Markdownmd, mdown, markdown, markdn
MultiMarkdown``
NAnt Build Filebuild
OCamlml, mli
OCamllexmll
OCamlyaccmly
Objective-Cm, h
Objective-C++mm, M, h
PHP Source``
PHPphp, php3, php4, php5, php7, phps, phpt, phtml
Pascalpas, p, dpr
Perlpl, pm, pod, t, PL
Plain Texttxt
Pythonpy, py3, pyw, pyi, pyx, pyx.in, pxd, pxd.in, pxi, pxi.in, rpy, cpy, SConstruct, Sconstruct, sconstruct, SConscript, gyp, gypi, Snakefile, wscript
R Console``
RR, r, s, S, Rprofile
Rd (R Documentation)rd
Regular Expressionre
Regular Expressions (Javascript)``
Regular Expressions (Python)``
Ruby Hamlhaml, sass
Ruby on Railsrxml, builder
Rubyrb, Appfile, Appraisals, Berksfile, Brewfile, capfile, cgi, Cheffile, config.ru, Deliverfile, Fastfile, fcgi, Gemfile, gemspec, Guardfile, irbrc, jbuilder, podspec, prawn, rabl, rake, Rakefile, Rantfile, rbx, rjs, ruby.rail, Scanfile, simplecov, Snapfile, thor, Thorfile, Vagrantfile
Rustrs
SQL (Rails)erbsql, sql.erb
SQLsql, ddl, dml
Scalascala, sbt
Shell-Unix-Generic``
TOMLtoml, tml, Cargo.lock, Gopkg.lock, Pipfile
Tcltcl
TeXsty, cls
Textiletextile
XMLxml, xsd, xslt, tld, dtml, rss, opml, svg
YAMLyaml, yml, sublime-syntax
camlp4``
commands-builtin-shell-bash``
reStructuredTextrst, rest
- - - - - -

© 2019 Kenton Hamaluik

-
- - \ No newline at end of file diff --git a/docs/02-markdown/01-commonmark.html b/docs/02-markdown/01-commonmark.html new file mode 100644 index 0000000..35de0b3 --- /dev/null +++ b/docs/02-markdown/01-commonmark.html @@ -0,0 +1,164 @@ + + + + + + The mkbook Book | Commonmark + + + + + + + + + + + + + +
+

mkbook nominally utilizes CommonMark with some GFM extensions through the use of the comrak crate. In using comrak, a specific set of options are used, which are listed here:

+
+let options: ComrakOptions = ComrakOptions {
+    hardbreaks: false,
+    smart: true,
+    github_pre_lang: false,
+    default_info_string: None,
+    unsafe_: true,
+    ext_strikethrough: true,
+    ext_tagfilter: false,
+    ext_table: true,
+    ext_autolink: true,
+    ext_tasklist: true,
+    ext_superscript: true,
+    ext_header_ids: Some("header".to_owned()),
+    ext_footnotes: true,
+    ext_description_lists: true,
+    ..ComrakOptions::default()
+};
+
+

Mostly, know that the following extensions are enabled:

+
    +
  • Strikethrough
  • +
  • Tables
  • +
  • Autolinks
  • +
  • Task Lists
  • +
  • Superscripts (e = mc^2^.e = mc<sup>2</sup>.)
  • +
  • Footnotes
  • +
  • Description Lists: +
    +First term
    +
    +: Details for the **first term**
    +
    +Second term
    +
    +: Details for the **second term**
    +
    +    More details in second paragraph.
    +
    +
  • +
+ + + + + +

© 2019 Kenton Hamaluik

+
+ + \ No newline at end of file diff --git a/docs/02-markdown/02-syntax-highlighting.html b/docs/02-markdown/02-syntax-highlighting.html new file mode 100644 index 0000000..851ee00 --- /dev/null +++ b/docs/02-markdown/02-syntax-highlighting.html @@ -0,0 +1,626 @@ + + + + + + The mkbook Book | Syntax Highlighting + + + + + + + + + + + + + +
+

Syntax Highlighting

+

GFM syntax highlighting is also available by using fenced code tags with a label denoting the language, as such:

+
+```c++
+#include <stdio>
+
+int main() {
+    std::cout << "Hello, world!" << std::endl;
+    return 0;
+}
+```
+
+

which results in:

+
+#include <stdio>
+
+int main() {
+    std::cout << "Hello, world!" << std::endl;
+    return 0;
+}
+
+

To denote the language you can either use one the language’s extensions as the label, or the full name of the language (which is not case-sensitive).

+

The list of supported languages is currently as follows:

+
+

ASP

+
+
+

asa

+
+
+

ActionScript

+
+
+

as

+
+
+

AppleScript

+
+
+

applescript, script editor

+
+
+

Batch File

+
+
+

bat, cmd

+
+
+

BibTeX

+
+
+

bib

+
+
+

Bourne Again Shell (bash)

+
+
+

sh, bash, zsh, fish, .bash_aliases, .bash_completions, .bash_functions, .bash_login, .bash_logout, .bash_profile, .bash_variables, .bashrc, .profile, .textmate_init

+
+
+

C

+
+
+

c, h

+
+
+

C#

+
+
+

cs, csx

+
+
+

C++

+
+
+

cpp, cc, cp, cxx, c++, C, h, hh, hpp, hxx, h++, inl, ipp

+
+
+

CSS

+
+
+

css, css.erb, css.liquid

+
+
+

Cargo Build Results

+
+
+

``

+
+
+

Clojure

+
+
+

clj

+
+
+

D

+
+
+

d, di

+
+
+

Diff

+
+
+

diff, patch

+
+
+

Erlang

+
+
+

erl, hrl, Emakefile, emakefile

+
+
+

Go

+
+
+

go

+
+
+

Graphviz (DOT)

+
+
+

dot, DOT, gv

+
+
+

Groovy

+
+
+

groovy, gvy, gradle

+
+
+

HTML

+
+
+

html, htm, shtml, xhtml, inc, tmpl, tpl

+
+
+

HTML (ASP)

+
+
+

asp

+
+
+

HTML (Erlang)

+
+
+

yaws

+
+
+

HTML (Rails)

+
+
+

rails, rhtml, erb, html.erb

+
+
+

HTML (Tcl)

+
+
+

adp

+
+
+

Haskell

+
+
+

hs

+
+
+

Haxe

+
+
+

hx, hxsl, hscript

+
+
+

Hxml

+
+
+

hxml

+
+
+

JSON

+
+
+

json, sublime-settings, sublime-menu, sublime-keymap, sublime-mousemap, sublime-theme, sublime-build, sublime-project, sublime-completions, sublime-commands, sublime-macro, sublime-color-scheme

+
+
+

Java

+
+
+

java, bsh

+
+
+

Java Properties

+
+
+

properties

+
+
+

Java Server Page (JSP)

+
+
+

jsp

+
+
+

JavaDoc

+
+
+

``

+
+
+

JavaScript

+
+
+

js, htc

+
+
+

JavaScript (Rails)

+
+
+

js.erb

+
+
+

LaTeX

+
+
+

tex, ltx

+
+
+

LaTeX Log

+
+
+

``

+
+
+

Lisp

+
+
+

lisp, cl, clisp, l, mud, el, scm, ss, lsp, fasl

+
+
+

Literate Haskell

+
+
+

lhs

+
+
+

Lua

+
+
+

lua

+
+
+

MATLAB

+
+
+

matlab

+
+
+

Make Output

+
+
+

``

+
+
+

Makefile

+
+
+

make, GNUmakefile, makefile, Makefile, OCamlMakefile, mak, mk

+
+
+

Markdown

+
+
+

md, mdown, markdown, markdn

+
+
+

MultiMarkdown

+
+
+

``

+
+
+

NAnt Build File

+
+
+

build

+
+
+

OCaml

+
+
+

ml, mli

+
+
+

OCamllex

+
+
+

mll

+
+
+

OCamlyacc

+
+
+

mly

+
+
+

Objective-C

+
+
+

m, h

+
+
+

Objective-C++

+
+
+

mm, M, h

+
+
+

PHP

+
+
+

php, php3, php4, php5, php7, phps, phpt, phtml

+
+
+

PHP Source

+
+
+

``

+
+
+

Pascal

+
+
+

pas, p, dpr

+
+
+

Perl

+
+
+

pl, pm, pod, t, PL

+
+
+

Plain Text

+
+
+

txt

+
+
+

Python

+
+
+

py, py3, pyw, pyi, pyx, pyx.in, pxd, pxd.in, pxi, pxi.in, rpy, cpy, SConstruct, Sconstruct, sconstruct, SConscript, gyp, gypi, Snakefile, wscript

+
+
+

R

+
+
+

R, r, s, S, Rprofile

+
+
+

R Console

+
+
+

``

+
+
+

Rd (R Documentation)

+
+
+

rd

+
+
+

Regular Expression

+
+
+

re

+
+
+

Regular Expressions (Javascript)

+
+
+

``

+
+
+

Regular Expressions (Python)

+
+
+

``

+
+
+

Ruby

+
+
+

rb, Appfile, Appraisals, Berksfile, Brewfile, capfile, cgi, Cheffile, config.ru, Deliverfile, Fastfile, fcgi, Gemfile, gemspec, Guardfile, irbrc, jbuilder, podspec, prawn, rabl, rake, Rakefile, Rantfile, rbx, rjs, ruby.rail, Scanfile, simplecov, Snapfile, thor, Thorfile, Vagrantfile

+
+
+

Ruby Haml

+
+
+

haml, sass

+
+
+

Ruby on Rails

+
+
+

rxml, builder

+
+
+

Rust

+
+
+

rs

+
+
+

SCSS

+
+
+

scss

+
+
+

SQL

+
+
+

sql, ddl, dml

+
+
+

SQL (Rails)

+
+
+

erbsql, sql.erb

+
+
+

Sass

+
+
+

sass

+
+
+

Scala

+
+
+

scala, sbt

+
+
+

Shell-Unix-Generic

+
+
+

``

+
+
+

TOML

+
+
+

toml, tml, Cargo.lock, Gopkg.lock, Pipfile

+
+
+

Tcl

+
+
+

tcl

+
+
+

TeX

+
+
+

sty, cls

+
+
+

Textile

+
+
+

textile

+
+
+

XML

+
+
+

xml, xsd, xslt, tld, dtml, rss, opml, svg

+
+
+

YAML

+
+
+

yaml, yml, sublime-syntax

+
+
+

camlp4

+
+
+

``

+
+
+

commands-builtin-shell-bash

+
+
+

``

+
+
+

reStructuredText

+
+
+

rst, rest

+
+
+ + + + + +

© 2019 Kenton Hamaluik

+
+ + \ No newline at end of file diff --git a/docs/02-markdown/index.html b/docs/02-markdown/index.html new file mode 100644 index 0000000..6b0eebb --- /dev/null +++ b/docs/02-markdown/index.html @@ -0,0 +1,123 @@ + + + + + + The mkbook Book | Markdown + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/03-frontmatter.html b/docs/03-frontmatter/index.html similarity index 55% rename from docs/03-frontmatter.html rename to docs/03-frontmatter/index.html index bc0485b..20a3c01 100644 --- a/docs/03-frontmatter.html +++ b/docs/03-frontmatter/index.html @@ -4,62 +4,102 @@ The mkbook Book | Front Matter - - + + - + - +

Each .md file can optionally contain a header with metadata describing the document. If the header isn’t present, default values will be used which may look ugly.

@@ -84,11 +124,11 @@
- + Next chapter: “Structure” - + diff --git a/docs/04-structure.html b/docs/04-structure/index.html similarity index 69% rename from docs/04-structure.html rename to docs/04-structure/index.html index 8e4b277..b3dc500 100644 --- a/docs/04-structure.html +++ b/docs/04-structure/index.html @@ -4,62 +4,102 @@ The mkbook Book | Structure - - + + - + - +

mkbook follows a fairly simple directory structure for now, with a mkbook.toml file declaring the book’s metadata, and .md files defining each chapter of the book.

@@ -135,11 +175,11 @@
- + Next chapter: “Customization” - + diff --git a/docs/05-customization.html b/docs/05-customization.html deleted file mode 100644 index 0f00443..0000000 --- a/docs/05-customization.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - The mkbook Book | Customization - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/05-customization/index.html b/docs/05-customization/index.html new file mode 100644 index 0000000..457674b --- /dev/null +++ b/docs/05-customization/index.html @@ -0,0 +1,123 @@ + + + + + + The mkbook Book | Customization + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/06-how-it-works.html b/docs/06-how-it-works/index.html similarity index 68% rename from docs/06-how-it-works.html rename to docs/06-how-it-works/index.html index 830dbbf..fcdcfe1 100644 --- a/docs/06-how-it-works.html +++ b/docs/06-how-it-works/index.html @@ -4,56 +4,96 @@ The mkbook Book | How it Works - - + + - + - +

mkbook generates a completely static, javascript-free website from a series of Markdown files. All of the layout and styling is controlled purely by hand-crafted CSS specific to this book’s purpose.

diff --git a/docs/icons.svg b/docs/icons.svg index 8ec8e56..2988103 100644 --- a/docs/icons.svg +++ b/docs/icons.svg @@ -12,5 +12,9 @@ arrow-up + +list-ol + + diff --git a/docs/index.html b/docs/index.html index 9fc2021..d031074 100644 --- a/docs/index.html +++ b/docs/index.html @@ -14,13 +14,13 @@ <p>This tool aims to work somewhat similarly to <em>mdbook</em>, but is generally intended to be a more minimal alternative that is customized more towards my needs and desires than anything else.</p> " /> - +

The mkbook Book

by Kenton Hamaluik

- +

mkbook is my simpler alternative to mdbook which is a great tool, but for which I really dislike some of the decisions they took, such as relying on javascript for highlighting and navigation, and including a lot of bells and whistles such as javascript-based search.

@@ -31,17 +31,43 @@

Table of Contents

    -
  1. Introduction
  2. +
  3. + Introduction + +
  4. -
  5. Markdown
  6. +
  7. + Markdown + +
      + +
    1. Commonmark
    2. + +
    3. Syntax Highlighting
    4. + +
    + +
  8. -
  9. Front Matter
  10. +
  11. + Front Matter + +
  12. -
  13. Structure
  14. +
  15. + Structure + +
  16. -
  17. Customization
  18. +
  19. + Customization + +
  20. -
  21. How it Works
  22. +
  23. + How it Works + +
diff --git a/docs/style.css b/docs/style.css index 78de007..ca51b53 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1 +1 @@ -@import url("https://fonts.googleapis.com/css?family=Crimson+Pro|Poppins:700|Source+Code+Pro&display=swap");body{margin:0;line-height:1.5;font-size:14pt;color:#222222;background:#eeeeee;padding:0;font-family:"Crimson Pro","Georgia",Georgia,"Times New Roman",Times,serif}h1,h2,h3{margin-top:0;line-height:1.2;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif}a{color:#222222;text-decoration:underline}a:hover{color:#8a2888;text-decoration:none}figure{display:block;text-align:center;overflow-x:auto}figure img,figure video{max-width:100%}figure figcaption{display:block;font-size:0.75em;text-align:center}code,kbd{margin:0 2px;padding:0 2px;border:1px solid #4c566a;border-radius:3px;word-break:break-all;font-family:"Source Code Pro","Courier New",Courier,monospace;font-size:0.75em}kbd{color:#222222;background:#eeeeee;box-shadow:0px 2px 4px rgba(0,0,0,0.5)}pre{overflow-x:auto;font-family:"Source Code Pro","Courier New",Courier,monospace;padding:0.5em}dl{display:grid;grid-template-columns:auto 1fr}dl dt{font-weight:700;margin:0;padding:0 0.5em 0.25em;border-right:1px solid #dddddd;text-align:right}dl dd{margin:0;padding:0 0.5em 0.25em}dl dt p,dl dd p{margin:0}p{margin-top:0}footer{color:#444444}footer p{margin-right:0.5em}table{margin:0 auto;border-collapse:collapse;border-spacing:0.5em}table th{border-bottom:1px solid #eee}table th,table td{vertical-align:top}html,body{width:100%;min-height:100vh}body{display:grid;grid-template-columns:auto 1fr;grid-template-rows:1fr;justify-items:stretch;align-items:stretch}body nav.big{background:#2c2c38;padding:0.5em 1em 1em;display:flex;flex-direction:column}body nav.big header{margin:0 0 1em;display:flex;flex-direction:column;align-items:stretch;border-bottom:2px solid #888888}body nav.big header h1{font-size:1.5em;font-weight:700;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0;text-align:left;color:#eeeeee}body nav.big header h1 a{color:#eeeeee;text-decoration:none}body nav.big header h1 a:hover{color:#cf5ccd}body nav.big header h2{font-size:1em;font-weight:600;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0;text-align:right}body nav.big ol{margin:0 2em;padding:0}body nav.big ol li{width:100%;font-size:1.25em;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#eeeeee}body nav.big ol li a{text-decoration:none;margin:0 0 0.25em 0;color:#5babd1}body nav.big ol li a:hover{color:#cf5ccd}body nav.big ol li a.current{color:#cf5ccd}body nav.big ol li a.current:hover{color:#fefefe}body nav.small{display:none;width:100%;align-items:center;justify-content:space-between;background:#2c2c38;padding:0}body nav.small>*{margin:0.5em}body nav.small a{text-decoration:none;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#5babd1}body nav.small a:hover{color:#cf5ccd}body nav.small span.title{text-decoration:none;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#fefefe}body nav.small span.placeholder{width:1em;height:1em}body>*{min-width:0;min-height:0}body article{max-width:38em;padding:0.5em 2em 0 2em}body article>*{max-width:100%}body .next-chapter{width:100%}body .next-chapter a{display:flex;align-items:center;justify-content:flex-end;margin-right:0.5em;font-size:1.2em;text-decoration:none;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#5babd1}body .next-chapter a:hover{color:#cf5ccd}body .next-chapter a span:first-child{margin-right:0.5em}body footer{width:100%;text-align:right;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end}@media screen and (max-width: 768px){body{grid-template-columns:1fr;grid-template-rows:auto 1fr}body nav.big{display:none}body nav.small{display:flex}body article{padding:1em 0.5em 0 0.5em}}body.toc{display:flex;flex-direction:column;justify-content:flex-start;align-items:center}body.toc>*{width:36em}body.toc header{margin-top:1em;display:flex;flex-direction:column;align-items:center}body.toc header h1{font-size:3em;font-weight:700;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0}body.toc header h2{font-size:1em;font-weight:600;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0}body.toc header time{font-size:1em;font-weight:400;font-family:"Crimson Pro","Georgia",Georgia,"Times New Roman",Times,serif}body.toc nav{background:none;display:flex;flex-direction:column;align-items:stretch}body.toc nav h1{text-align:left;font-size:2.5em;font-weight:600;margin-bottom:0}body.toc nav ol{margin:0.25em 0 0}body.toc nav ol li{font-size:1.5em;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif}body.toc nav ol li a{text-decoration:none;margin:0 0 0.25em 0;color:#5babd1}body.toc nav ol li a:hover{color:#cf5ccd}body.toc footer{flex:1}@media screen and (max-width: 768px){body.toc>*{width:100%}body.toc header h1,body.toc header h2,body.toc header time{text-align:center}body.toc article,body.toc nav{padding:0}body.toc article>*,body.toc nav>*{margin-left:0.5em;margin-right:0.5em}body.toc nav h1{font-size:1.75em}}span.icon{display:flex;align-items:center}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:1em;height:1em;stroke-width:0;stroke:currentColor;fill:currentColor}.icon-arrow-left{width:0.875em}.icon-arrow-right{width:0.875em}.icon-arrow-up{width:0.875em}@media (prefers-color-scheme: dark){body{background-color:#222222;color:#eeeeee}a{color:#eeeeee}a:hover{color:#5babd1}nav{background:#18181d}img{filter:grayscale(30%)}dl dt{border-right:1px solid #333333}footer{color:#cccccc}}@media print{body{background:#ffffff;color:#000000}body:not(.toc) nav{display:none}a{color:#000000;text-decoration:underline}h2,h3{break-after:avoid-page}figure{break-inside:avoid}p{orphans:2;widows:2}*{overflow:hidden}body{display:block}} +@import url("https://fonts.googleapis.com/css?family=Crimson+Pro|Poppins:700|Source+Code+Pro&display=swap");body{margin:0;line-height:1.5;font-size:14pt;color:#222222;background:#eeeeee;padding:0;font-family:"Crimson Pro","Georgia",Georgia,"Times New Roman",Times,serif}h1,h2,h3{margin-top:0;line-height:1.2;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif}a{color:#222222;text-decoration:underline}a:hover{color:#8a2888;text-decoration:none}figure{display:block;text-align:center;overflow-x:auto}figure img,figure video{max-width:100%}figure figcaption{display:block;font-size:0.75rem;text-align:center}code,kbd{margin:0 2px;padding:0 2px;border:1px solid #4c566a;border-radius:3px;word-break:break-all;font-family:"Source Code Pro","Courier New",Courier,monospace;font-size:0.75rem}kbd{color:#222222;background:#eeeeee;box-shadow:0px 2px 4px rgba(0,0,0,0.5)}pre{overflow-x:auto;font-family:"Source Code Pro","Courier New",Courier,monospace;padding:0.5rem}dl{display:grid;grid-template-columns:auto auto}dl dt{font-weight:700;margin:0;padding:0 0.5em 0.25rem;border-right:1px solid #dddddd;text-align:right}dl dd{margin:0;padding:0 0.5em 0.25rem}dl dt p,dl dd p{margin:0}p{margin-top:0}footer{color:#444444}footer p{margin-right:0.5rem}table{margin:0 auto;border-collapse:collapse;border-spacing:0.5rem}table th{border-bottom:1px solid #eee}table th,table td{vertical-align:top}ol{list-style-type:none;counter-reset:item;margin:0;padding:0}ol>li{display:table;counter-increment:item;margin-bottom:0.6rem}ol>li:before{content:counters(item, ".") ". ";display:table-cell;padding-right:0.6rem}li ol>li{margin:0}li ol>li:before{content:counters(item, ".") " "}html,body{width:100%;min-height:100vh}body{display:grid;grid-template-columns:auto 1fr;grid-template-rows:1fr;justify-items:stretch;align-items:stretch}body nav.big{background:#2c2c38;padding:0.5em 1em 1rem;display:flex;flex-direction:column}body nav.big header{margin:0 0 1rem;display:flex;flex-direction:column;align-items:stretch;border-bottom:2px solid #888888}body nav.big header h1{font-size:1.5rem;font-weight:700;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0;text-align:left;color:#eeeeee}body nav.big header h1 a{color:#eeeeee;text-decoration:none}body nav.big header h1 a:hover{color:#cf5ccd}body nav.big header h2{font-size:1rem;font-weight:600;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0;text-align:right}body nav.big ol{margin:0 2rem;padding:0}body nav.big ol li{width:100%;font-size:1.25rem;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#eeeeee}body nav.big ol li a{text-decoration:none;margin:0 0 0.25em 0;color:#5babd1}body nav.big ol li a:hover{color:#cf5ccd}body nav.big ol li a.current{color:#cf5ccd}body nav.big ol li a.current:hover{color:#fefefe}body nav.big ol li ol{margin:0 0 0 1rem}body nav.small{display:none;width:100%;align-items:center;justify-content:space-between;background:#2c2c38;padding:0}body nav.small>*{margin:0.5rem}body nav.small a{text-decoration:none;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#5babd1}body nav.small a:hover{color:#cf5ccd}body nav.small span{display:inline-flex;align-items:center}body nav.small span>*{margin-right:0.5rem}body nav.small span>*:last-child{margin-right:0}body nav.small span.title{text-decoration:none;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#fefefe;justify-self:center}body nav.small span.placeholder{width:1em;height:1em}body>*{min-width:0;min-height:0}body article{max-width:38rem;padding:0.5em 2em 0 2rem}body article>*{max-width:100%}body .next-chapter{width:100%}body .next-chapter a{display:flex;align-items:center;justify-content:flex-end;margin-right:0.5rem;font-size:1.2rem;text-decoration:none;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;color:#5babd1}body .next-chapter a:hover{color:#cf5ccd}body .next-chapter a span:first-child{margin-right:0.5rem}body footer{width:100%;text-align:right;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end}@media screen and (max-width: 768px){body{grid-template-columns:1fr;grid-template-rows:auto 1fr}body nav.big{display:none}body nav.small{display:flex}body article{padding:1em 0.5em 0 0.5rem}}body.toc{display:flex;flex-direction:column;justify-content:flex-start;align-items:center}body.toc>*{width:36rem}body.toc header{margin-top:1rem;display:flex;flex-direction:column;align-items:center}body.toc header h1{font-size:3rem;font-weight:700;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0}body.toc header h2{font-size:1rem;font-weight:600;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif;margin-bottom:0}body.toc header time{font-size:1rem;font-weight:400;font-family:"Crimson Pro","Georgia",Georgia,"Times New Roman",Times,serif}body.toc nav{background:none;display:flex;flex-direction:column;align-items:stretch}body.toc nav h1{text-align:left;font-size:2.5rem;font-weight:600;margin-bottom:0}body.toc nav ol li{font-size:1.5rem;font-family:"Poppins","Franklin Gothic Medium","Arial Narrow",Arial,sans-serif}body.toc nav ol li a{text-decoration:none;margin:0 0 0.25em 0;color:#5babd1}body.toc nav ol li a:hover{color:#cf5ccd}body.toc nav ol li ol li{font-size:1.25rem}body.toc nav>ol{margin-left:0.5rem;margin-right:0.5rem}body.toc article,body.toc nav{padding:0}body.toc article>*,body.toc nav>*{margin-left:0.5rem;margin-right:0.5rem}body.toc footer{flex:1}@media screen and (max-width: 768px){body.toc>*{width:100%}body.toc header h1,body.toc header h2,body.toc header time{text-align:center}body.toc nav h1{font-size:1.75rem}}span.icon{display:flex;align-items:center}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:1em;height:1em;stroke-width:0;stroke:currentColor;fill:currentColor}.icon-arrow-left{width:0.875em}.icon-arrow-right{width:0.875em}.icon-arrow-up{width:0.875em}.icon-list-ol{width:1em}@media (prefers-color-scheme: dark){body{background-color:#222222;color:#eeeeee}a{color:#eeeeee}a:hover{color:#5babd1}nav{background:#18181d}img{filter:grayscale(30%)}dl dt{border-right:1px solid #333333}footer{color:#cccccc}}@media print{body{background:#ffffff;color:#000000}body:not(.toc) nav{display:none}a{color:#000000;text-decoration:underline}h2,h3{break-after:avoid-page}figure{break-inside:avoid}p{orphans:2;widows:2}*{overflow:hidden}body{display:block}} diff --git a/src/main.rs b/src/main.rs index bc03be1..d5ee258 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,8 @@ pub const ASSET_DEFAULT_INTRODUCTION: &'static [u8] = include_bytes!(concat!(env pub const SYNTAX_TOML: &'static str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/syntaxes/TOML.sublime-syntax")); pub const SYNTAX_HAXE: &'static str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/syntaxes/haxe.sublime-syntax")); pub const SYNTAX_HXML: &'static str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/syntaxes/hxml.sublime-syntax")); +pub const SYNTAX_SASS: &'static str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/syntaxes/Sass.sublime-syntax")); +pub const SYNTAX_SCSS: &'static str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/syntaxes/SCSS.sublime-syntax")); lazy_static! { static ref HIGHLIGHT_SYNTAX_SETS: SyntaxSet = { @@ -26,13 +28,17 @@ lazy_static! { ssb.add(SyntaxDefinition::load_from_str(SYNTAX_TOML, true, None).expect("valid TOML syntax definition")); ssb.add(SyntaxDefinition::load_from_str(SYNTAX_HAXE, true, None).expect("valid haxe syntax definition")); ssb.add(SyntaxDefinition::load_from_str(SYNTAX_HXML, true, None).expect("valid hxml syntax definition")); + ssb.add(SyntaxDefinition::load_from_str(SYNTAX_SASS, true, None).expect("valid sass syntax definition")); + ssb.add(SyntaxDefinition::load_from_str(SYNTAX_SCSS, true, None).expect("valid scss syntax definition")); let ss = ssb.build(); //if cfg!(debug_assertions) { - // println!("| Language Name | Supported Tags / Extensions |"); - // println!("|:-|:-|"); - // for s in ss.syntaxes().iter() { - // println!("| {} | `{}` |", s.name, s.file_extensions.iter().map(|s| &**s).collect::>().join("`, `")); + // let mut syntaxes: Vec<(String, String)> = ss.syntaxes().iter() + // .map(|s| (s.name.clone(), s.file_extensions.iter().map(|s| &**s).collect::>().join("`, `"))) + // .collect(); + // syntaxes.sort_by(|a, b| a.0.cmp(&b.0)); + // for syntax in syntaxes { + // println!("{}\n\n: `{}`\n\n", syntax.0, syntax.1); // } //} @@ -65,6 +71,7 @@ mod filters; use models::frontmatter::{ParsedFrontMatter, FrontMatter}; use models::book::{ParsedBook, Book}; +use models::chapter::{Chapter}; fn format_code(lang: &str, src: &str) -> Result> { use syntect::parsing::SyntaxReference; @@ -165,10 +172,10 @@ fn format_markdown(src: &str) -> Result> { #[template(path = "index.html")] struct IndexTemplate<'a, 'b> { book: &'a Book, - chapters: &'b Vec, + chapters: &'b Vec, } -fn generate_index(book: &Book, chapters: &Vec, mut output: W) -> Result<(), Box> { +fn generate_index(book: &Book, chapters: &Vec, mut output: W) -> Result<(), Box> { // fill out our template let template = IndexTemplate { book, @@ -185,33 +192,19 @@ fn generate_index(book: &Book, chapters: &Vec { - title: &'a str, + chapter: &'a Chapter, content: &'b str, url: &'f str, - chapters: &'c Vec, - prev_chapter: Option<&'d models::chapter::Chapter>, - next_chapter: Option<&'e models::chapter::Chapter>, + chapters: &'c Vec, + prev_chapter: Option<&'d Chapter>, + next_chapter: Option<&'e Chapter>, book: &'g Book, } -fn format_page(book: &Book, frontmatter: FrontMatter, chapters: &Vec, url: &str, content: &str, mut output: W) -> Result<(), Box> { - let this_index = chapters.iter().enumerate().find(|(_, chap)| chap.url == url).map(|(i, _)| i).expect("chapter exists"); - let prev_chapter = if this_index > 0 { - Some(chapters.iter().nth(this_index - 1).expect("chapter n-1 exists")) - } - else { - None - }; - let next_chapter = if this_index < chapters.len() - 1 { - Some(chapters.iter().nth(this_index + 1).expect("chapter n+1 exists")) - } - else { - None - }; - +fn format_page(book: &Book, chapter: &Chapter, chapters: &Vec, prev_chapter: Option<&Chapter>, next_chapter: Option<&Chapter>, url: &str, content: &str, mut output: W) -> Result<(), Box> { // fill out our template let template = PageTemplate { - title: &frontmatter.title, + chapter, content, url, chapters, @@ -274,25 +267,84 @@ fn main() -> Result<(), Box> { let book: Book = parsed_book.into(); // load all our chapters - let mut chapters: Vec = Vec::default(); + let mut chapters: Vec = Vec::default(); for entry in src.read_dir()? { let entry = entry?; let path = entry.path(); - if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() { + if entry.file_type()?.is_dir() { + // try to find a `chapter.toml` file and parse it to get the chapter's title, fall back to the directory + // name if we can't do that + let chapter_name = path.file_name().map(std::ffi::OsStr::to_str).flatten().unwrap_or_default(); + let index_path = path.join("index.md"); + let (front, contents) = if index_path.exists() { + let contents = fs::read_to_string(&index_path)?; + let (front, contents) = extract_frontmatter(&contents)?; + let front = front.unwrap_or_default().into_front(chapter_name); + (front, contents) + } + else { + (FrontMatter { + title: chapter_name.to_owned(), + }, String::new()) + }; + + let mut chapter: Chapter = Chapter { + url: format!("{}/index.html", chapter_name), + front, + sections: Vec::default(), + source: path.clone(), + contents, + }; + + for entry in path.read_dir()? { + let entry = entry?; + let path = entry.path(); + if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() { + let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten(); + if name.is_none() { continue; } + let name = name.unwrap(); + if name == "index" { + continue; + } + + let contents = fs::read_to_string(&path)?; + let (front, contents) = extract_frontmatter(&contents)?; + let front = front.unwrap_or_default().into_front(name); + chapter.sections.push(Chapter { + url: format!("{}/{}.html", chapter_name, name), + front, + sections: Vec::new(), + source: path, + contents, + }); + } + } + + chapters.push(chapter); + } + else if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() { let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten(); if name.is_none() { continue; } let name = name.unwrap(); let contents = fs::read_to_string(&path)?; - let (front, _) = extract_frontmatter(&contents)?; + let (front, contents) = extract_frontmatter(&contents)?; let front = front.unwrap_or_default().into_front(name); - chapters.push(models::chapter::Chapter { - url: format!("{}.html", name), - title: front.title, + chapters.push(Chapter { + url: format!("{}/index.html", name), + front, + sections: Vec::new(), + source: path, + contents, }); } } + + // sort all the chapters chapters.sort_by(|a, b| a.url.cmp(&b.url)); + for chapter in chapters.iter_mut() { + chapter.sections.sort_by(|a, b| a.url.cmp(&b.url)); + } // generate our index let index_out_path = dest.join("index.html"); @@ -301,26 +353,61 @@ fn main() -> Result<(), Box> { generate_index(&book, &chapters, index_out)?; println!("Rendered index into `{}`", index_out_path.display()); - // compile markdown - for entry in src.read_dir()? { - let entry = entry?; - let path = entry.path(); - if let Some("md") = path.extension().map(std::ffi::OsStr::to_str).flatten() { - let name = path.file_stem().map(std::ffi::OsStr::to_str).flatten(); - if name.is_none() { continue; } - let name = name.unwrap(); - let out = dest.join(format!("{}.html", name)); - + // compile markdown and write the actual pages + let mut prev_chapter = None; + for (chapter_index, chapter) in chapters.iter().enumerate() { + // render the index + let chapter_root = dest.join(chapter.source.file_stem().map(std::ffi::OsStr::to_str).flatten().unwrap()); + let out = chapter_root.join("index.html"); + print!("Rendering `{}` into `{}`...", chapter.source.display(), out.display()); + fs::create_dir_all(&chapter_root)?; + + let outfile = fs::File::create(&out)?; + let outfile = io::BufWriter::new(outfile); + + let contents = format_markdown(&chapter.contents)?; + + let next_chapter = + if chapter.sections.len() > 0 { + Some(chapter.sections.iter().nth(0).expect("section 0 exists")) + } + else if chapter_index < chapters.len() - 1 { + Some(chapters.iter().nth(chapter_index + 1).expect("chapter n+1 exists")) + } + else { + None + }; + + format_page(&book, &chapter, &chapters, prev_chapter, next_chapter, &chapter.url, &contents, outfile)?; + prev_chapter = Some(chapter); + + println!(" done!"); + + // now the sections + for (section_index, section) in chapter.sections.iter().enumerate() { + let name = section.source.file_stem().map(std::ffi::OsStr::to_str).flatten().unwrap(); + let out = chapter_root.join(&format!("{}.html", name)); + print!("Rendering `{}` into `{}`...", section.source.display(), out.display()); + let outfile = fs::File::create(&out)?; let outfile = io::BufWriter::new(outfile); - - let contents = fs::read_to_string(&path)?; - let (front, contents) = extract_frontmatter(&contents)?; - let front = front.unwrap_or_default().into_front(name); - let contents = format_markdown(&contents)?; - format_page(&book, front, &chapters, &format!("{}.html", name), &contents, outfile)?; - - println!("Rendered `{}` into `{}`", path.display(), out.display()); + + let contents = format_markdown(§ion.contents)?; + + let next_chapter = if section_index < chapter.sections.len() - 1 { + Some(chapter.sections.iter().nth(section_index + 1).expect("chapter n+1 exists")) + } + else if chapter_index < chapters.len() - 1 { + Some(chapters.iter().nth(chapter_index + 1).expect("chapter n+1 exists")) + } + else { + None + }; + + format_page(&book, §ion, &chapters, prev_chapter, next_chapter, §ion.url, &contents, outfile)?; + prev_chapter = Some(section); + + println!(" done!"); } } diff --git a/src/models/chapter.rs b/src/models/chapter.rs index 4991c62..80bb12a 100644 --- a/src/models/chapter.rs +++ b/src/models/chapter.rs @@ -1,4 +1,11 @@ +use std::path::PathBuf; +use super::frontmatter::FrontMatter; + +#[derive(Debug)] pub struct Chapter { pub url: String, - pub title: String, + pub front: FrontMatter, + pub sections: Vec, + pub source: PathBuf, + pub contents: String, } diff --git a/src/models/frontmatter.rs b/src/models/frontmatter.rs index 0655310..0fc8154 100644 --- a/src/models/frontmatter.rs +++ b/src/models/frontmatter.rs @@ -1,10 +1,11 @@ use serde::Deserialize; -#[derive(Deserialize, Default)] +#[derive(Deserialize, Default, Debug)] pub struct ParsedFrontMatter { pub title: Option, } +#[derive(Debug)] pub struct FrontMatter { pub title: String, } diff --git a/style/base.scss b/style/base.scss index fcbe3c4..bf3b850 100644 --- a/style/base.scss +++ b/style/base.scss @@ -38,7 +38,7 @@ figure { figcaption { display: block; - font-size: 0.75em; + font-size: 0.75rem; text-align: center; } } @@ -50,7 +50,7 @@ code, kbd { border-radius: 3px; word-break: break-all; font-family: $font-mono; - font-size: 0.75em; + font-size: 0.75rem; } kbd { @@ -62,24 +62,24 @@ kbd { pre { overflow-x: auto; font-family: $font-mono; - padding: 0.5em; + padding: 0.5rem; } dl { display: grid; - grid-template-columns: auto 1fr; + grid-template-columns: auto auto; dt { font-weight: 700; margin: 0; - padding: 0 0.5em 0.25em; + padding: 0 0.5em 0.25rem; border-right: 1px solid #dddddd; text-align: right; } dd { margin: 0; - padding: 0 0.5em 0.25em; + padding: 0 0.5em 0.25rem; } dt, dd { @@ -96,14 +96,14 @@ p { footer { color: #444444; p { - margin-right: 0.5em; + margin-right: 0.5rem; } } table { margin: 0 auto; border-collapse: collapse; - border-spacing: 0.5em; + border-spacing: 0.5rem; th { border-bottom: 1px solid #eee; @@ -113,3 +113,32 @@ table { vertical-align: top; } } + +// sub-list numbering +// taken from: https://stackoverflow.com/a/26245056 +ol { + list-style-type: none; + counter-reset: item; + margin: 0; + padding: 0; +} + +ol > li { + display: table; + counter-increment: item; + margin-bottom: 0.6rem; +} + +ol > li:before { + content: counters(item, ".") ". "; + display: table-cell; + padding-right: 0.6rem; +} + +li ol > li { + margin: 0; +} + +li ol > li:before { + content: counters(item, ".") " "; +} diff --git a/style/icons.scss b/style/icons.scss index 040aece..79c7b15 100644 --- a/style/icons.scss +++ b/style/icons.scss @@ -23,4 +23,8 @@ span.icon { .icon-arrow-up { width: 0.875em; +} + +.icon-list-ol { + width: 1em; } \ No newline at end of file diff --git a/style/layout.scss b/style/layout.scss index b5e833c..6c058fb 100644 --- a/style/layout.scss +++ b/style/layout.scss @@ -12,20 +12,20 @@ body { nav.big { background: #2c2c38; - padding: 0.5em 1em 1em; + padding: 0.5em 1em 1rem; display: flex; flex-direction: column; header { - margin: 0 0 1em; + margin: 0 0 1rem; display: flex; flex-direction: column; align-items: stretch; border-bottom: 2px solid #888888; h1 { - font-size: 1.5em; + font-size: 1.5rem; font-weight: 700; font-family: $font-sansserif; margin-bottom: 0; @@ -44,7 +44,7 @@ body { } h2 { - font-size: 1em; + font-size: 1rem; font-weight: 600; font-family: $font-sansserif; margin-bottom: 0; @@ -53,11 +53,11 @@ body { } ol { - margin: 0 2em; + margin: 0 2rem; padding: 0; li { width: 100%; - font-size: 1.25em; + font-size: 1.25rem; font-family: $font-sansserif; color: #eeeeee; a { @@ -77,8 +77,16 @@ body { } } } + + ol { + margin: 0 0 0 1rem; + } } } + + /*ol { counter-reset: item } + li{ display: block } + li:before { content: counters(item, ".") " "; counter-increment: item }*/ } nav.small { @@ -90,7 +98,7 @@ body { padding: 0; >* { - margin: 0.5em; + margin: 0.5rem; } a { @@ -103,10 +111,24 @@ body { } } + span { + display: inline-flex; + align-items: center; + + >* { + margin-right: 0.5rem; + + &:last-child { + margin-right: 0; + } + } + } + span.title { text-decoration: none; font-family: $font-sansserif; color: #fefefe; + justify-self: center; } span.placeholder { @@ -121,8 +143,8 @@ body { } article { - max-width: 38em; - padding: 0.5em 2em 0 2em; + max-width: 38rem; + padding: 0.5em 2em 0 2rem; >* { max-width: 100%; @@ -136,9 +158,9 @@ body { display: flex; align-items: center; justify-content: flex-end; - margin-right: 0.5em; + margin-right: 0.5rem; - font-size: 1.2em; + font-size: 1.2rem; text-decoration: none; font-family: $font-sansserif; color: #5babd1; @@ -148,7 +170,7 @@ body { } span:first-child { - margin-right: 0.5em; + margin-right: 0.5rem; } } } @@ -177,7 +199,7 @@ body { } article { - padding: 1em 0.5em 0 0.5em; + padding: 1em 0.5em 0 0.5rem; } } } diff --git a/style/toc.scss b/style/toc.scss index 17d0013..bb0f8fb 100644 --- a/style/toc.scss +++ b/style/toc.scss @@ -1,101 +1,114 @@ body.toc { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + + > * { + width: 36rem; + } + + header { + margin-top: 1rem; display: flex; flex-direction: column; - justify-content: flex-start; align-items: center; - >* { - width: 36em; + h1 { + font-size: 3rem; + font-weight: 700; + font-family: $font-sansserif; + margin-bottom: 0; } - header { - margin-top: 1em; - display: flex; - flex-direction: column; - align-items: center; - - h1 { - font-size: 3em; - font-weight: 700; - font-family: $font-sansserif; - margin-bottom: 0; - } - - h2 { - font-size: 1em; - font-weight: 600; - font-family: $font-sansserif; - margin-bottom: 0; - } + h2 { + font-size: 1rem; + font-weight: 600; + font-family: $font-sansserif; + margin-bottom: 0; + } - time { - font-size: 1em; - font-weight: 400; - font-family: $font-serif; - } + time { + font-size: 1rem; + font-weight: 400; + font-family: $font-serif; } + } - nav { - background: none; - display: flex; - flex-direction: column; - align-items: stretch; - - h1 { - text-align: left; - font-size: 2.5em; - font-weight: 600; - margin-bottom: 0; + nav { + background: none; + display: flex; + flex-direction: column; + align-items: stretch; + + h1 { + text-align: left; + font-size: 2.5rem; + font-weight: 600; + margin-bottom: 0; + } + + ol { + li { + font-size: 1.5rem; + font-family: $font-sansserif; + + a { + text-decoration: none; + margin: 0 0 0.25em 0; + color: #5babd1; + + &:hover { + color: #cf5ccd; + } } ol { - margin: 0.25em 0 0; - li { - font-size: 1.5em; - font-family: $font-sansserif; - - a { - text-decoration: none; - margin: 0 0 0.25em 0; - color: #5babd1; - - &:hover { - color: #cf5ccd; - } - } - } + li { + font-size: 1.25rem; + } } + } + } + + > ol { + margin-left: 0.5rem; + margin-right: 0.5rem; } + } - footer { - flex: 1; + article, + nav { + padding: 0; + > * { + margin-left: 0.5rem; + margin-right: 0.5rem; } + } + + footer { + flex: 1; + } } @media screen and (max-width: 768px) { - body.toc { - >* { - width: 100%; - } - - header { - h1, h2, time { - text-align: center; - } - } + body.toc { + > * { + width: 100%; + } - article, nav { - padding: 0; - >* { - margin-left: 0.5em; - margin-right: 0.5em; - } - } + header { + h1, + h2, + time { + text-align: center; + } + } - nav { - h1 { - font-size: 1.75em; - } - } + nav { + h1 { + font-size: 1.75rem; + } } -} \ No newline at end of file + } +} diff --git a/templates/index.html b/templates/index.html index f9fbe76..700e0e3 100644 --- a/templates/index.html +++ b/templates/index.html @@ -27,7 +27,16 @@

Table of Contents

    {% for chapter in chapters %} -
  1. {{ chapter.title }}
  2. +
  3. + {{ chapter.front.title }} + {% if chapter.sections.len() > 0 %} +
      + {% for section in chapter.sections %} +
    1. {{ section.front.title }}
    2. + {% endfor %} +
    + {% endif %} +
  4. {% endfor %}
diff --git a/templates/page.html b/templates/page.html index d96fd0a..26758e2 100644 --- a/templates/page.html +++ b/templates/page.html @@ -3,9 +3,9 @@ - {{ book.title }} | {{ title }} - - + {{ book.title }} | {{ chapter.front.title }} + + @@ -17,58 +17,79 @@