canSplit calculation and new codeExample short code

This commit is contained in:
Sana Javed 2023-03-06 12:59:38 +01:00
parent f67317f20d
commit a3442155a5
4 changed files with 98 additions and 131 deletions

View File

@ -1,5 +1,6 @@
'use strict';
const path = require('path');
const { EleventyRenderPlugin } = require('@11ty/eleventy');
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const formatDistanceToNow = require('date-fns/formatDistanceToNow');
@ -9,8 +10,8 @@ const markdown = require('markdown-it');
const markdownItAttrs = require('markdown-it-attrs');
const markdownDefList = require('markdown-it-deflist');
const typogrify = require('typogr');
const sass = require('sass');
const { getImplStatus } = require('./source/helpers/sass_helpers.ts');
const { Liquid } = require('liquidjs');
const { getImplStatus, canSplit, generateCodeExample } = require('./source/helpers/sass_helpers.ts');
/** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */
module.exports = (eleventyConfig) => {
@ -53,6 +54,15 @@ module.exports = (eleventyConfig) => {
return '';
});
const engine = new Liquid({
root: path.resolve(__dirname, 'source/_includes/'),
extname: '.liquid',
});
eleventyConfig.addLiquidShortcode('codeExample', (contents, exampleName, autogenCSS = true, syntax = null) => {
const codeExample = generateCodeExample(contents, autogenCSS)
return engine.renderFile('code_example.liquid', {code: codeExample, exampleName: exampleName})
})
// Paired shortcodes...
eleventyConfig.addPairedLiquidShortcode('markdown', (content) =>
mdown.render(content),
@ -109,42 +119,6 @@ module.exports = (eleventyConfig) => {
},
);
eleventyConfig.addLiquidFilter(
'codeExample',
(contents, autogenCSS = true, syntax = null) => {
//TODO when are values for syntax passed in?
//TODO add tests
const splitContents = contents.split('===');
const scssContents = splitContents[0];
const sassContents = splitContents[1];
const cssContents = splitContents[2];
const scssExamples = scssContents.split('---');
const sassExamples = sassContents.split('---');
let cssExample;
if (cssContents) {
cssExample = cssContents;
} else if (!cssContents && autogenCSS) {
// TODO check first if you even have scss or sass to generate css from
// TODO what if no scss but sass?
cssExample = '';
scssExamples.forEach((scssSnippet) => {
const generatedCSS = sass.compileString(scssSnippet);
cssExample += generatedCSS.css;
});
}
return {
scss: scssExamples,
css: cssExample,
sass: sassExamples,
splitLocation: '50.0%', //TODO dynamically determine
};
},
);
eleventyConfig.addPlugin(EleventyRenderPlugin);
eleventyConfig.addPlugin(syntaxHighlight);

View File

@ -1,56 +1,52 @@
{% assign first_tab_id = ui_id %}
{% assign second_tab_id = first_tab_id | plus: 1 %}
{% assign third_tab_id = second_tab_id | plus: 1 %}
<div class="code-example ui-tabs" style="--split-location: {{ code.splitLocation }}">
<div class="code-example ui-tabs {% if code.canSplit %}can-split{% endif %}" style="--split-location: {{ code.splitLocation }}" >
<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix" role="tablist">
<li
class="ui-tabs-tab ui-tab ui-tabs-active"
aria-controls="example-{{ example_id | strip }}-scss"
aria-controls="example-{{ exampleName | strip }}-scss"
role="tab"
aria-expanded="true"
aria-selected="true">
<a
href="#example-{{ example_id | strip }}-scss"
href="#example-{{ exampleName | strip }}-scss"
class="ui-tabs-anchor"
role="presentation"
tabindex="-1"
id="ui-id-{{ first_tab_id | strip }}">SCSS</a>
id="ui-id-{{ exampleName | strip }}-scss">SCSS</a>
</li>
<li
class="ui-tabs-tab ui-tab"
role="tab"
aria-controls="example-{{ example_id | strip }}-sass"
aria-controls="example-{{ exampleName | strip }}-sass"
aria-selected="false"
aria-expanded="false"
tabindex="-1">
<a
href="#example-{{ example_id | strip }}-sass"
href="#example-{{ exampleName | strip }}-sass"
class="ui-tabs-anchor"
role="presentation"
tabindex="-1"
id="ui-id-{{ second_tab_id | strip }}">Sass</a>
id="ui-id-{{ exampleName | strip }}-sass">Sass</a>
</li>
<li
class="ui-tabs-tab css-tab ui-tab"
role="tab"
tabindex="-1"
aria-controls="example-{{ example_id | strip }}-css"
aria-labelledby="ui-id-{{ third_tab_id | strip }}"
aria-controls="example-{{ exampleName | strip }}-css"
aria-labelledby="ui-id-{{ exampleName | strip }}-css"
aria-selected="false"
aria-expanded="false">
<a
href="#example-{{ example_id | strip }}-css"
href="#example-{{ exampleName | strip }}-css"
class="ui-tabs-anchor"
role="presentation"
tabindex="-1"
id="ui-id-{{ third_tab_id | strip }}">CSS</a>
id="ui-id-{{ exampleName | strip }}-css">CSS</a>
</li>
</ul>
<div
id="example-{{ example_id | strip }}-scss"
id="example-{{ exampleName | strip }}-scss"
class="ui-tabs-panel scss"
aria-labelledby="ui-id-{{ first_tab_id | strip }}"
aria-labelledby="ui-id-{{ exampleName | strip }}-scss"
role="tabpanel"
aria-hidden="false"
style="">
@ -59,9 +55,9 @@
{%- endfor -%}
</div>
<div
id="example-{{ example_id | strip }}-sass"
id="example-{{ exampleName | strip }}-sass"
class="ui-tabs-panel sass ui-tabs-panel-inactive ui-tabs-panel-previously-active"
aria-labelledby="ui-id-{{ second_tab_id | strip }}"
aria-labelledby="ui-id-{{ exampleName | strip }}-sass"
role="tabpanel"
aria-hidden="true"
style="">
@ -70,9 +66,9 @@
{%- endfor -%}
</div>
<div
id="example-{{ example_id | strip }}-css"
id="example-{{ exampleName | strip }}-css"
class="ui-tabs-panel css ui-tabs-panel-inactive"
aria-labelledby="ui-id-{{ third_tab_id | strip }}"
aria-labelledby="ui-id-{{ exampleName | strip }}-css"
role="tabpanel"
aria-hidden="true"
style="">

View File

@ -82,7 +82,7 @@ separate them. All our examples are available in both syntaxes.
{% endmarkdown %}
{%- capture captureCode -%}
{%- capture variablesCodeExample -%}
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
@ -98,12 +98,7 @@ body
font: 100% $font-stack
color: $primary-color
{%- endcapture -%}
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
{%- assign example_id = 1 -%}
{%- assign ui_id = 1 -%}
{% render 'code_example', code: parsedExample,example_id: example_id, ui_id: ui_id %}
{% codeExample variablesCodeExample, 'variables' %}
{% markdown %}
When the Sass is processed, it takes the variables we define for the
@ -134,7 +129,7 @@ navigation:
{% endmarkdown %}
{%- capture captureCode -%}
{%- capture nestingCodeExample -%}
nav {
ul {
margin: 0;
@ -165,18 +160,7 @@ nav
padding: 6px 12px
text-decoration: none
{%- endcapture -%}
{% capture example_id %}
{{ example_id | plus: 1 }}
{% endcapture %}
{% capture ui_id %}
{{ ui_id | plus: 3 }}
{% endcapture %}
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
{% codeExample nestingCodeExample, 'nesting' %}
</section>
@ -210,7 +194,6 @@ partials are used with the `@use` rule.
{% assign implStatusData = "1.23.0" | implStatus: false, false, false, false, "Only Dart Sass currently supports `@use`. Users of other implementations must use the [`@import` rule][] instead.
[`@import` rule]: /documentation/at-rules/import" %}
{% render 'impl_status', implStatusData: implStatusData %}
You don't have to write all your Sass in a single file. You can split it up
@ -224,7 +207,7 @@ file will also include the CSS it generates in your compiled output!
{% endmarkdown %}
{%- capture captureCode -%}
{%- capture modulesCodeExample -%}
// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
@ -271,18 +254,7 @@ body {
color: white;
}
{% endcapture %}
{% capture example_id %}
{{ example_id | plus: 1 }}
{% endcapture %}
{% capture ui_id %}
{{ ui_id | plus: 3 }}
{% endcapture %}
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
{% codeExample modulesCodeExample, 'modules' %}
</section>
@ -299,7 +271,7 @@ Sass very DRY. You can even pass in values to make your mixin more flexible. Her
{% endmarkdown %}
{% capture captureCode %}
{% capture mixinsCodeExample %}
@mixin theme($theme: DarkGray) {
background: $theme;
box-shadow: 0 0 1px rgba($theme, .25);
@ -332,17 +304,7 @@ Sass very DRY. You can even pass in values to make your mixin more flexible. Her
@include theme($theme: DarkGreen)
{% endcapture %}
{% capture example_id %}
{{ example_id | plus: 1 }}
{% endcapture %}
{% capture ui_id %}
{{ ui_id | plus: 3 }}
{% endcapture %}
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
{% codeExample mixinsCodeExample, 'mixins' %}
{% markdown %}
To create a mixin you use the `@mixin` directive and give it a name. We've named our mixin `theme`. We're also using the variable `$theme` inside the parentheses so we can pass in a `theme` of whatever we want. After you create your mixin, you can then use it as a CSS declaration starting with `@include` followed by the name of the mixin.
@ -362,7 +324,7 @@ Using `@extend` lets you share a set of CSS properties from one selector to anot
{% endmarkdown %}
{%- capture captureCode -%}
{%- capture extendInheritanceCodeExample -%}
// This CSS will print because %message-shared is extended.
%message-shared {
border: 1px solid #ccc;
@ -422,18 +384,7 @@ Using `@extend` lets you share a set of CSS properties from one selector to anot
@extend %message-shared
border-color: yellow
{% endcapture %}
{% capture example_id %}
{{ example_id | plus: 1 }}
{% endcapture %}
{% capture ui_id %}
{{ ui_id | plus: 3 }}
{% endcapture %}
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
{% codeExample extendInheritanceCodeExample, 'extend-inheritance' %}
{% markdown %}
What the above code does is tells `.message`, `.success`, `.error`, and
@ -468,7 +419,7 @@ to do some simple math to calculate widths for an `article` and `aside`.
{% endmarkdown %}
{%- capture captureCode -%}
{%- capture operatorsCodeExample -%}
@use "sass:math";
.container {
@ -512,18 +463,7 @@ aside[role="complementary"] {
margin-left: auto;
}
{% endcapture %}
{% capture example_id %}
{{ example_id | plus: 1 }}
{% endcapture %}
{% capture ui_id %}
{{ ui_id | plus: 3 }}
{% endcapture %}
{%- assign parsedExample = captureCode | codeExample: true, 'scss' -%}
{% render 'code_example', code: parsedExample, example_id: example_id, ui_id: ui_id %}
{% codeExample operatorsCodeExample, 'operators' %}
{% markdown %}
We've created a very simple fluid grid, based on 960px. Operations in Sass

View File

@ -1,3 +1,37 @@
import sass from 'sass';
export function generateCodeExample(contents: string, autogenCSS: boolean, syntax: string) {
const splitContents = contents.split('===');
const scssContents = splitContents[0];
const sassContents = splitContents[1];
const cssContents = splitContents[2];
const scssExamples = scssContents.split('---');
const sassExamples = sassContents.split('---');
let cssExample: string;
if (cssContents) {
cssExample = cssContents;
} else {
// TODO check first if you even have scss or sass to generate css from
// TODO what if no scss but sass?
cssExample = '';
scssExamples.forEach((scssSnippet) => {
const generatedCSS = sass.compileString(scssSnippet);
cssExample += generatedCSS.css;
});
}
return {
scss: scssExamples,
css: cssExample,
sass: sassExamples,
canSplit: canSplit(scssExamples, sassExamples, cssExample),
splitLocation: '50.0%', // TODO remove when css grid implementation done
};
}
export function getImplStatus(status: string | boolean | null) {
switch (status) {
case null:
@ -12,3 +46,26 @@ export function getImplStatus(status: string | boolean | null) {
return `since ${status}`;
}
}
export function canSplit(
scssExamples: string[],
sassExamples: string[],
cssExample: string,
) {
const exampleSources: [string[], string[]] = [scssExamples, sassExamples];
const exampleSourceLengths = exampleSources
.map((sourceList) =>
sourceList.map((source) =>
source.split('\n').map((line) => line.length),
),
)
.flat()
.flat();
const cssSourceLengths = cssExample.split('\n').map((line) => line.length);
const maxSourceWidth = Math.max(...exampleSourceLengths);
const maxCSSWidth = Math.max(...cssSourceLengths)
//TODO css example doesn't include comments so extend inheritance example can split is wrong
return Boolean((maxSourceWidth + maxCSSWidth) < 110);
}