创建插件处理hexo图片

背景介绍

  • 在使用markdown编写hexo文档时我们会插入图片,一般需要将它和md文件放在一起,作为一个相对路径插入。但是默认情况下hexo并不能正确识别并处理它的地址
  • 因此需要自己创建一个插件处理它,当前使用的插件参考自 hexo-asset-image 不直接npm install使用它的原因是,这个插件本身也存在些问题,对他进行了些许修改

配置

  • 首先需要修改 _config.yml 文件,打开 post_asset_folder

    1
    post_asset_folder: true
  • 同时需要注意配置好如下两个配置

    1
    2
    3
    4
    # 部署后的链接
    url: https://tonyjiangwj.github.io
    # 网站根目录
    root: /
  • 在_config.yml中配置插件名称并启用它,我们命名它为asset-image

    1
    2
    3
    4
    # Extensions
    ## Plugins: https://hexo.io/plugins/
    asset-image:
    enable: true
  • 然后创建自己的插件,放在 scripts 目录下

    1
    2
    scripts
    | --> asset-image.js
  • asset-image.js内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    'use strict';
    var cheerio = require('cheerio');

    // http://stackoverflow.com/questions/14480345/how-to-get-the-nth-occurrence-in-a-string
    function getPosition(str, m, i) {
    return str.split(m, i).join(m).length;
    }

    hexo.extend.filter.register('after_post_render', function (data) {
    var config = hexo.config;
    if (config.post_asset_folder) {
    var link = data.permalink;
    var beginPos = getPosition(link, '/', 3);
    var appendLink = '/';
    // In hexo 3.1.1, the permalink of "about" page is like ".../about/index.html".
    // if not with index.html endpos = link.lastIndexOf('.') + 1 support hexo-abbrlink
    if (/.*\/index\.html$/.test(link)) {
    // when permalink is end with index.html, for example 2019/02/20/xxtitle/index.html
    // image in xxtitle/ will go to xxtitle/index/
    appendLink = '/index/';
    var endPos = link.lastIndexOf('.');
    }
    else {
    var endPos = link.lastIndexOf('/');
    }
    console.info && console.info('origin link:', link)
    link = link.substring(beginPos, endPos) + appendLink;
    console.info && console.info('resolved link:', link)

    var toprocess = ['excerpt', 'more', 'content'];
    for (var i = 0; i < toprocess.length; i++) {
    var key = toprocess[i];

    var $ = cheerio.load(data[key], {
    ignoreWhitespace: false,
    xmlMode: false,
    lowerCaseTags: false,
    decodeEntities: false
    });

    $('img').each(function () {
    if ($(this).attr('src')) {
    // For windows style path, we replace '\' to '/'.
    var src = $(this).attr('src').replace('\\', '/');
    if (!(/http[s]*.*|\/\/.*/.test(src)
    || /^\s+\//.test(src)
    || /^\s*\/uploads|images\//.test(src))) {
    // For "about" page, the first part of "src" can't be removed.
    // In addition, to support multi-level local directory.
    var linkArray = link.split('/').filter(function (elem) {
    return elem != '';
    });
    var srcArray = src.split('/').filter(function (elem) {
    return elem != '' && elem != '.';
    });
    if (srcArray.length > 1)
    srcArray.shift();
    src = srcArray.join('/');
    let imageSrc = config.root + '.' + link + src
    $(this).attr('src', imageSrc);
    console.info && console.info("update link as:-->" + imageSrc);
    }
    } else {
    console.info && console.info("no src attr, skipped...");
    console.info && console.info($(this));
    }
    });
    data[key] = $.html();
    }
    }
    });
  • 我们编写hexo文章的时候,hexo new {文章名称} 会同时创建同名的文件夹,然后插入图片时将文件放到这个文件夹内即可,在markdown中使用相对路径引用它

  • 编写完毕后,执行 hexo clean && hexo generate 即可重新生成正确的html文件,图片的src将会被替换成正确的地址。