mirror of https://github.com/jkjoy/sunpeiwen.git
758 lines
20 KiB
Markdown
758 lines
20 KiB
Markdown
|
# hexo-util
|
||
|
|
||
|
[![Build Status](https://github.com/hexojs/hexo-util/workflows/Tester/badge.svg?branch=master)](https://github.com/hexojs/hexo-util/actions?query=workflow%3ATester)
|
||
|
[![NPM version](https://badge.fury.io/js/hexo-util.svg)](https://www.npmjs.com/package/hexo-util)
|
||
|
[![Coverage Status](https://coveralls.io/repos/hexojs/hexo-util/badge.svg?branch=master&service=github)](https://coveralls.io/github/hexojs/hexo-util?branch=master)
|
||
|
[![dependencies Status](https://david-dm.org/hexojs/hexo-util/status.svg)](https://david-dm.org/hexojs/hexo-util)
|
||
|
[![devDependencies Status](https://david-dm.org/hexojs/hexo-util/dev-status.svg)](https://david-dm.org/hexojs/hexo-util?type=dev)
|
||
|
|
||
|
Utilities for [Hexo].
|
||
|
|
||
|
## Table of contents
|
||
|
|
||
|
- [Installation](#installation)
|
||
|
- [Usage](#usage)
|
||
|
- [Cache](#cache)
|
||
|
- [CacheStream](#cachestream)
|
||
|
- [camelCaseKeys](#camelcasekeysobj-options)
|
||
|
- [createSha1Hash](#createsha1hash)
|
||
|
- [decodeURL](#decodeurlstr)
|
||
|
- [deepMerge](#deepmergetarget-source)
|
||
|
- [encodeURL](#encodeurlstr)
|
||
|
- [escapeDiacritic](#escapediacriticstr)
|
||
|
- [escapeHTML](#escapehtmlstr)
|
||
|
- [escapeRegex](#escaperegexstr)
|
||
|
- [full_url_for](#full_url_forpath)
|
||
|
- [gravatar](#gravatarstr-options)
|
||
|
- [hash](#hashstr)
|
||
|
- [highlight](#highlightstr-options)
|
||
|
- [htmlTag](#htmltagtag-attrs-text-escape)
|
||
|
- [isExternalLink](#isexternallinkurl-sitehost-exclude)
|
||
|
- [Pattern](#patternrule)
|
||
|
- [Permalink](#permalinkrule-options)
|
||
|
- [prettyUrls](#prettyurlsurl-options)
|
||
|
- [prismHighlight](#prismhighlightstr-options)
|
||
|
- [relative_url](#relative_urlfrom-to)
|
||
|
- [slugize](#slugizestr-options)
|
||
|
- [spawn](#spawncommand-args-options)
|
||
|
- [stripHTML](#striphtmlstr)
|
||
|
- [wordWrap](#wordwrapstr-options)
|
||
|
- [tocObj](#tocobjstr-options)
|
||
|
- [truncate](#truncatestr-options)
|
||
|
- [unescapeHTML](#unescapehtmlstr)
|
||
|
- [url_for](#url_forpath-option)
|
||
|
- [bind(hexo)](#bindhexo)
|
||
|
|
||
|
## Installation
|
||
|
|
||
|
``` bash
|
||
|
$ npm install hexo-util --save
|
||
|
```
|
||
|
|
||
|
## Usage
|
||
|
|
||
|
``` js
|
||
|
var util = require('hexo-util');
|
||
|
```
|
||
|
|
||
|
### Cache()
|
||
|
|
||
|
A simple plain object cache
|
||
|
|
||
|
``` js
|
||
|
const cache = new Cache();
|
||
|
|
||
|
// set(key, value)
|
||
|
cache.set('foo', 'bar');
|
||
|
|
||
|
// get(key) => value
|
||
|
cache.get('foo');
|
||
|
// 'bar'
|
||
|
|
||
|
// has(key) => Boolean
|
||
|
cache.has('foo');
|
||
|
// true
|
||
|
cache.has('bar');
|
||
|
// false
|
||
|
|
||
|
// apply(key. value)
|
||
|
cache.apply('baz', () => 123);
|
||
|
// 123
|
||
|
cache.apply('baz', () => 456);
|
||
|
// 123
|
||
|
cache.apply('qux', 456);
|
||
|
// 456
|
||
|
cache.apply('qux', '789');
|
||
|
// 456
|
||
|
|
||
|
// size()
|
||
|
cache.size();
|
||
|
// 3
|
||
|
|
||
|
// dump()
|
||
|
cache.dump();
|
||
|
/*
|
||
|
{
|
||
|
foo: 'bar',
|
||
|
baz: 123,
|
||
|
qux: 456
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// del(key)
|
||
|
cache.del('baz');
|
||
|
cache.has('baz');
|
||
|
// false
|
||
|
|
||
|
// flush()
|
||
|
cache.flush();
|
||
|
cache.has('foo');
|
||
|
// false
|
||
|
cache.size();
|
||
|
// 0
|
||
|
```
|
||
|
|
||
|
### CacheStream()
|
||
|
|
||
|
Caches contents piped to the stream.
|
||
|
|
||
|
``` js
|
||
|
var stream = new CacheStream();
|
||
|
|
||
|
fs.createReadStream('/path/to/file').pipe(stream);
|
||
|
|
||
|
stream.on('finish', function(){
|
||
|
// Read cache piped to the stream
|
||
|
console.log(stream.getCache());
|
||
|
|
||
|
// Destroy cache
|
||
|
stream.destroy();
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### camelCaseKeys(obj, options)
|
||
|
|
||
|
Convert object keys to camelCase. Original keys will be converted to getter/setter and sync to the camelCase keys.
|
||
|
|
||
|
``` js
|
||
|
camelCaseKeys({
|
||
|
foo_bar: 'test'
|
||
|
});
|
||
|
// { fooBar: 'test', foo_bar: 'test' }
|
||
|
```
|
||
|
|
||
|
### createSha1Hash()
|
||
|
return SHA1 hash object.
|
||
|
This is the same as calling `createHash('utf8')` in the node.js native module crypto.
|
||
|
``` js
|
||
|
const sha1 = createSha1Hash();
|
||
|
fs.createReadStream('/path/to/file')
|
||
|
.pipe(sha1)
|
||
|
.on('finish', () => {
|
||
|
console.log(sha1.read());
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### decodeURL(str)
|
||
|
|
||
|
Decode [encoded](https://en.wikipedia.org/wiki/Percent-encoding) URL or path. An alternative to the native [`decodeURI()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) function, with added ability to decode [punycoded](https://en.wikipedia.org/wiki/Punycode) domain.
|
||
|
|
||
|
``` js
|
||
|
decodeURL('http://foo.com/b%C3%A1r')
|
||
|
// http://foo.com/bár
|
||
|
|
||
|
decodeURL('http://xn--br-mia.com/baz')
|
||
|
// http://bár.com/baz
|
||
|
|
||
|
decodeURL('/foo/b%C3%A1r/')
|
||
|
// /foo/bár/
|
||
|
|
||
|
/* Alternatively, Node 10+ offers native API to decode punycoded domain */
|
||
|
const {format} = require('url')
|
||
|
decodeURI(format(new URL('http://xn--br-mia.com.com/b%C3%A1r'), {unicode: true}))
|
||
|
// http://bár.com/báz
|
||
|
```
|
||
|
|
||
|
### deepMerge(target, source)
|
||
|
|
||
|
Merges the enumerable properties of two objects deeply. `target` and `source` remain untouched.
|
||
|
|
||
|
``` js
|
||
|
// Merge deeply
|
||
|
const obj1 = {a: {b: 1, c: 1, d: {e: 1, f: 1}}};
|
||
|
const obj2 = {a: {b: 2, d: {f: 'f'} }};
|
||
|
|
||
|
deepMerge(obj1, obj2);
|
||
|
// {a: {b: 2, c: 1, d: {e: 1, f: 'f'} }}
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
// Arrays will be combined in the same property, similar to lodash.merge
|
||
|
const obj1 = { 'a': [{ 'b': 2 }, { 'd': 4 }] };
|
||
|
const obj2 = { 'a': [{ 'c': 3 }, { 'e': 5 }] };
|
||
|
|
||
|
deepMerge(obj1, obj2);
|
||
|
// { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] };
|
||
|
```
|
||
|
|
||
|
### encodeURL(str)
|
||
|
|
||
|
Encode URL or path into a [safe format](https://en.wikipedia.org/wiki/Percent-encoding).
|
||
|
|
||
|
``` js
|
||
|
encodeURL('http://foo.com/bár')
|
||
|
// http://foo.com/b%C3%A1r
|
||
|
|
||
|
encodeURL('/foo/bár/')
|
||
|
// /foo/b%C3%A1r/
|
||
|
```
|
||
|
|
||
|
### escapeDiacritic(str)
|
||
|
|
||
|
Escapes diacritic characters in a string.
|
||
|
|
||
|
### escapeHTML(str)
|
||
|
|
||
|
Escapes HTML entities in a string.
|
||
|
|
||
|
``` js
|
||
|
escapeHTML('<p>Hello "world".</p>')
|
||
|
// <p>Hello "world".</p>
|
||
|
|
||
|
/* support escaped characters */
|
||
|
escapeHTML('<foo>bar</foo>')
|
||
|
// <foo>bar</foo>
|
||
|
```
|
||
|
|
||
|
### escapeRegex(str)
|
||
|
|
||
|
Escapes special characters in a regular expression.
|
||
|
|
||
|
### full_url_for(path)
|
||
|
|
||
|
Returns a url with the config.url prefixed. Output is [encoded](#encodeurlstr) automatically. Requires [`bind(hexo)`](#bindhexo).
|
||
|
|
||
|
``` yml
|
||
|
_config.yml
|
||
|
url: https://example.com/blog # example
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
full_url_for('/a/path')
|
||
|
// https://example.com/blog/a/path
|
||
|
```
|
||
|
|
||
|
### gravatar(str, [options])
|
||
|
|
||
|
Returns the gravatar image url from an email.
|
||
|
|
||
|
If you didn't specify the [options] parameter, the default options will apply. Otherwise, you can set it to a number which will then be passed on as the size parameter to Gravatar. Finally, if you set it to an object, it will be converted into a query string of parameters for Gravatar.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`s` | Output image size | 80
|
||
|
`d` | Default image |
|
||
|
`f` | Force default |
|
||
|
`r` | Rating |
|
||
|
|
||
|
More info: [Gravatar](https://en.gravatar.com/site/implement/images/)
|
||
|
|
||
|
``` js
|
||
|
gravatar('a@abc.com')
|
||
|
// https://www.gravatar.com/avatar/b9b00e66c6b8a70f88c73cb6bdb06787
|
||
|
gravatar('a@abc.com', 40)
|
||
|
// https://www.gravatar.com/avatar/b9b00e66c6b8a70f88c73cb6bdb06787?s=40
|
||
|
gravatar('a@abc.com' {s: 40, d: 'https://via.placeholder.com/150'})
|
||
|
// https://www.gravatar.com/avatar/b9b00e66c6b8a70f88c73cb6bdb06787?s=40&d=https%3A%2F%2Fvia.placeholder.com%2F150
|
||
|
```
|
||
|
|
||
|
### hash(str)
|
||
|
|
||
|
Generates SHA1 hash.
|
||
|
|
||
|
``` js
|
||
|
hash('123456');
|
||
|
// <Buffer 7c 4a 8d 09 ca 37 62 af 61 e5 95 20 94 3d c2 64 94 f8 94 1b>
|
||
|
```
|
||
|
|
||
|
### highlight(str, [options])
|
||
|
|
||
|
Syntax highlighting for a code block.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`gutter` | Whether to show line numbers | true
|
||
|
`wrap` | Whether to wrap the code block in [`<table>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table) | true
|
||
|
`firstLine` | First line number | 1
|
||
|
`hljs` | Whether to use the `hljs-*` prefix for CSS classes | false
|
||
|
`lang` | Language |
|
||
|
`caption` | Caption |
|
||
|
`tab`| Replace tabs |
|
||
|
`autoDetect` | Detect language automatically (warning: slow)<br>_Sublanguage highlight requires `autoDetect` to be enabled and `lang` to be unset_ | false
|
||
|
`mark` | Line highlight specific line(s) |
|
||
|
`languageAttr` | Output code language into `data-language` attr | false
|
||
|
|
||
|
### htmlTag(tag, attrs, text, escape)
|
||
|
|
||
|
Creates a html tag.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`tag` | Tag / element name |
|
||
|
`attrs` | Attribute(s) and its value.<br>Value is always [escaped](#escapehtmlstr), URL is always [encoded](#encodeurlstr). |
|
||
|
`text` | Text, the value is always escaped<br>_(except for `<style>` tag)_ |
|
||
|
`escape` | Whether to escape the text | true
|
||
|
|
||
|
``` js
|
||
|
htmlTag('img', {src: 'example.png'})
|
||
|
// <img src="example.png">
|
||
|
|
||
|
htmlTag('a', {href: 'http://hexo.io/'}, 'Hexo')
|
||
|
// <a href="http://hexo.io/">Hexo</a>
|
||
|
|
||
|
htmlTag('link', {href: 'http://foo.com/'}, '<a>bar</a>')
|
||
|
// <a href="http://foo.com/"><bar></a>
|
||
|
|
||
|
htmlTag('a', {href: 'http://foo.com/'}, '<b>bold</b>', false)
|
||
|
// <a href="http://foo.com/"><b>bold</b></a>
|
||
|
|
||
|
/* text value of <style> won't be escaped, url is still encoded */
|
||
|
htmlTag('style', {}, 'p { content: "<"; background: url("bár.jpg"); }')
|
||
|
// <style>p { content: "<"; background: url("b%C3%A1r.jpg"); }</style>
|
||
|
|
||
|
/* support script tag with async/defer */
|
||
|
htmlTag('script', {src: '/foo.js', async: true}, '')
|
||
|
// <script src="/foo.js" async></script>
|
||
|
```
|
||
|
|
||
|
### isExternalLink(url, sitehost, [exclude])
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`url` | The input URL. |
|
||
|
`sitehost` | The hostname / url of website. You can also pass `hexo.config.url`. |
|
||
|
`exclude` | Exclude hostnames. Specific subdomain is required when applicable, including www. | `[]`
|
||
|
|
||
|
Returns if a given url is external link relative to given `sitehost` and `[exclude]`.
|
||
|
|
||
|
``` js
|
||
|
// 'sitehost' can be a domain or url
|
||
|
isExternalLink('https://example.com', 'example.com');
|
||
|
// false
|
||
|
isExternalLink('https://example.com', 'https://example.com');
|
||
|
// false
|
||
|
isExternalLink('https://example.com', '//example.com/blog/');
|
||
|
// false
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
isExternalLink('/archives/foo.html', 'example.com');
|
||
|
// false
|
||
|
isExternalLink('https://foo.com/', 'example.com');
|
||
|
// true
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
isExternalLink('https://foo.com', 'example.com', ['foo.com', 'bar.com']);
|
||
|
// false
|
||
|
isExternalLink('https://bar.com', 'example.com', ['foo.com', 'bar.com']);
|
||
|
// false
|
||
|
isExternalLink('https://baz.com/', 'example.com', ['foo.com', 'bar.com']);
|
||
|
// true
|
||
|
```
|
||
|
|
||
|
|
||
|
### Pattern(rule)
|
||
|
|
||
|
Parses the string and tests if the string matches the rule. `rule` can be a string, a regular expression or a function.
|
||
|
|
||
|
``` js
|
||
|
var pattern = new Pattern('posts/:id');
|
||
|
|
||
|
pattern.match('posts/89');
|
||
|
// {0: 'posts/89', 1: '89', id: '89'}
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
var pattern = new Pattern('posts/*path');
|
||
|
|
||
|
pattern.match('posts/2013/hello-world');
|
||
|
// {0: 'posts/2013/hello-world', 1: '2013/hello-world', path: '2013/hello-world'}
|
||
|
```
|
||
|
|
||
|
### Permalink(rule, [options])
|
||
|
|
||
|
Parses a permalink.
|
||
|
|
||
|
Option | Description
|
||
|
--- | ---
|
||
|
`segments` | Customize the rule of a segment in the permalink
|
||
|
|
||
|
``` js
|
||
|
var permalink = new Permalink(':year/:month/:day/:title', {
|
||
|
segments: {
|
||
|
year: /(\d{4})/,
|
||
|
month: /(\d{2})/,
|
||
|
day: /(\d{2})/
|
||
|
}
|
||
|
});
|
||
|
|
||
|
permalink.parse('2014/01/31/test');
|
||
|
// {year: '2014', month: '01', day: '31', title: 'test'}
|
||
|
|
||
|
permalink.test('2014/01/31/test');
|
||
|
// true
|
||
|
|
||
|
permalink.stringify({year: '2014', month: '01', day: '31', title: 'test'})
|
||
|
// 2014/01/31/test
|
||
|
```
|
||
|
|
||
|
### prettyUrls(url, [options])
|
||
|
|
||
|
Rewrite urls to pretty URLs.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`trailing_index` | `/about/index.html -> /about/` when `false` | `true`
|
||
|
`trailing_html` | `/about.html -> /about` when `false` | `true`
|
||
|
|
||
|
Note: `trailing_html` ignores any link with a trailing `index.html`. (will not be rewritten to `index`).
|
||
|
|
||
|
``` js
|
||
|
prettyUrls('/foo/bar.html');
|
||
|
// /foo/bar.html
|
||
|
prettyUrls('/foo/bar/index.html');
|
||
|
// /foo/bar/index.html
|
||
|
|
||
|
prettyUrls('/foo/bar.html', { trailing_index: false });
|
||
|
// /foo/bar.html
|
||
|
prettyUrls('/foo/bar/index.html', { trailing_index: false });
|
||
|
// /foo/bar/
|
||
|
|
||
|
prettyUrls('/foo/bar.html', { trailing_html: false });
|
||
|
// /foo/bar
|
||
|
prettyUrls('/foo/bar/index.html', { trailing_html: false });
|
||
|
// /foo/bar/index.html
|
||
|
|
||
|
prettyUrls('/foo/bar.html', { trailing_index: false, trailing_html: false });
|
||
|
// /foo/bar
|
||
|
prettyUrls('/foo/bar/index.html', { trailing_index: false, trailing_html: false });
|
||
|
// /foo/bar/
|
||
|
```
|
||
|
|
||
|
### prismHighlight(str, [options])
|
||
|
|
||
|
Syntax highlighting for a code block using PrismJS.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`lineNumber` | Whether to show line numbers | true
|
||
|
`lang` | Language | `'none'`
|
||
|
`tab`| Replace tabs |
|
||
|
`isPreprocess` | Enable preprocess or not | true
|
||
|
`mark` | Highlight specific line |
|
||
|
`firstLine` | First line number |
|
||
|
`caption` | Caption |
|
||
|
|
||
|
When `isPreprocess` is enabled, `prismHighlight()` will return PrismJS processed HTML snippet. Otherwise `str` will only be escaped and `prismHighlight()` will return the HTML snippet that is suitable for `prism.js` working in the Browser.
|
||
|
|
||
|
`mark` and `firstLine` options will have effect only when `isPreprocess` is disabled.
|
||
|
|
||
|
### relative_url(from, to)
|
||
|
|
||
|
Returns the relative URL from `from` to `to`. Output is [encoded](#encodeurlstr) automatically. Requires [`bind(hexo)`](#bindhexo).
|
||
|
|
||
|
``` js
|
||
|
relative_url('foo/bar/', 'css/style.css')
|
||
|
// ../../css/style.css
|
||
|
```
|
||
|
|
||
|
### slugize(str, [options])
|
||
|
|
||
|
Transforms a string into a clean URL-friendly string.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`separator` | Separator | -
|
||
|
`transform` | Transform the string into lower case (`1`) or upper case (`2`) |
|
||
|
|
||
|
``` js
|
||
|
slugize('Hello World') = 'Hello-World'
|
||
|
slugize('Hellô Wòrld') = 'Hello-World'
|
||
|
slugize('Hello World', {separator: '_'}) = 'Hello_World'
|
||
|
slugize('Hello World', {transform: 1}) = 'hello-world'
|
||
|
slugize('Hello World', {transform: 2}) = 'HELLO-WORLD'
|
||
|
```
|
||
|
|
||
|
### spawn(command, [args], [options])
|
||
|
|
||
|
Launches a new process with the given `command`. This method returns a promise.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`cwd` | Current working directory of the child process |
|
||
|
`env` | Environment key-value pairs |
|
||
|
`stdio` | Child's stdio configuration | `pipe`
|
||
|
`detached` | The child will be a process group leader |
|
||
|
`uid` | Sets the user identity of the process |
|
||
|
`gid` | Sets the group identity of the process |
|
||
|
`verbose` | Display messages on the console | `false`
|
||
|
`encoding` | Sets the encoding of the output string | `utf8`
|
||
|
|
||
|
More info: [`child_process.spawn()`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)
|
||
|
|
||
|
``` js
|
||
|
spawn('cat', 'test.txt').then((content) => {
|
||
|
console.log(content);
|
||
|
});
|
||
|
|
||
|
// $ cd "/target/folder"
|
||
|
// $ cat "foo.txt" "bar.txt"
|
||
|
spawn('cat', ['foo.txt', 'bar.txt'], { cwd: '/target/folder' }).then((content) => {
|
||
|
console.log(content);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### stripHTML(str)
|
||
|
|
||
|
Removes HTML tags in a string.
|
||
|
|
||
|
### stripIndent(str)
|
||
|
|
||
|
Strip leading whitespace from each line in a string. The line with the least number of leading whitespace, ignoring empty lines, determines the number to remove. Useful for removing redundant indentation.
|
||
|
|
||
|
### wordWrap(str, [options])
|
||
|
|
||
|
Wraps the string no longer than line width. This method breaks on the first whitespace character that does not exceed line width.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`width` | Line width | 80
|
||
|
|
||
|
``` js
|
||
|
wordWrap('Once upon a time')
|
||
|
// Once upon a time
|
||
|
|
||
|
wordWrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
|
||
|
// Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...
|
||
|
|
||
|
wordWrap('Once upon a time', {width: 8})
|
||
|
// Once\nupon a\ntime
|
||
|
|
||
|
wordWrap('Once upon a time', {width: 1})
|
||
|
// Once\nupon\na\ntime
|
||
|
```
|
||
|
|
||
|
### tocObj(str, [options])
|
||
|
|
||
|
Generate a table of contents in JSON format based on the given html string. Headings with attribute `data-toc-unnumbered="true"` will be marked as unnumbered.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`min_depth` | The minimum level of TOC | 1
|
||
|
`max_depth` | The maximum level of TOC | 6
|
||
|
|
||
|
|
||
|
``` js
|
||
|
const html = [
|
||
|
'<h1 id="title_1">Title 1</h1>',
|
||
|
'<div id="title_1_1"><h2>Title 1.1</h2></div>',
|
||
|
'<h3 id="title_1_1_1">Title 1.1.1</h3>',
|
||
|
'<h2 id="title_1_2">Title 1.2</h2>',
|
||
|
'<h2 id="title_1_3">Title 1.3</h2>',
|
||
|
'<h3 id="title_1_3_1">Title 1.3.1</h3>',
|
||
|
'<h1 id="title_2">Title 2</h1>',
|
||
|
'<h2 id="title_2_1">Title 2.1</h2>'
|
||
|
].join('\n');
|
||
|
|
||
|
tocObj(html);
|
||
|
/*
|
||
|
[
|
||
|
{ text: 'Title 1', id: 'title_1', level: 1 },
|
||
|
{ text: 'Title 1.1', id: 'title_1_1', level: 2 },
|
||
|
{ text: 'Title 1.1.1', id: 'title_1_1_1', level: 3 },
|
||
|
{ text: 'Title 1.2', id: 'title_1_2', level: 2 },
|
||
|
{ text: 'Title 1.3', id: 'title_1_3', level: 2 },
|
||
|
{ text: 'Title 1.3.1', id: 'title_1_3_1', level: 3 },
|
||
|
{ text: 'Title 2', id: 'title_2', level: 1 },
|
||
|
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
|
||
|
]
|
||
|
*/
|
||
|
|
||
|
tocObj(html, { min_depth: 2 });
|
||
|
/*
|
||
|
[
|
||
|
{ text: 'Title 1.1', id: 'title_1_1', level: 2 },
|
||
|
{ text: 'Title 1.1.1', id: 'title_1_1_1', level: 3 },
|
||
|
{ text: 'Title 1.2', id: 'title_1_2', level: 2 },
|
||
|
{ text: 'Title 1.3', id: 'title_1_3', level: 2 },
|
||
|
{ text: 'Title 1.3.1', id: 'title_1_3_1', level: 3 },
|
||
|
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
|
||
|
]
|
||
|
*/
|
||
|
|
||
|
tocObj(html, { max_depth: 2 });
|
||
|
/*
|
||
|
[
|
||
|
{ text: 'Title 1', id: 'title_1', level: 1 },
|
||
|
{ text: 'Title 1.1', id: 'title_1_1', level: 2 },
|
||
|
{ text: 'Title 1.2', id: 'title_1_2', level: 2 },
|
||
|
{ text: 'Title 1.3', id: 'title_1_3', level: 2 },
|
||
|
{ text: 'Title 2', id: 'title_2', level: 1 },
|
||
|
{ text: 'Title 2.1', id: 'title_2_1', level: 2 },
|
||
|
]
|
||
|
*/
|
||
|
|
||
|
tocObj('<h1 id="reference" data-toc-unnumbered="true">Reference</h1>')
|
||
|
/*
|
||
|
[
|
||
|
{ text: 'Reference', id: 'reference', level: 1, unnumbered: true }
|
||
|
]
|
||
|
*/
|
||
|
```
|
||
|
|
||
|
### truncate(str, [options])
|
||
|
|
||
|
Truncates a given text after a given `length` if text is longer than `length`. The last characters will be replaced with the `omission` option for a total length not exceeding `length`.
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`length` | Max length of the string | 30
|
||
|
`omission` | Omission text | ...
|
||
|
`separator` | truncate text at a natural break |
|
||
|
|
||
|
``` js
|
||
|
truncate('Once upon a time in a world far far away')
|
||
|
// "Once upon a time in a world..."
|
||
|
|
||
|
truncate('Once upon a time in a world far far away', {length: 17})
|
||
|
// "Once upon a ti..."
|
||
|
|
||
|
truncate('Once upon a time in a world far far away', {length: 17, separator: ' '})
|
||
|
// "Once upon a..."
|
||
|
|
||
|
truncate('And they found that many people were sleeping better.', {length: 25, omission: '... (continued)'})
|
||
|
// "And they f... (continued)"
|
||
|
```
|
||
|
|
||
|
### unescapeHTML(str)
|
||
|
|
||
|
Unescapes HTML entities in a string.
|
||
|
|
||
|
``` js
|
||
|
unescapeHTML('<p>Hello "world".</p>')
|
||
|
// <p>Hello "world".</p>
|
||
|
```
|
||
|
|
||
|
### url_for(path, [option])
|
||
|
|
||
|
Returns a url with the root path prefixed. Output is [encoded](#encodeurlstr) automatically. Requires [`bind(hexo)`](#bindhexo).
|
||
|
|
||
|
Option | Description | Default
|
||
|
--- | --- | ---
|
||
|
`relative` | Output relative link | Value of `config.relative_link`
|
||
|
|
||
|
``` yml
|
||
|
_config.yml
|
||
|
root: /blog/ # example
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
url_for('/a/path')
|
||
|
// /blog/a/path
|
||
|
```
|
||
|
|
||
|
Relative link, follows `relative_link` option by default
|
||
|
e.g. post/page path is '/foo/bar/index.html'
|
||
|
|
||
|
``` yml
|
||
|
_config.yml
|
||
|
relative_link: true
|
||
|
```
|
||
|
|
||
|
``` js
|
||
|
url_for('/css/style.css')
|
||
|
// ../../css/style.css
|
||
|
|
||
|
/* Override option
|
||
|
* you could also disable it to output a non-relative link,
|
||
|
* even when `relative_link` is enabled and vice versa.
|
||
|
*/
|
||
|
url_for('/css/style.css', {relative: false})
|
||
|
// /css/style.css
|
||
|
```
|
||
|
|
||
|
## bind(hexo)
|
||
|
|
||
|
Following utilities require `bind(hexo)` / `bind(this)` / `call(hexo, input)` / `call(this, input)` to parse the user config when initializing:
|
||
|
- [`full_url_for()`](#full_url_forpath)
|
||
|
- [`url_for()`](#url_forpath)
|
||
|
- [`relative_url()`](#relative_urlfrom-to)
|
||
|
|
||
|
Below examples demonstrate different approaches to creating a [helper](https://hexo.io/api/helper) (each example is separated by `/******/`),
|
||
|
|
||
|
``` js
|
||
|
// Single function
|
||
|
const url_for = require('hexo-util').url_for.bind(hexo);
|
||
|
|
||
|
hexo.extend.helper.register('test_url', (str) => {
|
||
|
return url_for(str);
|
||
|
})
|
||
|
|
||
|
|
||
|
/******/
|
||
|
// Multiple functions
|
||
|
const url_for = require('hexo-util').url_for.bind(hexo)
|
||
|
|
||
|
function testurlHelper(str) {
|
||
|
return url_for(str);
|
||
|
}
|
||
|
|
||
|
hexo.extend.helper.register('test_url', testurlHelper);
|
||
|
|
||
|
|
||
|
/******/
|
||
|
// Functions separated into different files.
|
||
|
// test_url.js
|
||
|
module.exports = function(str) {
|
||
|
const url_for = require('hexo-util').url_for.bind(this);
|
||
|
return url_for(str);
|
||
|
}
|
||
|
|
||
|
// index.js
|
||
|
hexo.extend.helper.register('test_url', require('./test_url'));
|
||
|
|
||
|
|
||
|
/******/
|
||
|
// Function.call() approach also works
|
||
|
const {url_for} = require('hexo-util');
|
||
|
module.exports = function(str) {
|
||
|
return url_for.call(this, str);
|
||
|
}
|
||
|
|
||
|
hexo.extend.helper.register('test_url', require('./test_url'));
|
||
|
|
||
|
|
||
|
/******/
|
||
|
// Separating functions into individual files
|
||
|
// Each file has multiple functions
|
||
|
// test_url.js
|
||
|
function testurlHelper(str) {
|
||
|
const url_for = require('hexo-util').url_for.bind(this);
|
||
|
return url_for(str);
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
testurlHelper: testurlHelper
|
||
|
}
|
||
|
|
||
|
// index.js
|
||
|
hexo.extend.helper.register('test_url', require('./test_url').testurlHelper);
|
||
|
```
|
||
|
|
||
|
## License
|
||
|
|
||
|
MIT
|
||
|
|
||
|
[Hexo]: http://hexo.io/
|