From 1020e0769e6fce702f2de5ede8394df86d9aa588 Mon Sep 17 00:00:00 2001 From: Sesh Sadasivam Date: Mon, 11 Apr 2022 21:57:15 -0700 Subject: [PATCH 1/3] Refactor codeblocks to handle generic variant input --- _layouts/spec.html | 8 +++++++ demo/enhanced-code-blocks.md | 6 ++--- demo/page-configuration-options.md | 6 +++-- docs/USAGE_ADVANCED.md | 24 +++++++++++++------ src_js/Config.ts | 13 ++++++++++ src_js/components/main_content/types.ts | 4 ++++ .../main_content/useEnhancedCodeBlocks.tsx | 19 +++++++++++---- src_js/global.d.ts | 3 ++- 8 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 src_js/components/main_content/types.ts diff --git a/_layouts/spec.html b/_layouts/spec.html index dab09f3b..91933801 100644 --- a/_layouts/spec.html +++ b/_layouts/spec.html @@ -89,11 +89,19 @@ with `nil` before deciding to use the site-configuration option. {%- endcomment -%} + {%- comment -%} + `useLegacyCodeBlocks` is DEPRECATED. + {%- endcomment -%} {% assign useLegacyCodeBlocks = page.useLegacyCodeBlocks %} {%- if useLegacyCodeBlocks == nil -%} {%- assign useLegacyCodeBlocks = site.primerSpec.useLegacyCodeBlocks -%} {%- endif -%} useLegacyCodeBlocks: {{ useLegacyCodeBlocks | default: false }}, + {% assign defaultCodeblockVariant = page.defaultCodeblockVariant %} + {%- if defaultCodeblockVariant == nil -%} + {%- assign defaultCodeblockVariant = site.primerSpec.defaultCodeblockVariant -%} + {%- endif -%} + defaultCodeblockVariant: "{{ defaultCodeblockVariant | default: 'enhanced' }}" }; diff --git a/demo/enhanced-code-blocks.md b/demo/enhanced-code-blocks.md index ea4ea71e..38641fad 100644 --- a/demo/enhanced-code-blocks.md +++ b/demo/enhanced-code-blocks.md @@ -401,10 +401,10 @@ $ echo "Spam & Eggs" ## Entire page -Add the page configuration option `useLegacyCodeBlocks: true` to the top of the page. To learn more about page configuration options, see [USAGE_ADVANCED.md#page-configuration-options](https://github.com/eecs485staff/primer-spec/blob/develop/docs/USAGE_ADVANCED.md#page-configuration-options). +Add the page configuration option `defaultCodeblockVariant: legacy` to the top of the page. To learn more about page configuration options, see [USAGE_ADVANCED.md#page-configuration-options](https://github.com/eecs485staff/primer-spec/blob/develop/docs/USAGE_ADVANCED.md#page-configuration-options). -If you have set the [site-wide](#entire-site) configuration option to use legacy code blocks, you can override the setting for a single page by settings `useLegacyCodeBlocks: false` at the top of the page. +If you have set the [site-wide](#entire-site) configuration option to use legacy code blocks, you can override the setting for a single page by settings `defaultCodeblockVariant: enhanced` at the top of the page. ## Entire site -Add the site-wide configuration option `useLegacyCodeBlocks: true` under the `primerSpec` settings in `_config.yml`. To learn more about site configuration options, see [USAGE_ADVANCED.md#site-configuration-options](https://github.com/eecs485staff/primer-spec/blob/develop/docs/USAGE_ADVANCED.md#site-configuration-options). +Add the site-wide configuration option `defaultCodeblockVariant: legacy` under the `primerSpec` settings in `_config.yml`. To learn more about site configuration options, see [USAGE_ADVANCED.md#site-configuration-options](https://github.com/eecs485staff/primer-spec/blob/develop/docs/USAGE_ADVANCED.md#site-configuration-options). diff --git a/demo/page-configuration-options.md b/demo/page-configuration-options.md index f5dd21fd..69f967fc 100644 --- a/demo/page-configuration-options.md +++ b/demo/page-configuration-options.md @@ -2,7 +2,9 @@ layout: spec disableSidebar: true -useLegacyCodeBlocks: true +defaultCodeblockVariant: legacy +# ^ This is equivalent to the following. +# useLegacyCodeBlocks: true --- # Page Configuration Options @@ -17,7 +19,7 @@ This boolean indicates whether the sidebar with Table of Contents should be show This configuration option is useful for small pages, or for pages with few headings. (On such pages, a Sidebar may not be useful, or might hamper the reading experience.) -### `useLegacyCodeBlocks: true` +### `defaultCodeblockVariant: legacy` This boolean indicates whether code blocks should _not_ be enhanced on the page. (By default, [code blocks are enhanced](https://eecs485staff.github.io/primer-spec/demo/enhanced-code-blocks.html) by Primer Spec.) diff --git a/docs/USAGE_ADVANCED.md b/docs/USAGE_ADVANCED.md index 450787a4..04249aab 100644 --- a/docs/USAGE_ADVANCED.md +++ b/docs/USAGE_ADVANCED.md @@ -23,12 +23,12 @@ See the [Primer Spec README](../README.md) for the main usage instructions. This - [`latex`: Boolean](#latex-boolean) - [`mermaid`: Boolean](#mermaid-boolean) - [mermaid: true](#mermaid-true) - - [`useLegacyCodeBlocks`: Boolean](#uselegacycodeblocks-boolean) + - [`defaultCodeblockVariant`: CodeblockVariant (String)](#defaultcodeblockvariant-codeblockvariant-string) - [`excludeFromSitemap`: Boolean](#excludefromsitemap-boolean) - [Site configuration options](#site-configuration-options) - [`defaultSubthemeName`: String](#defaultsubthemename-string) - [`defaultSubthemeMode`: String](#defaultsubthememode-string) - - [`useLegacyCodeBlocks`: Boolean](#uselegacycodeblocks-boolean-1) + - [`defaultCodeblockVariant`: CodeblockVariant (String)](#defaultcodeblockvariant-codeblockvariant-string-1) - [`sitemap`: Boolean | {label: String}](#sitemap-boolean--label-string) - [Pinning to a specific version](#pinning-to-a-specific-version) - [Using without Jekyll](#using-without-jekyll) @@ -287,9 +287,14 @@ graph TD; Check out the [demo](https://eecs485staff.github.io/primer-spec/demo/mermaid-diagrams.html) for inspiration and for links to Mermaid's syntax documentation. -#### `useLegacyCodeBlocks`: Boolean +#### `defaultCodeblockVariant`: CodeblockVariant (String) -Opt out of ["enhancing" code blocks](#enhanced-code-blocks) on the entire page. See an example of the "legacy" style code block in the [demo](../demo/enhanced-code-blocks.md#legacy-style-opt-out). +Choose the default codeblock variant to use. Valid codeblock variants are: + +- `enhanced` (default) +- `legacy` + +Use `legacy` to opt out of ["enhancing" code blocks](#enhanced-code-blocks) on the entire page. See an example of the "legacy" style code block in the [demo](../demo/enhanced-code-blocks.md#legacy-style-opt-out). This setting can be overriden per-block. @@ -335,11 +340,16 @@ Specify the default subtheme name. This subtheme will be applied for first-time Specify the default subtheme mode. This subtheme will be applied for first-time site visitors. Defaults to `system`. -#### `useLegacyCodeBlocks`: Boolean +#### `defaultCodeblockVariant`: CodeblockVariant (String) + +Choose the default codeblock variant to use. Valid codeblock variants are: -Opt out of ["enhancing" code blocks](#enhanced-code-blocks) on all pages in the entire site. See an example of the "legacy" style code block in the [demo](../demo/enhanced-code-blocks.md#legacy-style-opt-out). +- `enhanced` (default) +- `legacy` -This setting can be overriden per-page or per-block. +Use `legacy` to opt out of ["enhancing" code blocks](#enhanced-code-blocks) on the entire page. See an example of the "legacy" style code block in the [demo](../demo/enhanced-code-blocks.md#legacy-style-opt-out). + +This setting can be overriden per-block. #### `sitemap`: Boolean | {label: String} diff --git a/src_js/Config.ts b/src_js/Config.ts index 83bacfc7..9682d87a 100644 --- a/src_js/Config.ts +++ b/src_js/Config.ts @@ -1,4 +1,5 @@ import Storage from './utils/Storage'; +import { CodeblockVariant } from './components/main_content/types'; const SUBTHEME_NAME_STORAGE_KEY = 'spec_subtheme_name'; const SUBTHEME_MODE_STORAGE_KEY = 'spec_subtheme_mode'; @@ -32,6 +33,7 @@ export default { SITEMAP_URLS: window.PrimerSpecConfig.sitemapUrls || [], SITEMAP_LABEL: window.PrimerSpecConfig.sitemapLabel || 'Supplemental Pages', SITEMAP_SITE_TITLE: window.PrimerSpecConfig.sitemapSiteTitle || '', + DEFAULT_CODEBLOCK_VARIANT: getDefaultCodeblockVariant(), USE_LEGACY_CODE_BLOCKS: window.PrimerSpecConfig.useLegacyCodeBlocks || false, // Other constants @@ -72,3 +74,14 @@ function getInitSitemapEnabled() { return !!window.PrimerSpecConfig.sitemapEnabled; } + +function getDefaultCodeblockVariant(): CodeblockVariant { + if (window.PrimerSpecConfig.useLegacyCodeBlocks === true) { + return CodeblockVariant.LEGACY; + } + const maybeVariant = window.PrimerSpecConfig.defaultCodeblockVariant?.toLowerCase() as CodeblockVariant | null; + if (maybeVariant && Object.values(CodeblockVariant).includes(maybeVariant)) { + return maybeVariant; + } + return CodeblockVariant.ENHANCED; +} diff --git a/src_js/components/main_content/types.ts b/src_js/components/main_content/types.ts new file mode 100644 index 00000000..202aa7b9 --- /dev/null +++ b/src_js/components/main_content/types.ts @@ -0,0 +1,4 @@ +export enum CodeblockVariant { + ENHANCED = 'enhanced', + LEGACY = 'legacy', +} diff --git a/src_js/components/main_content/useEnhancedCodeBlocks.tsx b/src_js/components/main_content/useEnhancedCodeBlocks.tsx index a3a044f8..bc28698e 100644 --- a/src_js/components/main_content/useEnhancedCodeBlocks.tsx +++ b/src_js/components/main_content/useEnhancedCodeBlocks.tsx @@ -3,8 +3,9 @@ import { RefObject } from 'preact'; import * as JSXDom from 'jsx-dom'; import clsx from 'clsx'; import AnchorJS from 'anchor-js'; -import Config from '../../Config'; import slugify from '@sindresorhus/slugify'; +import Config from '../../Config'; +import { CodeblockVariant } from './types'; const CODEBLOCK_LINE_CLASS = 'primer-spec-code-block-line-code'; // We use the following class to ensure that we don't double-process code @@ -177,13 +178,21 @@ function enhanceBlocks( } function shouldRetainLegacyCodeBlock(codeblock: HTMLElement): boolean { - if (codeblock.dataset['variant'] != null) { - return codeblock.dataset['variant'] === 'legacy'; - } + // Don't mess with Mermaid blocks, they'll be handled by the Mermaid plugin. if (codeblock.querySelector('.language-mermaid') != null) { return true; } - return Config.USE_LEGACY_CODE_BLOCKS; + return getCodeblockVariant(codeblock) === CodeblockVariant.LEGACY; +} + +function getCodeblockVariant(codeblock: HTMLElement): CodeblockVariant { + const rawVariant = codeblock.dataset[ + 'variant' + ]?.toLowerCase() as CodeblockVariant | null; + if (rawVariant && Object.values(CodeblockVariant).includes(rawVariant)) { + return rawVariant as CodeblockVariant; + } + return Config.DEFAULT_CODEBLOCK_VARIANT; } function createEnhancedCodeBlock( diff --git a/src_js/global.d.ts b/src_js/global.d.ts index a4f6529d..9d26d34a 100644 --- a/src_js/global.d.ts +++ b/src_js/global.d.ts @@ -9,7 +9,8 @@ declare var PrimerSpecConfig: { sitemapLabel?: string; sitemapEnabled?: boolean; sitemapSiteTitle?: string; - useLegacyCodeBlocks?: boolean; + useLegacyCodeBlocks?: boolean /* DEPRECATED */; + defaultCodeblockVariant?: string; }; // Other global types From 237c7db9a2f10f264a1bb877ddd4375c59d0813e Mon Sep 17 00:00:00 2001 From: Sesh Sadasivam Date: Mon, 11 Apr 2022 22:33:28 -0700 Subject: [PATCH 2/3] Add new code-block variant to hide line numbers --- _sass/spec/base.scss | 25 +++--- demo/enhanced-code-blocks.md | 78 +++++++++++++++---- src_js/components/main_content/types.ts | 1 + .../main_content/useEnhancedCodeBlocks.tsx | 77 ++++++++++++------ 4 files changed, 130 insertions(+), 51 deletions(-) diff --git a/_sass/spec/base.scss b/_sass/spec/base.scss index 12022ca3..896f75aa 100644 --- a/_sass/spec/base.scss +++ b/_sass/spec/base.scss @@ -686,22 +686,25 @@ div.primer-spec-callout { } td.primer-spec-code-block-line-number { - width: 1%; - min-width: 50px; - color: var(--code-block-line-number-color); - text-align: right; - white-space: nowrap; - vertical-align: top; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; - &::before { - content: attr(data-line-number); - } - &:hover { - color: var(--code-block-default-color); + + &.primer-spec-code-block-line-numbers-shown { + width: 1%; + min-width: 50px; + color: var(--code-block-line-number-color); + text-align: right; + white-space: nowrap; + vertical-align: top; + &::before { + content: attr(data-line-number); + } + &:hover { + color: var(--code-block-default-color); + } } } diff --git a/demo/enhanced-code-blocks.md b/demo/enhanced-code-blocks.md index 38641fad..778cd9a2 100644 --- a/demo/enhanced-code-blocks.md +++ b/demo/enhanced-code-blocks.md @@ -358,24 +358,20 @@ OCT77770 OCT 77770 # DONT MOVE -# Legacy Style (Opt Out) +# Variants -Here's what the "legacy" style code block looks like: +The default code block style should work for most use cases. However, you might want to show text/code in a different style, for instance, with no line numbers. - -```console -$ echo "Spam & Eggs" -``` -{: data-variant="legacy" } - +Primer Spec supports three different styles (aka 'variants') of code blocks: +- **`enhanced` (default)**: This is the style you've seen in all of the above demos. +- [**`no-line-numbers`**](#no-line-numbers): Like `enhanced`, but the line numbers are not shown. +- [**`legacy`**](#legacy): This is the original style of code blocks from the original [GitHub Primer theme](https://github.com/pages-themes/primer). -In my opinion, the legacy style works best with single-line code blocks. +## Using variants -If you'd like to revert to using the "legacy" style, decide whether you'd like to revert a single code block or all code blocks in the page or in the site. +### Single code block -## Single code block - -Add the attribute `{: data-variant="legacy" }` to the code block. For instance: +Add the attribute `{: data-variant="" }` to the code block. For instance: ````markdown @@ -399,12 +395,64 @@ $ echo "Spam & Eggs" ```` -## Entire page +### Entire page Add the page configuration option `defaultCodeblockVariant: legacy` to the top of the page. To learn more about page configuration options, see [USAGE_ADVANCED.md#page-configuration-options](https://github.com/eecs485staff/primer-spec/blob/develop/docs/USAGE_ADVANCED.md#page-configuration-options). If you have set the [site-wide](#entire-site) configuration option to use legacy code blocks, you can override the setting for a single page by settings `defaultCodeblockVariant: enhanced` at the top of the page. -## Entire site +### Entire site Add the site-wide configuration option `defaultCodeblockVariant: legacy` under the `primerSpec` settings in `_config.yml`. To learn more about site configuration options, see [USAGE_ADVANCED.md#site-configuration-options](https://github.com/eecs485staff/primer-spec/blob/develop/docs/USAGE_ADVANCED.md#site-configuration-options). + +## Variant Demos + +### `no-line-numbers` + +Like `enhanced`, but the line numbers are not shown. + + +```plaintext +On the far-away island of Sala-ma-Sond, +Yertle the Turtle was king of the pond. +A nice little pond. It was clean. It was neat. +The water was warm. There was plenty to eat. +The turtles had everything turtles might need. +And they were all happy. Quite happy indeed. +``` +{: data-variant="no-line-numbers" } + + + +
+ Source code for this code block with no-line-numbers + + ````markdown +```plaintext +On the far-away island of Sala-ma-Sond, +Yertle the Turtle was king of the pond. +A nice little pond. It was clean. It was neat. +The water was warm. There was plenty to eat. +The turtles had everything turtles might need. +And they were all happy. Quite happy indeed. +``` +{: data-variant="no-line-numbers" } +```` + {: data-highlight="9" data-title="markdown" } +
+ + +### `legacy` + +This is the original style of code blocks from the original [GitHub Primer theme](https://github.com/pages-themes/primer). + + +```console +$ echo "Spam & Eggs" +``` +{: data-variant="legacy" } + + +In my opinion, the legacy style works best with single-line code blocks. + +If you'd like to revert to using the "legacy" style, decide whether you'd like to revert a single code block or all code blocks in the page or in the site. diff --git a/src_js/components/main_content/types.ts b/src_js/components/main_content/types.ts index 202aa7b9..ba312952 100644 --- a/src_js/components/main_content/types.ts +++ b/src_js/components/main_content/types.ts @@ -1,4 +1,5 @@ export enum CodeblockVariant { ENHANCED = 'enhanced', + NO_LINE_NUMBERS = 'no-line-numbers', LEGACY = 'legacy', } diff --git a/src_js/components/main_content/useEnhancedCodeBlocks.tsx b/src_js/components/main_content/useEnhancedCodeBlocks.tsx index bc28698e..f276bbc3 100644 --- a/src_js/components/main_content/useEnhancedCodeBlocks.tsx +++ b/src_js/components/main_content/useEnhancedCodeBlocks.tsx @@ -150,14 +150,16 @@ function enhanceBlocks( ? createCodeBlockAnchorId(codeblockNumericId, title) : null; - const enhancedCodeBlock = createEnhancedCodeBlock( + const enhancedCodeBlock = createEnhancedCodeBlock({ codeblockNumericId, - codeblockContents, - getCodeBlockLanguage(codeblock), - codeblock.dataset['highlight'] || null, + rawContent: codeblockContents, + language: getCodeBlockLanguage(codeblock), + rawHighlightRanges: codeblock.dataset['highlight'] || null, title, anchorId, - ); + showLineNumbers: + getCodeblockVariant(codeblock) !== CodeblockVariant.NO_LINE_NUMBERS, + }); if (!enhancedCodeBlock) { return; } @@ -195,14 +197,25 @@ function getCodeblockVariant(codeblock: HTMLElement): CodeblockVariant { return Config.DEFAULT_CODEBLOCK_VARIANT; } -function createEnhancedCodeBlock( - codeblockNumericId: number, - rawContent: string, - language: string | null, - rawHighlightRanges: string | null, - title?: string | null, - anchorId?: string | null, -): HTMLElement | null { +function createEnhancedCodeBlock(options: { + codeblockNumericId: number; + rawContent: string; + language: string | null; + rawHighlightRanges: string | null; + title?: string | null; + anchorId?: string | null; + showLineNumbers: boolean; +}): HTMLElement | null { + const { + codeblockNumericId, + rawContent, + language, + rawHighlightRanges, + title, + anchorId, + showLineNumbers, + } = options; + const lines = rawContent.split('\n'); if (lines.length === 0) { console.warn('useEnhancedCodeBlocks: Code Block appears to have no lines!'); @@ -259,13 +272,14 @@ function createEnhancedCodeBlock( }} > {lines.map((line, lineNumber) => - createCodeBlockLine( + createCodeBlockLine({ codeblockId, language, line, - lineNumber + 1, - highlightRanges.has(lineNumber + 1), - ), + lineNumber: lineNumber + 1, + shouldHighlight: highlightRanges.has(lineNumber + 1), + showLineNumbers, + }), )} @@ -276,13 +290,23 @@ function createEnhancedCodeBlock( return enhancedCodeBlock as HTMLElement; } -function createCodeBlockLine( - codeblockId: string, - language: string | null, - line: string, - lineNumber: number, - shouldHighlight: boolean, -): HTMLElement { +function createCodeBlockLine(options: { + codeblockId: string; + language: string | null; + line: string; + lineNumber: number; + shouldHighlight: boolean; + showLineNumbers: boolean; +}): HTMLElement { + const { + codeblockId, + language, + line, + lineNumber, + shouldHighlight, + showLineNumbers, + } = options; + const L_ID = `${codeblockId}-L${lineNumber}`; const LC_ID = `${codeblockId}-LC${lineNumber}`; const LR_ID = `${codeblockId}-LR${lineNumber}`; @@ -291,7 +315,10 @@ function createCodeBlockLine( {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions */} { e.preventDefault(); From d5374d37233fdea56e6866302bb717ea4c826a81 Mon Sep 17 00:00:00 2001 From: Sesh Sadasivam Date: Tue, 12 Apr 2022 21:05:38 -0700 Subject: [PATCH 3/3] Insert deprecation notices for 'useLegacyCodeBlocks' config option --- _config.yml | 2 +- _layouts/spec.html | 2 +- src_js/Config.ts | 7 ++++++- src_js/global.d.ts | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/_config.yml b/_config.yml index 38d862f5..472ed012 100644 --- a/_config.yml +++ b/_config.yml @@ -19,7 +19,7 @@ primerSpec: # sitemap: true # sitemap: # label: Demo pages -# useLegacyCodeBlocks: true +# defaultCodeblockVariant: no-line-numbers sass: style: :compressed diff --git a/_layouts/spec.html b/_layouts/spec.html index 91933801..5eaf0b41 100644 --- a/_layouts/spec.html +++ b/_layouts/spec.html @@ -90,7 +90,7 @@ option. {%- endcomment -%} {%- comment -%} - `useLegacyCodeBlocks` is DEPRECATED. + `useLegacyCodeBlocks` is DEPRECATED starting from v1.7.0 {%- endcomment -%} {% assign useLegacyCodeBlocks = page.useLegacyCodeBlocks %} {%- if useLegacyCodeBlocks == nil -%} diff --git a/src_js/Config.ts b/src_js/Config.ts index 9682d87a..e9add9d9 100644 --- a/src_js/Config.ts +++ b/src_js/Config.ts @@ -34,7 +34,10 @@ export default { SITEMAP_LABEL: window.PrimerSpecConfig.sitemapLabel || 'Supplemental Pages', SITEMAP_SITE_TITLE: window.PrimerSpecConfig.sitemapSiteTitle || '', DEFAULT_CODEBLOCK_VARIANT: getDefaultCodeblockVariant(), - USE_LEGACY_CODE_BLOCKS: window.PrimerSpecConfig.useLegacyCodeBlocks || false, + + // DEPRECATED in v1.7.0. Use `DEFAULT_CODEBLOCK_VARIANT` instead. + USE_LEGACY_CODE_BLOCKS_DEPRECATED_DO_NOT_USE: + window.PrimerSpecConfig.useLegacyCodeBlocks || false, // Other constants PRIMER_SPEC_APP_NODE_ID: 'primer-spec-app-container', @@ -77,6 +80,8 @@ function getInitSitemapEnabled() { function getDefaultCodeblockVariant(): CodeblockVariant { if (window.PrimerSpecConfig.useLegacyCodeBlocks === true) { + // Note that `useLegacyCodeBlocks` is deprecated in v1.7.0. This code + // just ensures backwards-compatibility. return CodeblockVariant.LEGACY; } const maybeVariant = window.PrimerSpecConfig.defaultCodeblockVariant?.toLowerCase() as CodeblockVariant | null; diff --git a/src_js/global.d.ts b/src_js/global.d.ts index 9d26d34a..28872c13 100644 --- a/src_js/global.d.ts +++ b/src_js/global.d.ts @@ -9,7 +9,7 @@ declare var PrimerSpecConfig: { sitemapLabel?: string; sitemapEnabled?: boolean; sitemapSiteTitle?: string; - useLegacyCodeBlocks?: boolean /* DEPRECATED */; + useLegacyCodeBlocks?: boolean /* DEPRECATED in v1.7.0 */; defaultCodeblockVariant?: string; };