



The @it-service-npm/remark-include-code package allows you
to embed code files within your Markdown documents.
With this plugin, you can use ::include-code{file="./included.ts"}
syntax to include code to markdown.
Additional features:
- Attribute
language for select code language
- Support for various code file encodings
with
encoding attribute (utf8 by default).
With useEditorConfig attribute or plugin parameter
charset property value from .editorconfig file used for encoding
- Boolean attribute
optional,
which disable fatal directive error when file does not exists
- Deleting the last blank line
(with boolean
trimFinalNewline attribute or plugin parameter)
- Inserting a range of lines from a file
(with integer
fromLine and toLine attributes)
- Replacing tabs with a specified number (
tabWidth attribute) of spaces.
With useEditorConfig attribute or plugin parameter
tab_width property value from .editorconfig used for tabWidth
- Removing the extra indentation for a block of code
with
trimExtraIndent attribute or parameter.
(tabWidth value expected!)
There are two plugins: remarkIncludeCode (preferred) and remarkIncludeCodeSync.
[!IMPORTANT]
remark-directive plugin expected before
@it-service-npm/remark-include-code.
This package provides two plugins presets:
[!TIP]
This plugin has two named entry points:
- ‘sync’ ('@it-service-npm/remark-include-code/sync’)
- ‘async’ ('@it-service-npm/remark-include-code/async’)
With sync and async plugin function and preset.
Contents
Install
npm install --save-dev @it-service-npm/remark-include-code
Examples
Including the content of code files
The @it-service-npm/remark-include-code package allows you
to embed code files within your Markdown documents.
Async plugin using example:
import { remark } from 'remark';
import * as vFile from 'to-vfile';
import remarkDirective from 'remark-directive';
import { remarkIncludeCode } from '@it-service-npm/remark-include-code/async';
import type { VFile } from 'vfile';
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkDirective)
.use(remarkIncludeCode)
.process(await vFile.read(filePath));
};
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directives.
::include-code{file=./included1.ts}
After first file.
::include-code{file="./included 2.ts"}
After second file.
_That_ should do it!
included1.ts:
export function functionInIncluded1File(): void {
console.info('file #1');
};
included 2.ts:
export function functionInIncluded2File(): void {
console.info('file #2');
};
Remark output:
Hello. I am an main markdown file with `::include-code` directives.
```
export function functionInIncluded1File(): void {
console.info('file #1');
};
```
After first file.
```
export function functionInIncluded2File(): void {
console.info('file #2');
};
```
After second file.
*That* should do it!
Defining the code language
You can define the code language with language attribute.
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./included1.ts" language="typescript"}
_That_ should do it!
included1.ts:
export function functionInIncluded1File(): void {
console.info('file #1');
};
Remark output:
Hello. I am an main markdown file with `::include-code` directive.
```typescript
export function functionInIncluded1File(): void {
console.info('file #1');
};
```
*That* should do it!
Defining the code file encoding
You can define the code file encoding with encoding attribute.
Default — 'utf8'.
[!IMPORTANT]
With useEditorConfig attribute or plugin parameter
charset property value from .editorconfig file used for encoding
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./included1.bat" language="batchfile" encoding="CP866"}
included1.bat:
echo "Кириллический текст"
Remark output:
Hello. I am an main markdown file with `::include-code` directive.
```batchfile
echo "Кириллический текст"
```
Or You can use charset property value for encoding from .editorconfig file with
useEditorConfig attribute or parameter.
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./included1.bat" language="batchfile"}
example.ts:
import { remark } from 'remark';
import * as vFile from 'to-vfile';
import remarkDirective from 'remark-directive';
import { remarkIncludeCode } from '@it-service-npm/remark-include-code/async';
import type { VFile } from 'vfile';
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkDirective)
.use(remarkIncludeCode, { useEditorConfig: true })
.process(await vFile.read(filePath));
};
Trim final newline
You can trim final newline with trimFinalNewline attribute.
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./included1.ts" language="typescript" trimFinalNewline}
_That_ should do it!
included1.ts:
export function inFileWithFinalNewline(): void {
console.info('file #1');
};
Remark output:
Hello. I am an main markdown file with `::include-code` directive.
```typescript
export function inFileWithFinalNewline(): void {
console.info('file #1');
};
```
*That* should do it!
And You can trim final newline for all ::include-code directives with
plugin options without trimFinalNewline attribute.
Remark settings (.remarkrc.mjs):
import remarkDirective from 'remark-directive';
import { remarkIncludeCode } from '@it-service-npm/remark-include-code/async';
export default {
plugins: [
remarkDirective,
[remarkIncludeCode, {
trimFinalNewline: true
}],
],
settings: {
bullet: '-'
}
}
or without config file:
import { remark } from 'remark';
import * as vFile from 'to-vfile';
import remarkDirective from 'remark-directive';
import { remarkIncludeCode } from '@it-service-npm/remark-include-code/async';
import type { VFile } from 'vfile';
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkDirective)
.use(remarkIncludeCode, {
trimFinalNewline: true
})
.process(await vFile.read(filePath));
};
[!IMPORTANT]
Package presets remarkIncludeCodePreset and remarkIncludePresetSync
enables trimFinalNewline setting by default.
Inserting a specified range of lines from a file
You can insert a specified range of lines from a file
with fromLine and toLine attributes.
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./included.ts" language="typescript" fromLine=9 toLine=-1}
::include-code{file="./included.ts" language="typescript" fromLine=9 toLine=11}
_That_ should do it!
included.ts:
import { remark } from 'remark';
import * as vFile from 'to-vfile';
import { remarkIncludeCodePreset } from '@it-service-npm/remark-include-code/async';
import type { VFile } from 'vfile';
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkIncludeCodePreset)
.process(await vFile.read(filePath));
};
Remark output:
Hello. I am an main markdown file with `::include-code` directive.
```typescript
return remark()
.use(remarkIncludeCodePreset)
.process(await vFile.read(filePath));
```
```typescript
return remark()
.use(remarkIncludeCodePreset)
.process(await vFile.read(filePath));
```
*That* should do it!
Tabs replacing with spaces
::include-code replace tabs in code with spaces if tabWidth attribute specified.
[!IMPORTANT]
With useEditorConfig attribute or plugin parameter
tab_width property value from .editorconfig
used for tabWidth.
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./example.json" language="json" tabWidth=4}
example.json:
{
"extends": "./tsconfig.json",
"include": [
"./src"
],
"compilerOptions": {
"composite": true,
"noEmit": false,
"allowImportingTsExtensions": false,
"outDir": "./dist",
"rootDir": "./src"
}
}
Remark output:
Hello. I am an main markdown file with `::include-code` directive.
```json
{
"extends": "./tsconfig.json",
"include": [
"./src"
],
"compilerOptions": {
"composite": true,
"noEmit": false,
"allowImportingTsExtensions": false,
"outDir": "./dist",
"rootDir": "./src"
}
}
```
Or You can use tab_width property value from .editorconfig file with
useEditorConfig attribute or parameter.
main.md:
Hello. I am an main markdown file with `::include-code` directive.
::include-code{file="./example.json" language="json"}
example.ts:
import { remark } from 'remark';
import * as vFile from 'to-vfile';
import remarkDirective from 'remark-directive';
import { remarkIncludeCode } from '@it-service-npm/remark-include-code/async';
import type { VFile } from 'vfile';
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkDirective)
.use(remarkIncludeCode, { useEditorConfig: true })
.process(await vFile.read(filePath));
};
You can remove extra indentation with trimExtraIndent attribute or parameter
(for example, if You insert a specified range of lines from a file
with fromLine and toLine attributes).
[!IMPORTANT]
tabWidth value expected
(or tab_width property value from .editorconfig
with useEditorConfig attribute or parameter).
Source files:
main.md:
Hello. I am an main markdown file with `::include-code` directive.
Code fragment with extra indent,
removed with `trimExtraIndent` attribute (two spaces):
::include-code{file="./included.ts" language="typescript" fromLine=9 toLine=-1 tabWidth=2 trimExtraIndent}
Code fragment without extra indent:
::include-code{file="./included.ts" language="typescript" fromLine=6 tabWidth=2 trimExtraIndent}
included.ts:
import { remark } from 'remark';
import * as vFile from 'to-vfile';
import { remarkIncludeCodePreset } from '@it-service-npm/remark-include-code/async';
import type { VFile } from 'vfile';
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkIncludeCodePreset)
.process(await vFile.read(filePath));
};
Remark output:
Hello. I am an main markdown file with `::include-code` directive.
Code fragment with extra indent,
removed with `trimExtraIndent` attribute (two spaces):
```typescript
return remark()
.use(remarkIncludeCodePreset)
.process(await vFile.read(filePath));
```
Code fragment without extra indent:
```typescript
export async function remarkDirectiveUsingExample(
filePath: string
): Promise<VFile> {
return remark()
.use(remarkIncludeCodePreset)
.process(await vFile.read(filePath));
};
```
API
Please, read the API reference.
License
MIT © Sergei S. Betke