Skip to content

如何批量指定文章中图片的高度

Smallpath edited this page Feb 26, 2017 · 1 revision

背景

![]()形式的图片在页面初始化时高度为0,当图片加载好时会恢复真实高度导致闪屏,另外会使TOC跳转到错误的位置。

因此,需要手动将![]()形式的托转为<img height="960" src="url">来指定高度,避免闪屏。

目前,博客新版的后台管理已经默认提供了这个功能,如果你使用的是旧版的博客后台编写的文章,那么可以使用如下的办法来批量指定文章中七牛云图片的高度

兼容

如下代码要求node v7.6.0或以上

const Marked = require('marked')
const hljs = require('highlight.js')
const request = require('axios')

const host = 'https://smallpath.me'
const userInfo = {
  name: 'admin',
  password: 'admin'
}

const renderer = new Marked.Renderer()
const toc = []

renderer.heading = function (text, level) {
  var slug = text.toLowerCase().replace(/\s+/g, '-')
  toc.push({
    level: level,
    slug: slug,
    title: text
  })
  return `<h${level}><a href='#${slug}' id='${slug}' class='anchor'></a><a href='#${slug}'>${text}</a></h${level}>`
}

Marked.setOptions({
  highlight: function (code, lang) {
    if (hljs.getLanguage(lang)) {
      return hljs.highlight(lang, code).value
    } else {
      return hljs.highlightAuto(code).value
    }
  },
  renderer
})

const marked = text => {
  var tok = Marked.lexer(text)
  text = Marked.parser(tok).replace(/<pre>/ig, '<pre class="hljs">')
  return text
}

const store = {}

store.login = (conditions) => {
  return request.post(`${host}/proxyPrefix/admin/login`, conditions)
}

store.getImageHeight = url => {
  return request.get(`${url}?imageInfo`).then(response => response.data.height)
}

store.patchByID = (model, id, form) => {
  let target = `${host}/proxyPrefix/api/${model}/${id}`
  console.log('patching: ', target)
  return request.patch(target, form).then((response) => {
    return response.data
  })
}

store.fetchList = (model, query) => {
  let target = `${host}/proxyPrefix/api/${model}`
  return request.get(target, { params: query }).then((response) => {
    return response.data
  })
}

(async () => {

  const data = await store.login(userInfo)

  const { token } = data.data;

  request.interceptors.request.use((config) => {

    if (config.method === 'get' && config.url.indexOf('/proxyPrefix/api/user') === -1) {
      return config
    }

    if (token !== null && typeof token !== 'undefined') {
      config.headers['authorization'] = token
    }

    return config
  }, (error) => Promise.reject(error))

  const list = await store.fetchList('post', {})

  const reg = /\!\[.*?\]\((.*?)\)/gm

  for (let post of list) {
    const { markdownContent, content } = post
    let matchedArr = markdownContent.match(reg)
    let obj = {
      markdownContent: markdownContent,
      content: content
    }
    if (matchedArr) {

      for (let matched of matchedArr) {
        matched = matched.match(/\!\[.*?\]\((.*?)\)/)

        const [strToBeReplaced, urlToGetHeight] = matched
        const skip = strToBeReplaced.includes('${') || strToBeReplaced.includes('githubusercontent')
        if (skip) continue

        const height = await store.getImageHeight(urlToGetHeight)

        let result = `<img height="${height}" src="${urlToGetHeight}">`
        obj.markdownContent = obj.markdownContent.replace(strToBeReplaced, result)
      }
      obj.content = marked(obj.markdownContent.replace(/<!--more-->/g, ''))
      await store.patchByID('post', post._id, obj)
    }
  }

})()

使用办法

将代码复制到index.js文件中,修改第5行的host为对应的博客域名,修改第6行的后台管理账号和密码。再进入该目录使用如下命令

npm install --save marked highlight.js axios
node index.js

等待如下的信息输出完即可:

➜  node index.js
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b276
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b278
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b279
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b27a
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b27b
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b280
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b27c
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b281
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b284
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b285
patching:  https://smallpath.me/proxyPrefix/api/post/580b3ff504f59b4cc27845f0
patching:  https://smallpath.me/proxyPrefix/api/post/5826897ad7d24b0cc614efd4
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b277
patching:  https://smallpath.me/proxyPrefix/api/post/58424a09ba27b9072e55d938
patching:  https://smallpath.me/proxyPrefix/api/post/587a38f14036c9194b7a937b
patching:  https://smallpath.me/proxyPrefix/api/post/58b13661e41f6f7b05082fdb
patching:  https://smallpath.me/proxyPrefix/api/post/584425cfba27b9072e55d93b
patching:  https://smallpath.me/proxyPrefix/api/post/58838d52be995c51f0c4a9de
patching:  https://smallpath.me/proxyPrefix/api/post/58609c254036c9194b7a935d
patching:  https://smallpath.me/proxyPrefix/api/post/58038562a8f83d12578a2888
patching:  https://smallpath.me/proxyPrefix/api/post/5837f170b1b9d11dfa050352
patching:  https://smallpath.me/proxyPrefix/api/post/57e7b31fa73182482918b286
Clone this wiki locally