Markdown interpretation (#237)

This commit is contained in:
Simon Lecoq
2021-04-18 16:15:17 +02:00
committed by GitHub
parent f451085c98
commit db603605bd
14 changed files with 240 additions and 49 deletions

View File

@@ -7,7 +7,7 @@
return null
//Load inputs
let {sections, user, limit, lines} = imports.metadata.plugins.stackoverflow.inputs({data, account, q})
let {sections, user, limit, lines, "lines.snippet":codelines} = imports.metadata.plugins.stackoverflow.inputs({data, account, q})
if (!user)
throw {error:{message:"You must provide a stackoverflow user id"}}
@@ -32,14 +32,14 @@
//Load and format answers
console.debug(`metrics/compute/${login}/plugins > stackoverflow > querying api for ${key}`)
const {data:{items}} = await imports.axios.get(`${api.user}/answers?site=stackoverflow&pagesize=${limit}&filter=${filters.answer}&${sort}`)
result[key] = items.map(item => format.answer(item, {imports, data}))
result[key] = await Promise.all(items.map(item => format.answer(item, {imports, data, codelines})))
console.debug(`metrics/compute/${login}/plugins > stackoverflow > loaded ${result[key].length} items`)
//Load related questions
const ids = result[key].map(({question_id}) => question_id).filter(id => id)
if (ids) {
console.debug(`metrics/compute/${login}/plugins > stackoverflow > loading ${ids.length} related items`)
const {data:{items}} = await imports.axios.get(`${api.base}/questions/${ids.join(";")}?site=stackoverflow&filter=${filters.question}`)
items.map(item => format.question(item, {imports, data}))
await Promise.all(items.map(item => format.question(item, {imports, data, codelines})))
}
}
@@ -48,14 +48,14 @@
//Load and format questions
console.debug(`metrics/compute/${login}/plugins > stackoverflow > querying api for ${key}`)
const {data:{items}} = await imports.axios.get(`${api.user}/questions?site=stackoverflow&pagesize=${limit}&filter=${filters.question}&${sort}`)
result[key] = items.map(item => format.question(item, {imports, data}))
result[key] = await Promise.all(items.map(item => format.question(item, {imports, data, codelines})))
console.debug(`metrics/compute/${login}/plugins > stackoverflow > loaded ${result[key].length} items`)
//Load related answers
const ids = result[key].map(({accepted_answer_id}) => accepted_answer_id).filter(id => id)
if (ids) {
console.debug(`metrics/compute/${login}/plugins > stackoverflow > loading ${ids.length} related items`)
const {data:{items}} = await imports.axios.get(`${api.base}/answers/${ids.join(";")}?site=stackoverflow&filter=${filters.answer}`)
items.map(item => format.answer(item, {imports, data}))
await Promise.all(items.map(item => format.answer(item, {imports, data, codelines})))
}
}
@@ -74,9 +74,13 @@
const format = {
/**Cached */
cached:new Map(),
/**Format stackoverflow code snippets */
code(text) {
return text.replace(/<!-- language: lang-(?<lang>\w+) -->\s*(?<snippet> {4}[\s\S]+?)(?=(?:<!-- end snippet -->)|(?:<!-- language: lang-))/g, "```$<lang>\n$<snippet>```")
},
/**Format answers */
answer({body_markdown:body, score, up_vote_count:upvotes, down_vote_count:downvotes, is_accepted:accepted, comment_count:comments = 0, creation_date, owner:{display_name:author}, link, answer_id:id, question_id}, {imports, data}) {
const formatted = {type:"answer", body:imports.htmlunescape(body), score, upvotes, downvotes, accepted, comments, author, created:imports.date(creation_date*1000, {dateStyle:"short", timeZone:data.config.timezone?.name}), link, id, question_id,
async answer({body_markdown:body, score, up_vote_count:upvotes, down_vote_count:downvotes, is_accepted:accepted, comment_count:comments = 0, creation_date, owner:{display_name:author}, link, answer_id:id, question_id}, {imports, data, codelines}) {
const formatted = {type:"answer", body:await imports.markdown(format.code(imports.htmlunescape(body)), {codelines}), score, upvotes, downvotes, accepted, comments, author, created:imports.date(creation_date*1000, {dateStyle:"short", timeZone:data.config.timezone?.name}), link, id, question_id,
get question() {
return format.cached.get(`q${this.question_id}`) ?? null
},
@@ -85,8 +89,8 @@
return formatted
},
/**Format questions */
question({title, body_markdown:body, score, up_vote_count:upvotes, down_vote_count:downvotes, favorite_count:favorites, tags, is_answered:answered, answer_count:answers, comment_count:comments, view_count:views, creation_date, owner:{display_name:author}, link, question_id:id, accepted_answer_id = null}, {imports, data}) {
const formatted = {type:"question", title:imports.htmlunescape(title), body:imports.htmlunescape(body), score, upvotes, downvotes, favorites, tags, answered, answers, comments, views, author, created:imports.date(creation_date*1000, {dateStyle:"short", timeZone:data.config.timezone?.name}), link, id, accepted_answer_id,
async question({title, body_markdown:body, score, up_vote_count:upvotes, down_vote_count:downvotes, favorite_count:favorites, tags, is_answered:answered, answer_count:answers, comment_count:comments, view_count:views, creation_date, owner:{display_name:author}, link, question_id:id, accepted_answer_id = null}, {imports, data, codelines}) {
const formatted = {type:"question", title:await imports.markdown(title), body:await imports.markdown(format.code(imports.htmlunescape(body)), {codelines}), score, upvotes, downvotes, favorites, tags, answered, answers, comments, views, author, created:imports.date(creation_date*1000, {dateStyle:"short", timeZone:data.config.timezone?.name}), link, id, accepted_answer_id,
get answer() {
return format.cached.get(`a${this.accepted_answer_id}`) ?? null
},

View File

@@ -41,9 +41,18 @@ inputs:
max: 30
# Number of lines to display per question or answer
# Code snippets will take one line slot and should be configured with "plugin_stackoverflow_lines_snippet" instead
# Set to 0 to disable limitations
plugin_stackoverflow_lines:
description: Maximum number of lines to display per question or answer
type: number
default: 4
min: 0
min: 0
# Number of lines to display per code snippet
# Set to 0 to disable limitations
plugin_stackoverflow_lines_snippet:
description: Maximum number of lines to display per code snippet
type: number
default: 2
min: 0