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

Interactive synopsis Fix #2024 #3140

Merged
merged 29 commits into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
fe55d51
added html to react
yathomasi Dec 28, 2021
7eb7a3c
utility html to react parser
yathomasi Dec 28, 2021
d2491c4
using code component and minor changes
yathomasi Dec 28, 2021
0357010
added args linker plugin to add ids to options
yathomasi Dec 30, 2021
2db56e1
removed hover css
yathomasi Dec 30, 2021
551aae5
fixed selection logic
yathomasi Dec 30, 2021
65cd894
removed html to react dependency
yathomasi Dec 30, 2021
0897dbe
added anchor icon in front of list items
yathomasi Dec 31, 2021
aced399
update to fix only use args from square brackets
yathomasi Jan 3, 2022
532c3ec
show anchor icon on list hover
yathomasi Jan 4, 2022
5ab5723
added outline
yathomasi Jan 4, 2022
f433cc9
linkified whole arguments with parameters
yathomasi Jan 4, 2022
fee75df
allowed two level of square brackets nestings
yathomasi Jan 4, 2022
1ff0a76
made link icon visible on focus
yathomasi Jan 4, 2022
1d98d06
updated command linker to add hash links for args
yathomasi Jan 4, 2022
8392d9f
fix codeclimate
yathomasi Jan 4, 2022
9ed8ed8
added id attribute to respective inline code block
yathomasi Jan 5, 2022
27960ac
added id to list and paragraph instead
yathomasi Jan 5, 2022
b8d44a4
updated code component to use all props
yathomasi Jan 6, 2022
ce1530f
added ids for argument to respective code block
yathomasi Jan 6, 2022
d083248
used lodash has property for key check
yathomasi Jan 6, 2022
6515b73
replaced custom component with prism hook
yathomasi Jan 7, 2022
6013dd2
generalized the arg regex
yathomasi Jan 8, 2022
3debb34
updated command linker
yathomasi Jan 8, 2022
aebacd4
reduced line for code climate fix
yathomasi Jan 8, 2022
ee52a0e
used same link icon source for consistency
yathomasi Jan 10, 2022
301b0aa
added pathname params
yathomasi Jan 11, 2022
b99fd5c
code fixes
yathomasi Jan 11, 2022
59363d3
aligned the icons
yathomasi Jan 11, 2022
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
10 changes: 10 additions & 0 deletions config/prismjs/dvc-hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* eslint-env node */

const Prism = require('prismjs')
const argsRegex = new RegExp(/\-{1,2}[a-zA-Z-]*/, 'ig')

// Make sure the $ part of the command prompt in shell
// examples isn't copiable by making it an 'input' token.
Expand All @@ -17,3 +18,12 @@ Prism.hooks.add('after-tokenize', env => {
}
}
})

Prism.hooks.add('wrap', env => {
if (env.language === 'usage' && env.type === 'arg') {
const { content } = env
env.tag = 'a'
const href = content.match(argsRegex)[0]
env.attributes.href = `#${href}`
}
})
8 changes: 8 additions & 0 deletions config/prismjs/usage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,13 @@ Prism.languages.usage = {
},
usage: {
pattern: /(^|\n)\s*(usage|positional arguments|optional arguments)/
},
args: {
pattern: /(?<=\[)(?:[^\]\[]+|\[(?:[^\]\[]+|\[[^\]\[]*\])*\])*(?=\])/,
inside: {
arg: {
pattern: /\-{1,2}[^|]*/
}
}
}
}
10 changes: 9 additions & 1 deletion gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const apiMiddleware = require('./src/server/middleware/api')
const redirectsMiddleware = require('./src/server/middleware/redirects')
const makeFeedHtml = require('./plugins/utils/makeFeedHtml')
const { BLOG } = require('./src/consts')
const { linkIcon } = require('./static/icons')

const title = 'Data Version Control · DVC'
const description =
Expand Down Expand Up @@ -66,6 +67,12 @@ const plugins = [
plugins: [
'gatsby-remark-embedder',
'gatsby-remark-dvc-linker',
{
resolve: 'gatsby-remark-args-linker',
options: {
icon: linkIcon
}
},
{
resolve: 'gatsby-remark-prismjs',
options: {
Expand Down Expand Up @@ -97,7 +104,8 @@ const plugins = [
resolve: 'gatsby-remark-autolink-headers',
options: {
enableCustomId: true,
isIconAfterHeader: true
isIconAfterHeader: true,
icon: linkIcon
}
},
{
Expand Down
94 changes: 94 additions & 0 deletions plugins/gatsby-remark-args-linker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const visit = require('unist-util-visit')
const _ = require('lodash')

const argsRegex = new RegExp(/\-{1,2}[a-zA-Z-]*/, 'ig')

function patch(context, key, value) {
if (!_.has(context, key)) {
context[key] = value
}

return context[key]
}

const addIdAttrToNode = (node, id) => {
const data = patch(node, `data`, {})

patch(data, `id`, id)
patch(data, `htmlAttributes`, {})
patch(data, `hProperties`, {})
patch(data.htmlAttributes, `id`, id)
patch(data.hProperties, `id`, id)
}

module.exports = (
{ markdownAST },
{ icon = '', className = 'anchor', isIconAfterHeader = false }
) => {
visit(
markdownAST,
node =>
node.type === 'listItem' &&
node.children.some(
Copy link
Member

Choose a reason for hiding this comment

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

will it match lists like "- some text --flag"? also does it mean that we math lists outside the Options section?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it matches list with 1st line start with inline Code block i.e `` and that starts with -. Yes, If it exactly matches this then it's possible outside options too. We can work on this more if it collide but I found that unique for my quick overlook over the docs.

Copy link
Contributor

Choose a reason for hiding this comment

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

We do have a list that matches the pattern in our DVCLive docs: https://dvc-org-interactive-syn-zo8hwd.herokuapp.com/doc/dvclive/dvclive-with-dvc#--live-no-cache. Not sure if it does any harm to have links there... Though if we wanted, we could have gatsby-remark-args-linker only look through pages in our /command-reference/ directory 🤔

Copy link
Member

Choose a reason for hiding this comment

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

thanks, Julie and Thomas. q: how hard it is to make it strict and well-defined?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The possible way I could think of was to make it strict or well defined is by checking heading Options and looking into a consecutive list and to the list item.
But, I found it difficult to do so with Markdown AST. We could easily achieve that if we had something easy/well-defined APIs/functions as in DOM manipulation. Otherwise, we need to come up with some hacky way to do so.

Copy link
Member

Choose a reason for hiding this comment

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

sounds good, but it's also about replacing node.children.some with something like node.children.first

'docs/command-reference' - we need to make it a param? since it might be different across different websites later.

Copy link
Contributor

@julieg18 julieg18 Jan 7, 2022

Choose a reason for hiding this comment

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

sounds good, but it's also about replacing node.children.some with something like node.children.first

This would check the first child in the list, right? While this would work for almost all use cases /repro options starts with targets:

image

It is the only one as far as I know though :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops sorry, I missed this conversation.

Copy link
Contributor Author

@yathomasi yathomasi Jan 11, 2022

Choose a reason for hiding this comment

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

'docs/command-reference' - we need to make it a param? since it might be different across different websites later.

I have added the params for paths which can be a string(path) or an array of paths. For now, I have set it to docs/command-reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sounds good, but it's also about replacing node.children.some with something like node.children.first

I have made some changes and pushed.

item =>
item.type === 'paragraph' &&
item.children[0]?.type === 'inlineCode' &&
String(item.children[0]?.value).startsWith('-')
),
listItemNode => {
const isParagraphNode = listItemNode.children?.[0].type === 'paragraph'
if (!isParagraphNode) return
const paragraphNode = listItemNode.children[0]
const isFirstArgNode =
paragraphNode.children[0]?.type === 'inlineCode' &&
String(paragraphNode.children[0]?.value).startsWith('-')
if (isFirstArgNode) {
const firstArgNode = paragraphNode.children[0]
const value = firstArgNode.value
const id = value.match(argsRegex)[0]
addIdAttrToNode(firstArgNode, id)

const data = patch(listItemNode, `data`, {})
patch(data, `htmlAttributes`, {})
patch(data, `hProperties`, {})
if (icon) {
yathomasi marked this conversation as resolved.
Show resolved Hide resolved
patch(data.hProperties, `style`, `position:relative;`)
const label = id.split(`-`).join(` `)
const method = isIconAfterHeader ? `push` : `unshift`
listItemNode.children[method]({
type: `link`,
url: `#${id}`,
title: null,
children: [],
data: {
hProperties: {
'aria-label': `option ${label.trim()} permalink`,
class: `${className} ${isIconAfterHeader ? `after` : `before`}`
},
hChildren: [
{
type: `raw`,
// The Octicon link icon is the default. But users can set their own icon via the "icon" option.
value: icon
}
]
}
})
}

const isSecondArgNode =
String(paragraphNode.children[1]?.value).trim() === ',' &&
paragraphNode.children[2]?.type === 'inlineCode' &&
String(paragraphNode.children[2].value).startsWith('-')
if (isSecondArgNode) {
const secondArgNode = paragraphNode.children[2]
const value = secondArgNode.value
const id = value.match(argsRegex)[0]
addIdAttrToNode(secondArgNode, id)
}
}
}
)
// Manipulate AST
return markdownAST
}
12 changes: 12 additions & 0 deletions plugins/gatsby-remark-args-linker/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "gatsby-remark-args-linker",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
35 changes: 17 additions & 18 deletions plugins/gatsby-remark-dvc-linker/commandLinker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,32 @@ const { getItemByPath } = require('../../src/utils/shared/sidebar')

const DVC_REGEXP = /dvc\s+[a-z][a-z-.]*/
const COMMAND_REGEXP = /^[a-z][a-z-]*$/
const ARGS_REGEXP = new RegExp(/\-{1,2}[a-zA-Z-]*/, 'ig')
const COMMAND_ROOT = '/doc/command-reference/'

module.exports = astNode => {
const node = astNode[0]
const parent = astNode[2]

if (parent.type !== 'link' && DVC_REGEXP.test(node.value)) {
const parts = node.value.split(/\s+/)
const index = parts.findIndex(part => String(part).trim() === 'dvc')
const command = parts[index + 1]
const baseUrl = `${COMMAND_ROOT}${command}`
let url

const hasThirdSegment = parts[2] && COMMAND_REGEXP.test(parts[2])
const isCommandPageExists = getItemByPath(`${COMMAND_ROOT}${parts[1]}`)
const isSubcommandPageExists =
isCommandPageExists &&
hasThirdSegment &&
getItemByPath(`${COMMAND_ROOT}${parts[1]}/${parts[2]}`)

if (isSubcommandPageExists) {
url = `${COMMAND_ROOT}${parts[1]}/${parts[2]}`
} else if (isCommandPageExists && hasThirdSegment) {
url = `${COMMAND_ROOT}${parts[1]}#${parts[2]}`
} else if (isCommandPageExists) {
url = `${COMMAND_ROOT}${parts[1]}`
const isCommandPageExists = getItemByPath(baseUrl)
if (isCommandPageExists) {
url = baseUrl
for (const arg of parts.slice(index + 2)) {
if (arg && COMMAND_REGEXP.test(arg) && getItemByPath(`${url}/${arg}`)) {
url = `${url}/${arg}`
} else if (arg && ARGS_REGEXP.test(arg)) {
const id = arg.match(ARGS_REGEXP)[0]
url = `${url}#${id}`
break
}
}
createLinkNode(url, astNode)
}

createLinkNode(url, astNode)
}

return astNode
}
17 changes: 17 additions & 0 deletions src/components/Documentation/Markdown/Main/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,27 @@
}
}

a.token.arg {
color: var(--color-light-blue);
julieg18 marked this conversation as resolved.
Show resolved Hide resolved
outline-color: var(--color-light-blue-hover);
}

:global(a.gatsby-resp-image-link)::after {
content: unset;
}

li .anchor svg {
visibility: hidden;
}

li:hover .anchor svg {
visibility: visible;
}

li .anchor:focus svg {
visibility: visible;
}

.anchor {
margin-left: -24px;
}
Expand Down
4 changes: 4 additions & 0 deletions static/icons/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const svgIcon = `<svg aria-hidden="true" height="16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"/></svg>`
module.exports = {
linkIcon: svgIcon
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"target": "es5",
"module": "commonjs",
"resolveJsonModule": true,
"lib": ["dom", "es2015", "es2017"],
"lib": ["dom", "es2015", "es2017", "es2021"],
julieg18 marked this conversation as resolved.
Show resolved Hide resolved
"jsx": "react",
"sourceMap": true,
"strict": true,
Expand Down
Loading