aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-03-23 22:05:30 +0100
committerArmand Philippot <git@armandphilippot.com>2022-03-24 15:01:03 +0100
commit9226671f49b507ce6f71e6e2c3621014f05f74e9 (patch)
tree73a148d12ceebbf0d8a95b82353d3d84f6a7a76a
parent4e7a96c5a831882463802cdd4f84fe1464969cb0 (diff)
refactor: load prism plugins without babel
-rw-r--r--.babelrc52
-rw-r--r--src/components/MDX/CodeBlock/CodeBlock.tsx81
-rw-r--r--src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx2
m---------src/content0
-rw-r--r--src/pages/_app.tsx2
-rw-r--r--src/pages/article/[slug].tsx58
-rw-r--r--src/pages/projet/[slug].tsx1
-rw-r--r--src/styles/vendors/_prism.scss28
-rw-r--r--src/ts/types/prism.ts51
-rw-r--r--src/utils/helpers/prism.ts21
-rw-r--r--src/utils/providers/prism-theme.tsx (renamed from src/utils/providers/prism.tsx)8
11 files changed, 178 insertions, 126 deletions
diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index 657e285..0000000
--- a/.babelrc
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "presets": ["next/babel"],
- "plugins": [
- [
- "prismjs",
- {
- "languages": [
- "apacheconf",
- "bash",
- "css",
- "diff",
- "docker",
- "editorconfig",
- "ejs",
- "git",
- "html",
- "ignore",
- "ini",
- "javascript",
- "jsdoc",
- "json",
- "jsx",
- "makefile",
- "markup",
- "php",
- "phpdoc",
- "regex",
- "scss",
- "shell-session",
- "smarty",
- "tcl",
- "toml",
- "tsx",
- "twig",
- "yaml"
- ],
- "plugins": [
- "command-line",
- "copy-to-clipboard",
- "diff-highlight",
- "inline-color",
- "line-highlight",
- "line-numbers",
- "match-braces",
- "normalize-whitespace",
- "show-language",
- "toolbar"
- ]
- }
- ]
- ]
-}
diff --git a/src/components/MDX/CodeBlock/CodeBlock.tsx b/src/components/MDX/CodeBlock/CodeBlock.tsx
index 69f0124..c330063 100644
--- a/src/components/MDX/CodeBlock/CodeBlock.tsx
+++ b/src/components/MDX/CodeBlock/CodeBlock.tsx
@@ -1,28 +1,25 @@
+import {
+ PrismDefaultPlugins,
+ PrismLanguages,
+ PrismPlugins,
+} from '@ts/types/prism';
+import { usePrismTheme } from '@utils/providers/prism-theme';
import { useRouter } from 'next/router';
import Prism from 'prismjs';
-import { ReactChildren, useEffect } from 'react';
+import { useCallback, useEffect, useMemo } from 'react';
import { useIntl } from 'react-intl';
-import '@utils/plugins/prism-color-scheme';
-import { usePrismTheme } from '@utils/providers/prism';
const CodeBlock = ({
- className,
- children,
+ code,
+ language,
+ plugins,
}: {
- className: string;
- children: ReactChildren;
+ code: string;
+ language: PrismLanguages;
+ plugins: PrismPlugins[];
}) => {
- const classNames = className.split('+');
- const languageClass = classNames.find((name: string) =>
- name.startsWith('language-')
- );
const intl = useIntl();
const router = useRouter();
-
- useEffect(() => {
- Prism.highlightAll();
- }, []);
-
const { setCodeBlocks } = usePrismTheme();
useEffect(() => {
@@ -32,6 +29,46 @@ const CodeBlock = ({
setCodeBlocks(allPre);
}, [setCodeBlocks, router.asPath]);
+ const defaultPlugins: PrismDefaultPlugins[] = useMemo(
+ () => [
+ 'autoloader',
+ 'toolbar',
+ 'show-language',
+ 'copy-to-clipboard',
+ 'color-scheme',
+ 'match-braces',
+ 'normalize-whitespace',
+ ],
+ []
+ );
+
+ const loadPrismPlugins = useCallback(
+ async (prismPlugins: (PrismDefaultPlugins | PrismPlugins)[]) => {
+ for (const plugin of prismPlugins) {
+ try {
+ if (plugin === 'color-scheme') {
+ await import(`@utils/plugins/prism-${plugin}`);
+ } else {
+ await import(`prismjs/plugins/${plugin}/prism-${plugin}.min.js`);
+
+ if (plugin === 'autoloader')
+ Prism.plugins.autoloader.languages_path = '/prism/';
+ }
+ } catch (error) {
+ console.error('CodeBlock: an error occurred with Prism.');
+ console.error(error);
+ }
+ }
+ },
+ []
+ );
+
+ useEffect(() => {
+ loadPrismPlugins([...defaultPlugins, ...plugins]).then(() => {
+ Prism.highlightAll();
+ });
+ }, [loadPrismPlugins, defaultPlugins, plugins]);
+
const copyText = intl.formatMessage({
defaultMessage: 'Copy',
description: 'Prism: copy button text (no clicked)',
@@ -58,18 +95,20 @@ const CodeBlock = ({
id: 'Ua2g2p',
});
+ const defaultPluginsClasses = 'match-braces';
+ const pluginsClasses = plugins.join(' ');
+
return (
- <div
+ <pre
+ className={`language-${language} ${defaultPluginsClasses} ${pluginsClasses}`}
data-prismjs-copy={copyText}
data-prismjs-copy-success={copiedText}
data-prismjs-copy-error={errorText}
data-prismjs-color-scheme-dark={darkTheme}
data-prismjs-color-scheme-light={lightTheme}
>
- <pre className={classNames.join(' ')}>
- <code className={languageClass}>{children}</code>
- </pre>
- </div>
+ <code className={`language-${language}`}>{code}</code>
+ </pre>
);
};
diff --git a/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx b/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx
index 9707097..20ad267 100644
--- a/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx
+++ b/src/components/Settings/PrismThemeToggle/PrismThemeToggle.tsx
@@ -1,7 +1,7 @@
import { Toggle } from '@components/FormElements';
import { MoonIcon, SunIcon } from '@components/Icons';
import Spinner from '@components/Spinner/Spinner';
-import { usePrismTheme } from '@utils/providers/prism';
+import { usePrismTheme } from '@utils/providers/prism-theme';
import { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
diff --git a/src/content b/src/content
-Subproject b5aa522476547db4efa2d6c8e774ca0422ef654
+Subproject 52c97a48f39ef0de9a61d2cf120fae2c7079055
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index e8c00de..84c2469 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,7 +1,7 @@
import { AppPropsWithLayout } from '@ts/types/app';
import { settings } from '@utils/config';
import { AckeeProvider } from '@utils/providers/ackee';
-import { PrismThemeProvider } from '@utils/providers/prism';
+import { PrismThemeProvider } from '@utils/providers/prism-theme';
import { ThemeProvider } from 'next-themes';
import { useRouter } from 'next/router';
import { IntlProvider } from 'react-intl';
diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx
index 41b84b6..27a6f7b 100644
--- a/src/pages/article/[slug].tsx
+++ b/src/pages/article/[slug].tsx
@@ -14,21 +14,20 @@ import {
import styles from '@styles/pages/Page.module.scss';
import { NextPageWithLayout } from '@ts/types/app';
import { ArticleMeta, ArticleProps } from '@ts/types/articles';
+import { PrismDefaultPlugins, PrismPlugins } from '@ts/types/prism';
import { settings } from '@utils/config';
import { getFormattedPaths } from '@utils/helpers/format';
import { loadTranslation } from '@utils/helpers/i18n';
import { addPrismClasses } from '@utils/helpers/prism';
-import { usePrismTheme } from '@utils/providers/prism';
import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next';
import Head from 'next/head';
import { useRouter } from 'next/router';
-import { highlightAll } from 'prismjs';
+import Script from 'next/script';
+import Prism from 'prismjs';
import { ParsedUrlQuery } from 'querystring';
-import { useEffect } from 'react';
+import { useCallback, useEffect, useMemo } from 'react';
import { useIntl } from 'react-intl';
import { Blog, BlogPosting, Graph, WebPage } from 'schema-dts';
-import '@utils/plugins/prism-color-scheme';
-import Script from 'next/script';
const SingleArticle: NextPageWithLayout<ArticleProps> = ({
comments,
@@ -37,19 +36,48 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({
const intl = useIntl();
const router = useRouter();
- useEffect(() => {
- addPrismClasses();
- highlightAll();
- });
+ const loadPrismPlugins = useCallback(
+ async (prismPlugins: (PrismDefaultPlugins | PrismPlugins)[]) => {
+ for (const plugin of prismPlugins) {
+ try {
+ if (plugin === 'color-scheme') {
+ await import(`@utils/plugins/prism-${plugin}`);
+ } else {
+ await import(`prismjs/plugins/${plugin}/prism-${plugin}.min.js`);
- const { setCodeBlocks } = usePrismTheme();
+ if (plugin === 'autoloader')
+ Prism.plugins.autoloader.languages_path = '/prism/';
+ }
+ } catch (error) {
+ console.error('Article: an error occurred with Prism.');
+ console.error(error);
+ }
+ }
+ },
+ []
+ );
+
+ const plugins: (PrismDefaultPlugins | PrismPlugins)[] = useMemo(
+ () => [
+ 'autoloader',
+ 'toolbar',
+ 'show-language',
+ 'copy-to-clipboard',
+ 'color-scheme',
+ 'command-line',
+ 'line-numbers',
+ 'match-braces',
+ 'normalize-whitespace',
+ ],
+ []
+ );
useEffect(() => {
- const allPre: NodeListOf<HTMLPreElement> = document.querySelectorAll(
- 'pre[data-prismjs-color-scheme-current]'
- );
- setCodeBlocks(allPre);
- }, [setCodeBlocks, router.asPath]);
+ loadPrismPlugins(plugins).then(() => {
+ addPrismClasses();
+ Prism.highlightAll();
+ });
+ }, [plugins, loadPrismPlugins]);
if (router.isFallback) return <Spinner />;
diff --git a/src/pages/projet/[slug].tsx b/src/pages/projet/[slug].tsx
index b9a8f39..1f09fed 100644
--- a/src/pages/projet/[slug].tsx
+++ b/src/pages/projet/[slug].tsx
@@ -41,6 +41,7 @@ const Project: NextPageWithLayout<ProjectProps> = ({
};
const components: NestedMDXComponents = {
+ CodeBlock: (props) => CodeBlock(props),
Gallery: (props) => Gallery(props),
Image: (props) => ResponsiveImage({ caption: props.caption, ...props }),
Link: (props) => Link(props),
diff --git a/src/styles/vendors/_prism.scss b/src/styles/vendors/_prism.scss
index 2882835..7c05c9f 100644
--- a/src/styles/vendors/_prism.scss
+++ b/src/styles/vendors/_prism.scss
@@ -43,18 +43,6 @@
}
.toolbar-item:nth-child(1) {
- grid-column: 2;
- grid-row: 1;
- margin: 0 var(--spacing-2xs);
-
- @include mix.media("screen") {
- @include mix.dimensions("2xs") {
- order: 2;
- }
- }
- }
-
- .toolbar-item:nth-child(2) {
grid-column: 1;
grid-row: 1 / 3;
margin-right: auto;
@@ -64,24 +52,18 @@
color: var(--color-primary-darker);
font-size: var(--font-size-sm);
font-weight: 600;
+ }
- @include mix.media("screen") {
- @include mix.dimensions("2xs") {
- order: 1;
- }
- }
+ .toolbar-item:nth-child(2) {
+ grid-column: 2;
+ grid-row: 1;
+ margin: 0 var(--spacing-2xs);
}
.toolbar-item:nth-child(3) {
grid-column: 2;
grid-row: 2;
margin: 0 var(--spacing-2xs);
-
- @include mix.media("screen") {
- @include mix.dimensions("2xs") {
- order: 3;
- }
- }
}
}
diff --git a/src/ts/types/prism.ts b/src/ts/types/prism.ts
new file mode 100644
index 0000000..663bc08
--- /dev/null
+++ b/src/ts/types/prism.ts
@@ -0,0 +1,51 @@
+export type PrismLanguages =
+ | 'apacheconf'
+ | 'bash'
+ | 'css'
+ | 'diff'
+ | 'docker'
+ | 'editorconfig'
+ | 'ejs'
+ | 'git'
+ | 'graphql'
+ | 'html'
+ | 'ignore'
+ | 'ini'
+ | 'javascript'
+ | 'jsdoc'
+ | 'json'
+ | 'jsx'
+ | 'makefile'
+ | 'markup'
+ | 'php'
+ | 'phpdoc'
+ | 'regex'
+ | 'scss'
+ | 'shell-session'
+ | 'smarty'
+ | 'tcl'
+ | 'toml'
+ | 'tsx'
+ | 'twig'
+ | 'yaml';
+
+export type PrismDefaultPlugins =
+ | 'autoloader'
+ | 'color-scheme'
+ | 'copy-to-clipboard'
+ | 'match-braces'
+ | 'normalize-whitespace'
+ | 'show-language'
+ | 'toolbar';
+
+export type PrismPlugins =
+ | 'command-line'
+ | 'diff-highlight'
+ | 'inline-color'
+ | 'line-highlight'
+ | 'line-numbers';
+
+export type PrismProviderProps = {
+ language: PrismLanguages;
+ plugins: PrismPlugins[];
+};
diff --git a/src/utils/helpers/prism.ts b/src/utils/helpers/prism.ts
index bc84c91..a5f5787 100644
--- a/src/utils/helpers/prism.ts
+++ b/src/utils/helpers/prism.ts
@@ -17,19 +17,18 @@ export const addPrismClasses = () => {
const preTags = document.getElementsByTagName('pre');
Array.from(preTags).forEach((preTag) => {
- if (
- isLanguageBlock(preTag.classList) &&
- !preTag.classList.contains('command-line') &&
- !preTag.classList.contains('language-diff')
- ) {
- preTag.classList.add('line-numbers', 'match-braces');
- }
+ if (!isLanguageBlock(preTag.classList)) return;
+
+ preTag.classList.add('match-braces');
- if (
- preTag.classList.contains('command-line') &&
- preTag.classList.contains('filter-output')
- ) {
+ if (preTag.classList.contains('filter-output')) {
preTag.setAttribute('data-filter-output', '#output#');
}
+
+ if (preTag.classList.contains('language-bash')) {
+ preTag.classList.add('command-line');
+ } else if (!preTag.classList.contains('language-diff')) {
+ preTag.classList.add('line-numbers');
+ }
});
};
diff --git a/src/utils/providers/prism.tsx b/src/utils/providers/prism-theme.tsx
index 7a4221d..2ed8454 100644
--- a/src/utils/providers/prism.tsx
+++ b/src/utils/providers/prism-theme.tsx
@@ -28,8 +28,12 @@ export type PrismThemeProviderProps = {
export const PrismThemeContext = createContext<UsePrismThemeProps>({
themes: ['dark', 'light', 'system'],
- setTheme: (_) => {},
- setCodeBlocks: (_) => {},
+ setTheme: (_) => {
+ // This is intentional.
+ },
+ setCodeBlocks: (_) => {
+ // This is intentional.
+ },
});
export const usePrismTheme = () => useContext(PrismThemeContext);