123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- import { appFilters } from "../shared/e11ty/filters.mjs"
- import { appData } from "../shared/e11ty/data.mjs";
- import { readFileSync, existsSync } from 'node:fs';
- import { fileURLToPath } from 'node:url'
- import { join, dirname } from 'node:path';
- import beautify from 'js-beautify';
- const shiki = await import('shiki');
- import { createCssVariablesTheme } from 'shiki/core'
- const __dirname = dirname(fileURLToPath(import.meta.url))
- export default function (eleventyConfig) {
- const environment = process.env.NODE_ENV || "production";
- appFilters(eleventyConfig);
- appData(eleventyConfig);
- eleventyConfig.addPassthroughCopy({
- "node_modules/@tabler/core/dist": "dist",
- "public": "/",
- "static": "static",
- });
- eleventyConfig.addCollection('docs', collection => {
- return [...collection.getFilteredByGlob('./content/**/*.md')].sort((a, b) => {
- return a.data.title - b.data.title;
- });
- });
- eleventyConfig.setInputDirectory("content");
- eleventyConfig.setOutputDirectory("dist");
- eleventyConfig.setLayoutsDirectory("../../shared/layouts");
- eleventyConfig.setIncludesDirectory("../../shared/includes");
- eleventyConfig.setDataDirectory("../../shared/data");
- eleventyConfig.amendLibrary('md', () => { });
- eleventyConfig.addShortcode('scss-docs', function (name, filename) {
- const file = join(__dirname, `../core/scss/${filename}`)
- if (existsSync(file)) {
- const content = readFileSync(file, 'utf8');
- const regex = new RegExp(`\/\/\\sscss-docs-start\\s${name}\\n(.+?)\/\/\\sscss-docs-end`, 'gs')
- const m = content.matchAll(regex)
- if (m) {
- const matches = [...m]
- if (matches[0] && matches[0][1]) {
- const lines = matches[0][1].split('\n');
- // Find minimum number of leading spaces in non-empty lines
- const minIndent = lines
- .filter(line => line.trim().length > 0)
- .reduce((min, line) => {
- const match = line.match(/^(\s*)/);
- const leadingSpaces = match ? match[1].length : 0;
- return Math.min(min, leadingSpaces);
- }, Infinity);
- // Remove that many spaces from the start of each line
- const result = lines.map(line => line.startsWith(' '.repeat(minIndent))
- ? line.slice(minIndent)
- : line).join('\n');
- return "\n```scss\n" + result.trimRight() + "\n```\n"
- }
- }
- }
- return ''
- })
- // Shiki
- eleventyConfig.on('eleventy.before', async () => {
- const myTheme = createCssVariablesTheme({
- name: 'css-variables',
- variablePrefix: '--shiki-',
- variableDefaults: {},
- fontStyle: true
- })
- const highlighter = await shiki.createHighlighter({
- themes: ['github-dark', myTheme],
- langs: [
- 'html',
- 'blade',
- 'php',
- 'yaml',
- 'js',
- 'jsx',
- 'ts',
- 'shell',
- 'diff',
- 'vue',
- 'scss',
- 'css'
- ],
- });
- eleventyConfig.amendLibrary('md', function (mdLib) {
- return mdLib.set({
- highlight: function (code, lang) {
- // prettify code
- if(lang === 'html') {
- code = beautify.html(code, {
- indent_size: 2,
- wrap_line_length: 80,
- });
- }
- let highlightedCode = highlighter.codeToHtml(code, {
- lang: lang,
- theme: 'github-dark'
- });
- return highlightedCode;
- },
- });
- }
- );
- });
- /**
- * Filters
- */
- function buildCollectionTree(flatData) {
- const tree = [];
- const lookup = {};
- flatData
- .filter(item => item.url !== '/')
- .forEach(item => {
- lookup[item.url] = { ...item, children: [] };
- });
- flatData.forEach(item => {
- const parts = item.url.split('/').filter(Boolean);
- if (parts.length === 1) {
- tree.push(lookup[item.url]);
- } else {
- const parentUrl = '/' + parts.slice(0, -1).join('/') + '/';
- if (lookup[parentUrl]) {
- lookup[parentUrl].children.push(lookup[item.url]);
- } else {
- tree.push(lookup[item.url]);
- }
- }
- });
- return tree;
- }
- eleventyConfig.addFilter("collection-tree", function (collection) {
- const a = collection.map(item => {
- return {
- data: item.data,
- page: item.page,
- url: item.url,
- children: []
- }
- }).sort((a, b) => {
- const orderA = a.data.order ?? 999;
- const orderB = b.data.order ?? 999;
- if (orderA !== orderB) {
- return orderA - orderB;
- }
- const titleA = a.data.title ?? '';
- const titleB = b.data.title ?? '';
- return titleA.localeCompare(titleB);
- });
- return buildCollectionTree(a);
- });
- eleventyConfig.addFilter("collection-children", function (collection, page) {
- const url = page.url.split('/').filter(Boolean).join('/');
- const filteredCollection = collection.filter(item => {
- const parts = item.url.split('/').filter(Boolean);
- return parts.length > 1 && parts.slice(0, -1).join('/') === url;
- });
- return filteredCollection.sort((a, b) => {
- return (a.data?.order || 999) - (b.data?.order || 999);
- });
- });
- eleventyConfig.addFilter("next-prev", function (collection, page) {
- const items = collection
- .filter(item => {
- const parts = item.url.split('/').filter(Boolean);
- return parts.length > 1 && parts.slice(0, -1).join('/') === page.url.split('/').filter(Boolean).slice(0, -1).join('/');
- })
- .sort((a, b) => {
- return a.data.title.localeCompare(b.data.title);
- })
- .sort((a, b) => {
- return (a.data?.order || 999) - (b.data?.order || 999);
- });
- const index = items.findIndex(item => item.url === page.url);
- const prevPost = index > 0 ? items[index - 1] : null;
- const nextPost = index < items.length - 1 ? items[index + 1] : null;
- return {
- prev: prevPost ? prevPost : null,
- next: nextPost ? nextPost : null,
- };
- });
- const generateUniqueId = (text) => {
- return text
- .replace(/<[^>]+>/g, "")
- .replace(/\s/g, "-")
- .replace(/[^\w-]+/g, "")
- .replace(/--+/g, "-")
- .replace(/^-+|-+$/g, "")
- .toLowerCase();
- }
- eleventyConfig.addFilter("headings-id", function (content) {
- return content.replace(/<h([1-6])>([^<]+)<\/h\1>/g, (match, level, text) => {
- const headingId = generateUniqueId(text);
- return `<h${level} id="${headingId}">${text}</h${level}>`;
- });
- })
- eleventyConfig.addFilter("toc", function (name) {
- const toc = [];
- const contentWithoutExamples = name.replace(/<!--EXAMPLE-->[\s\S]*?<!--\/EXAMPLE-->/g, '');
- const headings = contentWithoutExamples.match(/<h([23])>([^<]+)<\/h\1>/g);
- if (headings) {
- headings.forEach(heading => {
- const level = parseInt(heading.match(/<h([1-6])>/)[1]);
- const text = heading.replace(/<[^>]+>/g, "");
- const id = generateUniqueId(text);
- toc.push({ level, text, id });
- });
- }
- return toc;
- })
- eleventyConfig.addFilter("remove-href", function (content) {
- return content.replace(/href="#"/g, 'href="javascript:void(0)"');
- })
- /**
- * Data
- */
- const pkg = JSON.parse(readFileSync(join("..", "core", "package.json"), "utf-8"))
- eleventyConfig.addGlobalData("environment", environment);
- eleventyConfig.addGlobalData("package", pkg);
- eleventyConfig.addGlobalData("cdnUrl", `https://cdn.jsdelivr.net/npm/@tabler/core@${pkg.version}`);
- const data = {
- iconsCount: () => 123,
- emailsCount: () => 123,
- illustrationsCount: () => 123
- };
- for (const [key, value] of Object.entries(data)) {
- eleventyConfig.addGlobalData(key, value);
- }
- eleventyConfig.addGlobalData("docs-links", [
- { title: 'Website', url: 'https://tabler.io', icon: 'world' },
- { title: 'Preview', url: 'https://preview.tabler.io', icon: 'layout-dashboard' },
- { title: 'Support', url: 'https://tabler.io/support', icon: 'headset' },
- ]);
- /**
- * Tags
- */
- eleventyConfig.addPairedShortcode("cards", function (content) {
- return `<div class="mt-6"><div class="row g-3">${content}</div></div>`;
- });
- eleventyConfig.addPairedShortcode("card", function (content, title, href) {
- return `<div class="col-6">
- <${href ? "a" : "div"} href="${href}" class="card ${href ? "" : " bg-surface-tertiary"}">
- <div class="card-body">
- <div class="position-relative">${href ? "" : `<span class="badge position-absolute top-0 end-0">Coming soon</span>`}
- <div class="row align-items-center">
- <div class="col">
- <h3 class="card-title mb-2">${title}</h3>
- <div class="text-secondary small">${content}</div>
- </div>
- <div class="col-auto">
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-chevron-right"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l6 6l-6 6" /></svg>
- </div>
- </div>
- </div>
- </div>
- </${href ? "a" : "div"}>
- </div>`;
- });
- };
|