Skip to content

Commit

Permalink
feat(builder): add support for loading snippets from files
Browse files Browse the repository at this point in the history
  • Loading branch information
skoropadas committed Aug 6, 2023
1 parent d0da419 commit f8889db
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {ChangeDetectionStrategy, Component} from '@angular/core';
import {NgDocButtonComponent} from '@ng-doc/ui-kit';
import {NgDocNotifyService} from '@ng-doc/ui-kit/services/notify';

// snippet-from-file="../ng-doc.page.ts"

@Component({
selector: 'ng-doc-button-inline-demo',
standalone: true,
Expand Down
19 changes: 18 additions & 1 deletion apps/ng-doc/docs/guides/snippets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,28 @@ If you are using nested snippets, you must specify the language after the snippe
export class DemoComponent {}
```

## Loading snippet from file

Snippet code can be loaded from a file, to do so, you need to use `snippet-from-file` comment,
this version of the snippet also supports `title`, `icon`, `opened` and `language` parameters,
for example:

> **Warning**
> Path is relative to the demo file. Snippets in loaded files are not supported and will be ignored.
```typescript name="demo.component.ts"
// snippet-from-file="./another.component.ts"
@Component({/* ... */})
export class DemoComponent {
onClick(): void {}
}
```

## Example

On the following example you can see how to use snippets in your demos and how they are displayed

```typescript file="./demos/button-inline-demo.component.ts" name="button-inline-demo.component.ts" {10,12,17,20,23,25}
```typescript file="./demos/button-inline-demo.component.ts" name="button-inline-demo.component.ts" {5,12,14,19,22,25,27}

```

Expand Down
33 changes: 29 additions & 4 deletions libs/builder/helpers/process-snippets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {escapeRegexp} from '@ng-doc/core';
import * as fs from 'fs';
import path from 'path';

import {NgDocSnippet} from '../interfaces';
import {parseSnippet} from '../parsers/parse-snippet';
Expand All @@ -14,22 +16,45 @@ const snippet = (id?: string | null) =>
: new RegExp(`\\n?\\r?^.*((\\/\\/|<!--|\\/\\*)\\s*)(snippet.*?(?=(-->|\\*\\/)?))\\s*(-->|\\*\\/)?$`, 'gm');

/**
* Process snippets from code
*
* @param code
* @param code - code to process
* @param basePath - base path to file
*/
export function processSnippets(code: string): NgDocSnippet[] {
export function processSnippets(code: string, basePath?: string): NgDocSnippet[] {
const result: NgDocSnippet[] = [];
const endings: Set<number> = new Set();
const startRegexp = snippet();
let match: RegExpExecArray | null;

// eslint-disable-next-line no-cond-assign
while ((match = startRegexp.exec(code))) {
if (!endings.has(match.index)) {
const isHTMLComment = match[2] === '<!--';

if (match[3]?.includes('snippet-from-file=') && basePath) {
const config = parseSnippet(match[3].trim());

if (config) {
const {title, lang, icon, opened, fromFile} = config;

const language = lang || (isHTMLComment ? 'html' : 'ts');

if (fromFile) {
const snippetCode = fs.readFileSync(path.join(basePath, fromFile), 'utf-8');

result.push({
title: title ?? path.basename(fromFile),
lang: language,
icon,
opened,
code: formatCode(removeSnippets(snippetCode), getCodeTypeFromLang(language)).trim(),
});
}
}
} else if (!endings.has(match.index)) {
const config = parseSnippet(match[3].trim());

if (config) {
const isHTMLComment = match[2] === '<!--';
const {id, title, lang, icon, opened} = config;
const endRegexp = snippet(id);

Expand Down
3 changes: 2 additions & 1 deletion libs/builder/helpers/snippets-from-asset.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {NgDocStyleType} from '@ng-doc/core';
import path from 'path';

import {NgDocAsset} from '../interfaces';
import {codeTypeFromExt} from './code-type-from-ext';
Expand All @@ -12,7 +13,7 @@ import {processSnippets} from './process-snippets';
* @param inlineStylesType - Inline styles type
*/
export function snippetsFromAsset(asset: NgDocAsset, inlineStylesType: NgDocStyleType): NgDocAsset[] {
const snippets = processLegacySnippets(asset.code).concat(processSnippets(asset.code));
const snippets = processLegacySnippets(asset.code).concat(processSnippets(asset.code, path.dirname(asset.filePath)));
const codeType = codeTypeFromExt(asset.filePath);
const isStylesFile = ['CSS', 'SCSS', 'LESS', 'SASS'].includes(codeType.toUpperCase());

Expand Down
Loading

0 comments on commit f8889db

Please sign in to comment.