Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: header extraction improvement (close: #238) #271

Merged
merged 3 commits into from
Apr 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions lib/util/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
const parseEmojis = str => {
const emojiData = require('markdown-it-emoji/lib/data/full.json')
return str.replace(/:(.+?):/g, (placeholder, key) => emojiData[key] || placeholder)
}
const parseHeaders = require('./parseHeaders')

exports.normalizeHeadTag = tag => {
if (typeof tag === 'string') {
Expand Down Expand Up @@ -35,11 +32,11 @@ exports.inferTitle = function (frontmatter) {
return 'Home'
}
if (frontmatter.data.title) {
return parseEmojis(frontmatter.data.title)
return parseHeaders(frontmatter.data.title)
}
const match = frontmatter.content.trim().match(/^#+\s+(.*)/)
if (match) {
return parseEmojis(match[1])
return parseHeaders(match[1])
}
}

Expand Down Expand Up @@ -71,7 +68,7 @@ exports.extractHeaders = (content, include = [], md) => {
const res = []
tokens.forEach((t, i) => {
if (t.type === 'heading_open' && include.includes(t.tag)) {
const title = parseEmojis(tokens[i + 1].content)
const title = parseHeaders(tokens[i + 1].content)
const slug = t.attrs.find(([name]) => name === 'id')[1]
res.push({
level: parseInt(t.tag.slice(1), 10),
Expand Down
29 changes: 29 additions & 0 deletions lib/util/parseHeaders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const parseEmojis = str => {
const emojiData = require('markdown-it-emoji/lib/data/full.json')
return str.replace(/:(.+?):/g, (placeholder, key) => emojiData[key] || placeholder)
}

const unescapeHtml = html => html
.replace(/"/g, '"')
.replace(/'/g, '\'')
.replace(/:/g, ':')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')

const removeMarkdownToken = str => str
.replace(/`(.*)`/, '$1') // ``
.replace(/\[(.*)\]\(.*\)/, '$1') // []()
.replace(/\*\*(.*)\*\*/, '$1') // **
.replace(/\*(.*)\*/, '$1') // *
.replace(/_(.*)_/, '$1') // _

// put here to avoid circular references
const compose = (...processors) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checking of the processors.length seems unnecessary. Perhaps something like this?

const compose = (...processors) => {
  return processors.reduce((prev, next) => {
    return (...args) => next(prev(...args))
  }, x => x)
}

Or

const compose = (...processors) => {
  return [
    x => x,
    ...processors
  ].reduce((prev, next) => {
    return (...args) => next(prev(...args))
  })
}

Copy link
Member Author

@ulivz ulivz Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm? Are you telling me how to write code?

Code should be as easy as possible to understand, don't always think about drag racing.

If you expect me to make a change, first give redux a PR.

Copy link
Member

@yyx990803 yyx990803 Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ulivz I also prefer easier to read code, but this is open source and @ycmjason is just offering what he thinks might be better code. He is not telling you how to write code and you don't have to be combative about this.

Copy link
Member Author

@ulivz ulivz Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yyx990803 Yes, I should say convincing reasons instead of arguing for it.

@ycmjason I'm terribly sorry about my recklessness, and I liked the style what you said above, but, after a long time, I found I always need to think back to what parameters of reduce's callback needs to accept. Until one day I read the source code of Redux, I found it's easier to undestand. so I'd like this style.

if (processors.length === 0) return input => input
if (processors.length === 1) return processors[0]
return processors.reduce((prev, next) => {
return (...args) => next(prev(...args))
})
}

module.exports = compose(unescapeHtml, parseEmojis, removeMarkdownToken)