Skip to content

Commit

Permalink
cssxref
Browse files Browse the repository at this point in the history
  • Loading branch information
viperehonchuk committed Feb 20, 2024
1 parent 2b05b1d commit 1fd5669
Show file tree
Hide file tree
Showing 14 changed files with 169 additions and 44 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ jobs:
BASE_PATH: ${{ vars.BASE_PATH }}
MODE: production
PATH_TO_LOCALIZED_CONTENT: ${{ vars.PATH_TO_LOCALIZED_CONTENT }}
PATH_TO_ORIGINAL_CONTENT: ${{ vars.PATH_TO_ORIGINAL_CONTENT }}
ROLLBAR_ACCESS_TOKEN: ${{ secrets.ROLLBAR_ACCESS_TOKEN }}
TARGET_LOCALE: ${{ vars.TARGET_LOCALE }}
GOOGLE_ANALYTICS_ID: ${{ vars.GOOGLE_ANALYTICS_ID }}
Expand Down
2 changes: 1 addition & 1 deletion external/original-content
6 changes: 3 additions & 3 deletions src/plugins/registry/get-all.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import registry from './registry.ts';
import { translatedContentRegistry } from './index.ts';

export default function getAll() {
if (registry.size === 0) {
if (translatedContentRegistry.size === 0) {
throw new Error('Registry is not initialized');
}
return [...registry.values()];
return [...translatedContentRegistry.values()];
}
6 changes: 3 additions & 3 deletions src/plugins/registry/has-page.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import registry from './registry.js';
import { translatedContentRegistry } from './index.ts';

export default function hasPage(slug: string): boolean {
if (!slug) {
throw new Error('Slug is required');
}
if (registry.size === 0) {
if (translatedContentRegistry.size === 0) {
throw new Error('Registry is not initialized');
}
return registry.has(slug);
return translatedContentRegistry.has(slug);
}
4 changes: 4 additions & 0 deletions src/plugins/registry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import type { RawPage } from './validation.ts';

export const translatedContentRegistry = new Map<string, RawPage>();
export const originalContentRegistry = new Map<string, RawPage>();
14 changes: 14 additions & 0 deletions src/plugins/registry/init-original-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { originalContentRegistry } from './index.ts';
import { initRegistry } from './registry.ts';

export default async function initOriginalRegistry() {
const PATH_TO_ORIGINAL_CONTENT = process.env.PATH_TO_ORIGINAL_CONTENT;
if (!PATH_TO_ORIGINAL_CONTENT) {
throw new Error('process.env.PATH_TO_ORIGINAL_CONTENT is not defined');
}
await initRegistry(
originalContentRegistry,
PATH_TO_ORIGINAL_CONTENT,
'en-us',
);
}
18 changes: 18 additions & 0 deletions src/plugins/registry/init-translated-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { translatedContentRegistry } from './index.ts';
import { initRegistry } from './registry.ts';

export default async function initTranslatedRegistry() {
const PATH_TO_LOCALIZED_CONTENT = process.env.PATH_TO_LOCALIZED_CONTENT;
if (!PATH_TO_LOCALIZED_CONTENT) {
throw new Error('process.env.PATH_TO_LOCALIZED_CONTENT is not defined');
}
const TARGET_LOCALE = process.env.TARGET_LOCALE;
if (!TARGET_LOCALE) {
throw new Error('process.env.TARGET_LOCALE is not defined');
}
await initRegistry(
translatedContentRegistry,
PATH_TO_LOCALIZED_CONTENT,
TARGET_LOCALE,
);
}
50 changes: 20 additions & 30 deletions src/plugins/registry/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,28 @@ import walk from '../utils/walk-async.js';

import { rawPageSchema, type RawPage } from './validation.js';

const registry = new Map<string, RawPage>();

export default registry;

export async function initRegistry() {
export async function initRegistry(
registry: Map<string, RawPage>,
pathToContent: string,
locale: string,
) {
if (registry.size > 0) {
return;
}
const PATH_TO_LOCALIZED_CONTENT = process.env.PATH_TO_LOCALIZED_CONTENT;
if (!PATH_TO_LOCALIZED_CONTENT) {
throw new Error('process.env.PATH_TO_LOCALIZED_CONTENT is not defined');
}
if (!process.env.TARGET_LOCALE) {
throw new Error('process.env.TARGET_LOCALE is not defined');
}
await walk(
join(PATH_TO_LOCALIZED_CONTENT, 'files', process.env.TARGET_LOCALE),
async (filePath) => {
if (!filePath.endsWith('/index.md')) {
return;
}
// console.log(filePath);
const markdownFile = await read(filePath);
await walk(join(pathToContent, 'files', locale), async (filePath) => {
if (!filePath.endsWith('/index.md')) {
return;
}
// console.log(filePath);
const markdownFile = await read(filePath);

// console.log(markdownFile);
matter(markdownFile);
// console.log(markdownFile.data.matter);
const data = {
...rawPageSchema.parse(markdownFile.data.matter),
filePath: filePath,
};
registry.set(data.slug, data);
},
);
// console.log(markdownFile);
matter(markdownFile);
// console.log(markdownFile.data.matter);
const data = {
...rawPageSchema.parse(markdownFile.data.matter),
filePath: filePath,
};
registry.set(data.slug, data);
});
}
4 changes: 2 additions & 2 deletions src/plugins/rehype/check-referenced-anchors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { z } from 'zod';

import hasAnchor, { initAnchorsRegistry } from '../registry/has-anchor.js';
import hasPage from '../registry/has-page.js';
import { initRegistry } from '../registry/registry.js';
import initTranslatedRegistry from '../registry/init-translated-registry.ts';
import getAnchorsFromTree from '../utils/get-anchors-from-tree.js';
import getSlugFromUrl from '../utils/get-slug-from-url.js';

const stringSchema = z.optional(z.string());

export default async function checkReferencedAnchors(tree: Root, file: VFile) {
// console.log('checkReferencedAnchors');
await initRegistry();
await initTranslatedRegistry();
await initAnchorsRegistry();
const currentPageSlugs = getAnchorsFromTree(tree);
const BASE_PATH = process.env.BASE_PATH;
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/rehype/inject-link-classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import type { Root } from 'hast';
import { visit } from 'unist-util-visit';

import hasPage from '../registry/has-page.js';
import { initRegistry } from '../registry/registry.js';
import initTranslatedRegistry from '../registry/init-translated-registry.ts';
import getSlugFromUrl from '../utils/get-slug-from-url.js';

const EXTERNAL_LINK_CLASS = 'wd-external';
const MISSING_LINK_CLASS = 'wd-nav-link-not-translated';

function getClassesByUrl(url: string): string[] {
console.log('getClassesByUrl', url);
if (url.startsWith('#')) {
return [];
}
Expand All @@ -29,12 +30,13 @@ function getClassesByUrl(url: string): string[] {
}

export default async function injectLinkClasses(tree: Root) {
await initRegistry();
await initTranslatedRegistry();

visit(tree, 'element', (node: Element) => {
if (node.tagName !== 'a') return;
const url = node.properties?.href;
if (typeof url !== 'string') return;
console.log(node);
const classes = getClassesByUrl(url);
node.properties.class = classes.join(' ');
if (classes.includes(EXTERNAL_LINK_CLASS)) {
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/remark/macros/expand.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Root } from 'mdast';
import { SKIP, visit } from 'unist-util-visit';

import { initRegistry } from '../../registry/registry.ts';
import initOriginalRegistry from '../../registry/init-original-registry.ts';
import initTranslatedRegistry from '../../registry/init-translated-registry.ts';
import { type AstroFile } from '../validate-astro-file.ts';

import brokenMacroToHtml from './broken-macro-to-html.js';
Expand All @@ -17,7 +18,8 @@ import type {
import unmakeMacroTree from './unmake-macro-tree.js';

export default async function expandMacros(tree: Root, file: AstroFile) {
await initRegistry();
await initTranslatedRegistry();
await initOriginalRegistry();
visit(tree, 'html', (node) => {
node.value = processHtml(node);
});
Expand Down
91 changes: 91 additions & 0 deletions src/plugins/remark/macros/macros/cssxref.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type { Html } from 'mdast';
import { SKIP } from 'unist-util-visit';

import {
originalContentRegistry,
translatedContentRegistry,
} from '../../../registry/index.ts';
import type { MacroFunction, MacroNode } from '../types.ts';
import { wrappedStringSchema } from '../validation.ts';

function parseArguments(value: string[]): [string, string | undefined, string] {
if (value.length === 0 || !value[0]) {
throw new Error('No arguments provided');
}
return [
wrappedStringSchema.parse(value[0]),
value[1] ? wrappedStringSchema.parse(value[1]) : undefined,
value[2] ? wrappedStringSchema.parse(value[2]) : '',
];
}

function macro(node: MacroNode): Html {
const targetLocale = process.env.TARGET_LOCALE;
let arguments_ = parseArguments(node.parameters);
let url = '';
let urlWithoutAnchor = '';
let displayName = arguments_[1] || arguments_[0];

// Deal with CSS data types by removing <>
let slug = arguments_[0].replaceAll(/&lt;(.*)&gt;/g, '$1');

// Special case <color>, <flex>, and <position>
switch (arguments_[0]) {
case '&lt;color&gt;': {
slug = 'color_value';
break;
}

case '&lt;flex&gt;': {
slug = 'flex_value';
break;
}

case '&lt;position&gt;': {
slug = 'position_value';
break;
}
}

const basePath = `/${targetLocale}/docs/Web/CSS/`;
urlWithoutAnchor = basePath + slug;
url = urlWithoutAnchor + arguments_[2];

const thisPage =
translatedContentRegistry.get(`Web/CSS/${slug}`) ||
originalContentRegistry.get(`Web/CSS/${slug}`);

if (!thisPage) {
throw new Error(`No page found for ${slug}`);
}

if (!arguments_[1]) {
// Append parameter brackets to CSS functions
if (
thisPage['page-type'] === 'css-function' &&
!displayName.endsWith('()')
) {
displayName += '()';
}
// Enclose CSS data types in arrow brackets
if (
thisPage['page-type'] === 'css-type' &&
!/^&lt;.+&gt;$/.test(displayName)
) {
displayName = '&lt;' + displayName + '&gt;';
}
}

return {
type: 'html',
value: `<a href="${url}" title="${thisPage?.title}"><code>${displayName}</code></a>`,
};
}

const cssxref: MacroFunction = (node, index, parent) => {
const replacement = macro(node);
parent.children[index] = replacement;
return [SKIP, index];
};

export default cssxref;
2 changes: 2 additions & 0 deletions src/plugins/remark/macros/macros/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import EmbedLiveSample from './EmbedLiveSample/index.ts';
import GlossaryDisambiguation from './GlossaryDisambiguation.ts';
import GlossarySidebar from './GlossarySidebar.ts';
import HTMLElement from './HTMLElement.ts';
import cssxref from './cssxref.ts';
import domxref from './domxref.ts';
import jsSidebar from './jsSidebar/index.ts';
import jsxref from './jsxref.ts';
Expand All @@ -13,6 +14,7 @@ const MACROS: Record<string, MacroFunction> = {
GlossaryDisambiguation,
GlossarySidebar,
HTMLElement,
cssxref,
domxref,
jsSidebar,
jsxref,
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/utils/get-slug-from-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export default function getSlugFromUrl(url: string): string {
throw new Error('process.env.TARGET_LOCALE is not defined');
}
if (!urlWithoutAnchor) {
throw new Error('urlWithoutAnchor is required');
console.error('urlWithoutAnchor is empty', url);
return '';
}
const separator = urlWithoutAnchor.includes(
`/${process.env.TARGET_LOCALE}/docs/`,
Expand Down

0 comments on commit 1fd5669

Please sign in to comment.