Skip to content

Commit

Permalink
Support clever-links, monospace-lines, {@linkcode}, {@linkplain}. Mer…
Browse files Browse the repository at this point in the history
…ges PR #86
  • Loading branch information
75lb committed Aug 29, 2024
1 parent ad89b18 commit 8764d6b
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 31 deletions.
46 changes: 33 additions & 13 deletions helpers/ddata.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const objectGet = require('object-get')
const where = require('test-value').where
const flatten = require('reduce-flatten')
const state = require('../lib/state')
const urlRe = require('regex-repo').urlRe

let malformedDataWarningIssued = false

Expand Down Expand Up @@ -620,32 +621,35 @@ function methodSig () {
/**
* extracts url and caption data from @link tags
* @param {string} - a string containing one or more {@link} tags
* @returns {Array.<{original: string, caption: string, url: string}>}
* @param {object} - `dmdOptions`; link formatting is influenced by the `clever-links` and `monospace-links` values
* @returns {Array.<{original: string, caption: string, url: string, format: 'code'|'plain'}>}
* @static
*/
function parseLink (text) {
function parseLink (text, dmdOptions = {}) {
if (!text) return ''
const results = []
let matches = null
const link1 = /{@link\s+([^\s}|]+?)\s*}/g // {@link someSymbol}
const link2 = /\[([^\]]+?)\]{@link\s+([^\s}|]+?)\s*}/g // [caption here]{@link someSymbol}
const link3 = /{@link\s+([^\s}|]+?)\s*\|([^}]+?)}/g // {@link someSymbol|caption here}
const link4 = /{@link\s+([^\s}|]+?)\s+([^}|]+?)}/g // {@link someSymbol Caption Here}
const link1 = /{@link(code|plain)?\s+([^\s}|]+?)\s*}/g // {@link someSymbol}
const link2 = /\[([^\]]+?)\]{@link(code|plain)?\s+([^\s}|]+?)\s*}/g // [caption here]{@link someSymbol}
const link3 = /{@link(code|plain)?\s+([^\s}|]+?)\s*\|([^}]+?)}/g // {@link someSymbol|caption here}
const link4 = /{@link(code|plain)?\s+([^\s}|]+?)\s+([^}|]+?)}/g // {@link someSymbol Caption Here}

while ((matches = link4.exec(text)) !== null) {
results.push({
original: matches[0],
caption: matches[2],
url: matches[1]
caption: matches[3],
url: matches[2],
format: matches[1]
})
text = text.replace(matches[0], ' '.repeat(matches[0].length))
}

while ((matches = link3.exec(text)) !== null) {
results.push({
original: matches[0],
caption: matches[2],
url: matches[1]
caption: matches[3],
url: matches[2],
format: matches[1]
})
text = text.replace(matches[0], ' '.repeat(matches[0].length))
}
Expand All @@ -654,19 +658,35 @@ function parseLink (text) {
results.push({
original: matches[0],
caption: matches[1],
url: matches[2]
url: matches[3],
format: matches[2]
})
text = text.replace(matches[0], ' '.repeat(matches[0].length))
}

while ((matches = link1.exec(text)) !== null) {
results.push({
original: matches[0],
caption: matches[1],
url: matches[1]
caption: matches[2],
url: matches[2],
format: matches[1]
})
text = text.replace(matches[0], ' '.repeat(matches[0].length))
}

results.forEach((result) => {
const format = result.format
if (format === undefined) {
result.format = format // if tag is @linkplain or @linkcode, then that determines the format
// else, if 'clever-links' is true, then if the link is a URL, it's plain, otherwise code format
|| (dmdOptions['clever-links'] && (urlRe.test(result.url) ? 'plain' : 'code'))
// else, if 'monospace-links' is true, then all links are code format
|| (dmdOptions['monospace-links'] && 'code')
// else, it's a plain
|| 'plain'
}
})

return results
}

Expand Down
8 changes: 5 additions & 3 deletions helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,18 @@ function escape (input) {
}

/**
replaces {@link} tags with markdown links in the suppied input text
replaces {@link}, {@linkplain}, and {@linkcode} tags with markdown links in the supplied input text
*/
function inlineLinks (text, options) {
if (text) {
const links = ddata.parseLink(text)
const dmdOptions = options.data.root.options
const links = ddata.parseLink(text, dmdOptions)
links.forEach(function (link) {
const captionFmt = link.format === 'code' ? '`' : ''
const linked = ddata._link(link.url, options)
if (link.caption === link.url) link.caption = linked.name
if (linked.url) link.url = linked.url
text = text.replace(link.original, '[' + link.caption + '](' + link.url + ')')
text = text.replace(link.original, '[' + captionFmt + link.caption + captionFmt + '](' + link.url + ')')
})
}
return text
Expand Down
14 changes: 14 additions & 0 deletions lib/dmd-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ function DmdOptions (options) {
*/
this['member-index-format'] = 'grouped'

/**
* If true, \{@link XXX} tags are rendered in normal text if XXX is a URL and monospace (code) format otherwise.
* @type {boolean}
* @dafult
*/
this['clever-links'] = false

/**
* If true, all \{@link} tags are rendered in monospace (code) format. This setting is ignored in `clever-links` is true.
* @type {boolean}
* @default
*/
this['monospace-links'] = false

/**
* Show identifiers marked `@private` in the output.
* @type {boolean}
Expand Down
16 changes: 13 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"reduce-flatten": "^3.0.1",
"reduce-unique": "^2.0.1",
"reduce-without": "^1.0.1",
"regex-repo": "^5.0.0",
"test-value": "^3.0.0",
"walk-back": "^5.1.1"
},
Expand Down
Loading

0 comments on commit 8764d6b

Please sign in to comment.