Hexo + NexT (VI): Hexo taught you how to write a filter plug-in

Sense and Simplicity

Hexo+ NexTIntroduced here, I think it can be very good to complete the task. Some basic functions and configure it provides, have already been explained. You have the freedom to configure its own blog environment, then enjoy codeword.

The blog is hosted on Github, is a good idea, do not blogger's own space is certainly very welcome. In fact, after compiling the article, he is a very simple static website. The purpose of the deployment is simple static website folder copied to a repository Github's, then this repository as a Web site folder, and nothing more, is very simple. So, there is no talk of value.

However, as a Coderstudied Hexo, gotta be real skill points, put forward a plan to solve a pain point, and then implement it.

Of course there are pain points, each with Typoracode article, habits text pictures WYSIWYG, but unfortunately, Typorathe picture is handled, Hexodoes not endorse, after conversion urldisorder, not recognized. So, I hope Typoraand Hexoprocessing images in a uniform manner, Typoraand Hexocan be displayed properly after compilation.

No one solved, I wanted to fix it.

Hexo blog index page topic

1. Typora uniform resource file pictures and the NexT

In Typora, the picture can be saved using the relative position, and can be flexibly customized with article file name. If we are Typorain a position to save the image file specified as the article of the same name folder, then with the NexTresources folder provided to coincide with the.

In the Typoramiddle, the picture storage location is set ./${filename}, see Figure.

In NexTthe theme configuration file, open the folder resource functions, Hexoresources will target resource folder compile time, according to its reference page and given appropriate url.

post_asset_folder: true

If we put the two unite, we can in markdown article before the article is compiled into html, to achieve such a conversion

![img](postname/sample.jpg) => {%asset_img sample.jpg%}

That happy: in Typoracase the use of ![img](postname/sample.jpg)the use of pictures, enjoy WYSIWYG, into a resource file during compilation, automatically correct url, cake and eat it, perfect.

2. Solutions

2.1 Hexo understand the mode of operation

Research Hexoproject structure, the main page of the compilation process, which is the Hexo gcommand how to perform.

According to Hexoan overview of Hexothe project implementation process is as follows:

  1. initialization
  2. Loading files
  3. Executing instructions
  4. End

The first step: initialize

Initialization phase, creates Hexoinstances, various configurations, a variety of plug-ins, all the various extensions in place, waiting for loading paper processing.

HexoProject file management package by package.jsonintroducing a variety of plug-in extensions.

Step Two: Load File

Load sourceall the articles and style, scripts and other resources. If instruction, you may monitor changes in the following document file.

The third step: execution instruction

Instruction execution console, according to an instruction out the corresponding command.

Step Four: Exit

2.2 start point

The purpose to be achieved, mainly in the process of compiling the page, which is mainly in the rendering renderstage.

From Hexosource code can certainly find clues, but it is too cumbersome, speed is not fast. There is no other way.

A change of ideas under study Hexoprovided by the API, suddenly found, which is the extension of this.

Basically all extensions can too literally, the most likely place to start is the Filterfilter.

It put to the definition:

hexo.extend.filter.register(type, function(data){
}, priority);
  • typeThe type, indicates the type of type of filter, the filter is what does this mean? Well, see what type

    before_post_render, after_post_render, before_exit, before_generate, This is the time to insert the filter ah.

  • function(data)Is a callback function, this is well understood, which is datawhat is, to say back.

  • priority, typeIs the timing of the filter insert, if you insert multiple filters at the same timing, then the priorityimplementation of the order to decide, `priority small value on the first execution.

Focus render

Type filter (filter is the insertion point) In the above, there is an important type before_post_render, meaning that the implementation of the filter prior to rendering. Check Hexothe API, the rendering process is as follows:

  • Execution before_post_renderfilter
  • Use Markdown or other renderer (by extension may be)
  • Use Nunjucks rendering
  • Execution after_post_renderfilter

Well, then we get before_post_renderto try.

Prepare a 2.3 filter

Find an example to learn about

From https://hexo.io/plugins/looking for a simple example of a filter which, it is found that a particularly simple Nodepackage. For example, the filter plug hexo-filter-auto-spacingMMHy , its file list is as follows:

  • lib
    • renderer.js
  • README.md
  • index.js
  • package.json

Which it is useful package.jsonand index.js. And package.jsonalso is a typical Nodepackage file, its output target by the mainspecified field, in this case mainfield points index, is our index.jsfile.

Look at the index.jscontent

var assign = require('deep-assign');
var renderer = require('./lib/renderer');
hexo.extend.filter.register('before_post_render', renderer.render, 9);

Look again at /lib/renderer.jsthe content

var reg = /(\s*)(```) *(.*?) *\n?\[hide\]([\s\S]+?)\s*(\2)(\n+|$)/g;

function ignore(data) {
  var source = data.source;
  var ext = source.substring(source.lastIndexOf('.')).toLowerCase();
  return ['.js', '.css', '.html', '.htm'].indexOf(ext) > -1;
}

exports.render = function (data) {
  if (!ignore(data)) {

    data.content = data.content
      .replace(reg, function (raw, start, startQuote, lang, content, endQuote, end) {
        return start + end;
      });
  }
};

Too simple, for the above example, it is to realize the filter definition

hexo.extend.filter.register(type, function(data){
}, priority);

Zhaomaohuahu

And Hexoproject files side by side to create a new file node_modules, and new projects on the inside hexo-image2asset. Structured as follows:

├─guide2it-blog
│  ├─node_modules
│  ├─public
│  ├─scaffolds
│  ├─source
│  │  ├─about
│  │  │  └─index
│  │  ├─categories
│  │  ├─images
│  │  ├─tags
│  │  └─_posts
│  │      ├─2019-04-19-01测试插件.md
│  │      └─2019-04-19-01测试插件
│  │        └─guide2it.jpg
│  ├─themes
│  │  └─next
└─node_modules
    └─hexo-image2asset
      ├─package.json
      └─index.js

As to why it is, this is the lesson of blood. For the Nodeproject, the new module should be /guide2it-blog/node_modulesbelow the established before me, too, and later because of baffling problem, a universal repair Dafa delete node_modules & npm installafter, my hexo-image2assetproject can not find, riding a crane to the West.

And I put hexo-image2assetthe manner described above arrangement, it is also on the search path Node project, but also to avoid making the same mistakes universal repair Dafa.

Research data structure of the data

In order to clarify the callback function datastructure, I decided to use an example to test.

See 2019-04-19-01测试插件.mdcontent

---
内容略
---
测试hexo-image2asset插件
下面我要加入一张图片了。
![测试](2019-04-19-01测试插件/guide2it.jpg)

Then I write index.js, as follows:

var deal_image=function(data){
  console.log(data);
}
hexo.extend.filter.register('before_post_render', deal_image, 9);

Execution hexo gstimulate the rendering process.

Document {
  layout: 'post',
  title: '测试插件',
  date: moment("2019-03-05T09:00:00.000"),
  _content:
   '\n测试hexo-image2asset插件\n\n下面我要加入一张图片了。\n\n![测试](2019-04-19-01测试插件/guide2it.jpg)',
  source: '_posts/2019-04-19-01测试插件.md',
  raw:
   '---\nlayout: post\ntitle: \'测试插件\'\ndate: 2019/3/5 09:00:00\ncategory: [\'博客\',\'Hexo\']\ntags: [\'博客\',\'Hexo\',\'NexT\']\n---\n\n测试hexo-image2asset插件\n\n下面我要加入一张图片了。\n\n![测试](2019-04-19-01测试插件/guide2it.jpg)',
  slug: '01测试插件',
  published: true,
  updated: moment("2019-04-21T01:15:15.699"),
  comments: true,
  photos: [],
  link: '',
  _id: 'cjuprkojw0001o4d4cbawzsgo',
  path: [Getter],
  permalink: [Getter],
  full_source: [Getter],
  asset_dir: [Getter],
  tags: [Getter],
  categories: [Getter],
  content:
   '\n测试hexo-image2asset插件\n\n下面我要加入一张图片了。\n\n![测试](2019-04-19-01测试插件/guide2it.jpg)',
  site: { data: {} } }

So this datais Document, its contents and the structure shown above. With content related to the three main fields _content, contentand raw, rawrepresent the original article, _contentthis prefix _is usually internal attributes, can not move, then move contentthe content.

Accordance with the format required resource object, should

![测试](2019-04-19-01测试插件/guide2it.jpg)Converted to

{%asset_img guide2it.jpg 测试%}

Convert the picture object to the resource object

The need to use regular expressions to global transformation, the string has to be converted in the article name, the need to find out.

Shaped like a known source _posts/2019-04-19-01测试插件.md, the file name should be to find the right-most /, followed by the string to remove .md.

The establishment of a regular expression to be replaced, the []contents of a ()determined to $1put the picture file name ()is defined as $2the final regular expression as follows.

Plug-in index.jsfull as follows.

var deal_image = function(data) {
    var reverseSource = data.source.split("").reverse().join("");
    var fileName = reverseSource.substring(3, reverseSource.indexOf("/")).split("").reverse().join("");
    var regExp = RegExp("!\\[([^\\f\\n\\r\\t\\v\\[\\]]+)\\]\\(" + fileName +
        '\\/([^\\\\\\/\\:\\*\\?\\"\\<\\>\\|\\,\\)]+)\\)');
    data.content = data.content.replace(regExp, "{%asset_img $2 %}","g");
    return data;
}
hexo.extend.filter.register('before_post_render', deal_image, 9);

There is a bug, replacing the object is "{%asset_img $2 $1 %}", if a regular match %1is purely digital, it is interpreted as the width of the image, it seems beside the point. So temporarily $1removed.

Guess you like

Origin www.cnblogs.com/guide2it/p/11111715.html