Skip to content

Commit

Permalink
feat(contented): support for auto relative linking (#547)
Browse files Browse the repository at this point in the history
<!--  Thanks for sending a pull request! -->

#### What this PR does / why we need it:

As per title for linking DX.
  • Loading branch information
fuxingloh authored Aug 7, 2023
1 parent d68f357 commit 1c38625
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 17 deletions.
10 changes: 3 additions & 7 deletions packages/contented-example/contented.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const config = {
pipelines: [
{
type: 'Contented',
pattern: 'docs/**/*.md',
dir: 'docs',
pattern: '**/*.md',
processor: 'md',
fields: {
title: {
Expand All @@ -28,15 +29,10 @@ const config = {
editOnGitHubLink: {
type: 'string',
resolve: (_, { file }) => {
return `https://github.com/levaintech/contented/edit/main/packages/contented-example/${file.data.contented.filePath}`;
return `https://github.com/levaintech/contented/edit/main/packages/contented-example/docs/${file.data.contented.filePath}`;
},
},
},
transform: (file) => {
file.path = file.path.replaceAll(/^\/docs\/?/g, '/');
file.sections = file.sections.slice(1);
return file;
},
},
{
type: 'Lorem',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
authoring-oriented workflow to encourage developer authoring within its contextual Git repository.

With a headless design of 1 config file `contented.config.mjs`, developers can start writing
their [markdown content](04-markdown) and preview it on their localhost `contented generate --watch`.
their [markdown content](./04-markdown.md) and preview it on their localhost `contented generate --watch`.
Choosing convention over configuration reduces HTML/UI clutter, allowing developers to focus on authoring.

Authored content can be continuously delivered (CD) into a hosted static site (e.g., GitHub Pages/Netlify/Vercel) for
Expand Down Expand Up @@ -34,7 +34,7 @@ naturally satisfies.
The outcome we're trying to achieve is
this [@contentedjs/contented-example/dist](https://www.jsdelivr.com/package/npm/@contentedjs/contented-example)

> [See Contented Limitations](09-Others/02-limitations.md)
> [See Contented Limitations](./09-Others/02-limitations.md)
## Powered By

Expand Down
22 changes: 21 additions & 1 deletion packages/contented-example/docs/04-markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,31 @@ title: Markdown Flavour
## Linking

```md
[Heading](#linking)
[Heading](#heading)
[External](https://example.com)

Relative Linking (manual):
[Relative Example 1](relative)
[Relative Example 2](to/folder/page-1)
[Relative Example 3](../back/page-3)

Relative Linking (automatic), give these 3 files:

1. 01-about.md
2. docs/01-introduction.md
3. docs/01-others/02-usage.md

[Automatic Relative Linking](./01-about.md):

- When you reference this link in the root dir of the pipeline `about` will be resolved.
- When you reference this link in the `docs` dir of the pipeline `../about` will be resolved.
- When you reference this link in the `docs/01-others` dir of the pipeline `../../about` will be resolved.

[Automatic Relative Linking](./docs/01-introduction.md):

- When you reference this link in the root dir of the pipeline `docs/introduction` will be resolved.
- When you reference this link in the `docs` dir of the pipeline `introduction` will be resolved.
- When you reference this link in the `docs/01-others` dir of the pipeline `../introduction` will be resolved.
```

It is highly recommended to use relative links for internal linking and avoid using absolute links.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ Since the purpose of Contented is to encourage authoring through a set of tools
been for engineers to produce more markdowns (_.md) or processed prose (`_.json`). The focus is never about building a
complete documentation website.

In fact, you should take the output(s) of [`contented build`](../03-api.md#contented-build) that are published into npm; and pull them
In fact, you should take the output(s) of [`contented build`](./03-api.md#contented-build) that are published into npm; and pull them
into your main/official website for re-presentation (`npm i, import from`). Remember, the prose/content/narrative
created is what's valuable here. Design can easily change, but your content stands the test of time.
19 changes: 17 additions & 2 deletions packages/contented-pipeline-md/src/plugins/RemarkLink.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { join, parse as parsePath, relative } from 'node:path';
import { parse } from 'node:url';

import { Link, Parent } from 'mdast';
Expand All @@ -20,7 +21,21 @@ function visitLink(file: VFile): (node: Link) => void {
if (parse(node.url).hostname !== null) {
return;
}
// eslint-disable-next-line no-param-reassign
node.url = contented.contentedPipeline.getSanitizedPath(node.url);

/* eslint-disable no-param-reassign */
const path = node.url;
if (path.startsWith('./')) {
const pipelineDir = join(
contented.contentedPipeline.rootPath,
contented.contentedPipeline.pipeline.dir ?? '',
'/',
);
const parsedPath = parsePath(join(pipelineDir, contented.filePath));
const linkedFilePath = join(pipelineDir, path);
const relativePath = relative(parsedPath.dir, linkedFilePath);
node.url = contented.contentedPipeline.getSanitizedPath(relativePath);
} else {
node.url = contented.contentedPipeline.getSanitizedPath(path);
}
};
}
10 changes: 10 additions & 0 deletions packages/contented-pipeline/src/Pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FileContent, FileIndex } from './PipelineFile.js';

export interface Pipeline {
type: string;
dir?: string;
pattern: string | string[];
/**
* Built in processor: 'md'
Expand Down Expand Up @@ -49,6 +50,15 @@ export abstract class ContentedPipeline {
* @return {FileContent[]} containing none, one or many FileContent
*/
async process(rootPath: string, file: string): Promise<FileContent[]> {
if (this.pipeline.dir) {
// When pipeline.dir is set, we need to recompute the file path
const filePath = join(rootPath, file);
/* eslint-disable no-param-reassign */
rootPath = join(rootPath, this.pipeline.dir, '/');
file = filePath.replace(rootPath, '');
/* eslint-enable no-param-reassign */
}

const fileIndex = await this.newFileIndex(rootPath, file);
const contents = await this.processFileIndex(fileIndex, rootPath, file);
if (contents === undefined) {
Expand Down
14 changes: 10 additions & 4 deletions packages/contented-processor/src/ContentedProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class ContentedProcessor {
config.rootDir = config.rootDir ?? './';
config.outDir = config.outDir ?? './.contented';
config.pipelines.forEach((pipeline) => {
pipeline.type = pipeline.type ?? 'Default';
pipeline.type = pipeline.type ?? 'Docs';
if (pipeline.type.match(/[^a-zA-Z]/g)) {
throw new Error(
'Due to codegen, pipeline.type must be a string with allowed characters within the range of [a-zA-Z].',
Expand Down Expand Up @@ -137,13 +137,19 @@ export class ContentedProcessor {
*/
private findPipelineByFile(filePath: string) {
return this.config.pipelines.find((pipeline) => {
const isMatched = (pattern: string): boolean => {
if (pipeline.dir) {
return minimatch(filePath, join(this.rootPath, pipeline.dir, pattern));
}
return minimatch(filePath, join(this.rootPath, pattern));
};

if (typeof pipeline.pattern === 'string') {
return minimatch(filePath, join(this.rootPath, pipeline.pattern));
return isMatched(pipeline.pattern);
}

for (const pattern of pipeline.pattern) {
const matched = minimatch(filePath, join(this.rootPath, pattern));
if (matched) {
if (isMatched(pattern)) {
return true;
}
}
Expand Down

0 comments on commit 1c38625

Please sign in to comment.