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

Add heading and line highlighting to code blocks #1034

Merged
merged 4 commits into from
Mar 7, 2020

Conversation

nbriannl
Copy link
Contributor

@nbriannl nbriannl commented Feb 9, 2020

Note: Will take out of WIP when #991 is approved

Note: This branch is a rebase over #991 in order to work on top of his changes. Will rebase over master once #991 is merged

What is the purpose of this pull request? (put "X" next to an item, remove the rest)

• [X] Enhancement to an existing feature

Code headings fixes #646 #645
Partially fixes the requirements of line highlighting in #473

What is the rationale for this request?

For MarkBind to be a developer documentation tool, can be helpful to indicate the language of a code block in the block itself. To make the usage more general, any heading test can be optionally added to a code block, be it a file name & extension, the language used, or a generic heading.

Also, it would be good to be able to highlight specific lines of the code block, so to allow the author to emphasis certain lines.

What changes did you make? (Give an overview)

Because the following are markdown-it-attrs, you can use the original fenced code syntax if you do not want to use these feature.

We overwrite the markdown-it rule for fenced code blocks, to add a heading (which is a div) if a heading is specified as an attribute.

As for the highlight-lines attribute, firstly, the values are parsed into ranges. Secondly, we add upon the implementation of the map function in #991 that maps each lines into spans. What this addition is is that if the current line is within any of the ranges that is intended to be highlighted, it is then given the CSS class "highlighted". This also means that it is ok to give an invalid ranges, i.e. a line number that is out of bounds of the number of lines in the code, because the lines are checked against the ranges and not the other way around.

CSS changes were also made to enable styling and position of the heading div with respect to the div containing the code.

The headings are meant to be additional (and possibly unimportant) info. That's why they are on the right rather than left, away from the readers main path of reading.

Hence, the following design, here is how it looks like

image

image

Provide some example code that this change will affect:
Add the following syntax to any test site and serve

```xml
<foo>
  <bar type="name">goo</bar>
</foo>
```
```xml {heading="html"}
<foo>
  <bar type="name">goo</bar>
</foo>
```
```nginx {heading="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."}
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
}
```
```nginx {heading="This is like a box heading" highlight-lines="1,4-7,8,11-55"}
user  www www;
worker_processes  2;
pid /var/run/nginx.pid;
error_log  /var/log/nginx.error_log  debug | info | notice | warn | error | crit;

events {
    connections   2000;
    use kqueue | rtsig | epoll | /dev/poll | select | poll;
}

server { # simple reverse-proxy
    listen       80;
    server_name  domain2.com www.domain2.com;
    access_log   logs/domain2.access.log  main;
} 
# It is ok to specify a range greater than the lines of the code block
```

Is there anything you'd like reviewers to focus on?

Please comment if the styling of the component can be improved.

Proposed commit message: (wrap lines at 72 characters)

Add heading and line highlighting to code blocks

@nbriannl nbriannl changed the title [WIP] Add heading to code blocks and highlights [WIP] Add heading to code blocks and line highlights Feb 9, 2020
@nbriannl nbriannl changed the title [WIP] Add heading to code blocks and line highlights [WIP] Add heading to code blocks and line highlighting Feb 9, 2020
@nbriannl nbriannl changed the title [WIP] Add heading to code blocks and line highlighting [WIP] Add heading and line highlighting to code blocks Feb 9, 2020
@nbriannl nbriannl force-pushed the code-heading-highlights branch 2 times, most recently from 8e578eb to 90df946 Compare February 9, 2020 09:23
@nbriannl nbriannl changed the title [WIP] Add heading and line highlighting to code blocks Add heading and line highlighting to code blocks Feb 9, 2020
@alyip98
Copy link
Contributor

alyip98 commented Feb 9, 2020

I think it looks weird to have the heading box on the right, its usually on the left.

I personally prefer the look of the previous implementation more than the heading box

And we could add a bit of CSS to solve the previously mentioned issues

.code-block:hover > .code-block-lang {
    display: none;
}

@damithc
Copy link
Contributor

damithc commented Feb 9, 2020

I think it looks weird to have the heading box on the right, its usually on the left.

Heading is a misnomer; these are meant to be additional (and possibly unimportant) info. That's why they are on the right rather than left, away from the readers main path of reading.

And we could add a bit of CSS to solve the previously mentioned issues

What about when the page is converted to pdf?

@damithc
Copy link
Contributor

damithc commented Feb 9, 2020

In terms of saving vertical space, perhaps we can make the heading overlap with the box about half a line height? Not sure how it will look though. Can try it out.
image

@nbriannl
Copy link
Contributor Author

nbriannl commented Feb 9, 2020

Heading is a misnomer

Then, should it be given another name, like 'alt-text'?

@damithc
Copy link
Contributor

damithc commented Feb 9, 2020

Then, should it be given another name, like 'alt-text'?

I think we should. alt-text might not work though, as it already is used for a different purpose (in HTML).

@alyip98
Copy link
Contributor

alyip98 commented Feb 9, 2020

What about when the page is converted to pdf?

We could use the .d-print-none class provided by Bootstrap to hide it from print.

@damithc
Copy link
Contributor

damithc commented Feb 9, 2020

We could use the .d-print-none class provided by Bootstrap to hide it from print.

The user may not want to hide it from the print.

@nbriannl
Copy link
Contributor Author

image

In terms of saving vertical space, perhaps we can make the heading overlap with the box about half a line height? Not sure how it will look though. Can try it out.

This is how it looks like

@nbriannl
Copy link
Contributor Author

image

As discussed, this is the final one.

Copy link
Contributor

@marvinchin marvinchin left a comment

Choose a reason for hiding this comment

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

Thanks for looking at this! Perhaps you can consider changing the base branch to be #991 instead of master to make it easier to review subsequently. I forgot that we work on different forks here 😅

position: relative;
}

.code-block > .code-block-heading {
Copy link
Contributor

Choose a reason for hiding this comment

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

.code-block-heading sounds specific enough without having to further qualify it with .code-block >. Let's remove the unnecessary qualifiers.

</span>
</include>

##### Using them altogether
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel that this section isn't very necessary, since combining selectors should be fairly self explanatory. I'd lean towards removing this section to avoid bloating the user guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Turns out we do need it 😅

let highlightLines = token.attrGet('highlight-lines')
let lineNumbers = []
if (highlightLines) {
lineNumbers = highlightLines.split(',').map(v => v.split('-').map(v => parseInt(v, 10)))
Copy link
Contributor

Choose a reason for hiding this comment

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

Some comments here to describe what the input format should look like would be helpful! It would make maintaining this code easier in the future.

Splitting up this line into several steps with well-named intermediate variables could help as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Edited.

return currentLineNumber === start
})
if (inRange) {
return `<span class="highlighted">${line || '&#x200B;'}</span>`;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can abstract the section ${line || '&#x200B;'} into a separate variable, to make it clearer that this is identical across both cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed.

@@ -45,17 +45,44 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => {
if (!highlighted) {
str = markdownIt.utils.escapeHtml(str);
}
let highlightLines = token.attrGet('highlight-lines')
Copy link
Contributor

Choose a reason for hiding this comment

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

You have missing ;s in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Turns out eslint ignores src/lib/markbind/src/lib/markdown-it/* 😱

if (heading) {
return `<div class='code-block'>`
+ `<div class='code-block-heading'><span>` + heading + `<span></div>`
+ `<div class='code-block-content'><pre><code ${slf.renderAttrs(token)}>${str}</code></pre></div>`
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above, lets abstract the common part into it's own variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Copy link
Contributor

@marvinchin marvinchin left a comment

Choose a reason for hiding this comment

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

I was playing around with the feature and found an issue when the heading is too long:
Screenshot 2020-02-13 at 11 10 50 PM

Perhaps we could either split it across several lines, or truncate it after a certain length?

@@ -45,17 +45,55 @@ markdownIt.renderer.rules.fence = (tokens, idx, options, env, slf) => {
if (!highlighted) {
str = markdownIt.utils.escapeHtml(str);
}

const linesToHighlight = token.attrGet('highlight-lines');
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think of this?
linesToHighlight -> highlightLinesInput
arrLinesToHighlight -> highlightLines

This is to make it clearer which is the raw input that needs to be processed, and which are the actual lines to be highlighted.

I generally also don't like using arr to denote arrays as it leads to unnecessary verbosity IMO. A well named plural variable should be sufficient to convey that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks good to me.

@nbriannl
Copy link
Contributor Author

I was playing around with the feature and found an issue when the heading is too long:
Screenshot 2020-02-13 at 11 10 50 PM

Perhaps we could either split it across several lines, or truncate it after a certain length?

overflow-wrap: break-word; does the trick.

@nbriannl nbriannl changed the title Add heading and line highlighting to code blocks [WIP] Add heading and line highlighting to code blocks Feb 15, 2020
@nbriannl
Copy link
Contributor Author

#991 has been merged. Ready for review.

@nbriannl nbriannl changed the title [WIP] Add heading and line highlighting to code blocks Add heading and line highlighting to code blocks Feb 26, 2020
const heading = token.attrGet('heading');
const codeBlockContent = `<pre><code ${slf.renderAttrs(token)}>${str}</code></pre>`;
if (heading) {
return `${'<div class=\'code-block\'>'
Copy link
Contributor

Choose a reason for hiding this comment

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

The nested string interpolation feels a little strange to me. I normally do prefer string interpolation to concatenation, but for multi-line strings it gets difficult to read. What do you think of this?

return '<div class="code-block">'
      + `<div class="code-block-heading"><span>${heading}<span></div>`
      + `<div class="code-block-content">${codeBlockContent}</div>`
      + '</div>';

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry if this diff was already included when I last reviewed it and I didn't catch it then 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done 👍

Copy link
Contributor

@marvinchin marvinchin left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@marvinchin marvinchin added this to the v2.11.1 milestone Feb 27, 2020
@yamgent
Copy link
Member

yamgent commented Mar 3, 2020

@nbriannl will need you to update the css files, thanks.

Added heading to code blocks

Add line highlighting to code blocks

Edit css

remove unit for length 0 css

(cherry picked from commit da7e23a)

Update User Guide

(cherry picked from commit aceb551)

Remove console log

(cherry picked from commit cd8cc26)

Update User Guide

Update User Guide

Update tests

Edit CSS

Edit CSS

Remove User Guide Section

Remove uneeded specifity

Rewrite code for clarity

Edit User Guide

Handle wrap for very long single word

Improve variable naming

Update test sites

Add note for optimization

Settle rebase

Reduce complexity of code sample in User Guide

rewrite return string
@nbriannl
Copy link
Contributor Author

nbriannl commented Mar 3, 2020

CSS files updated. @yamgent

@yamgent yamgent added the pr.Enhancement 📈 Enhancement to an existing feature label Mar 7, 2020
@yamgent yamgent merged commit 3a41773 into MarkBind:master Mar 7, 2020
@damithc
Copy link
Contributor

damithc commented Mar 7, 2020

@nbriannl the netlify preview of this PR has some hover over glitches. Are they being addressed elsewhere?
image

@nbriannl
Copy link
Contributor Author

nbriannl commented Mar 7, 2020

@damithc what is the hover over glitch specifically?

@damithc
Copy link
Contributor

damithc commented Mar 7, 2020

The page width seem to change as I scroll the page. In the top half of the page, the middle column seem to be wider than intended, which pushes the pageNav gets out of view (as seen from the screenshot) but things go back to normal in the 2nd half of the page. Scroll that specific page in the user guide from top to bottom while watching the width of the middle column. Let me know if you can't reproduce it.

@nbriannl
Copy link
Contributor Author

nbriannl commented Mar 7, 2020

I can reproduce it in this PR. #1077 has been raised regarding this.

@damithc
Copy link
Contributor

damithc commented Mar 7, 2020

I can reproduce it in this PR. #1077 has been raised regarding this.

Got it. Seems severe enough problem that needs to be fixed before the next release though. Are you working on it?

@nbriannl
Copy link
Contributor Author

nbriannl commented Mar 7, 2020

I was not working on it and this is the first time I'm aware regarding this. I'm investigating it now.

Tejas2805 added a commit to Tejas2805/markbind that referenced this pull request Mar 7, 2020
…nvert-to-code-block

* 'master' of https://github.com/MarkBind/markbind:
  Allow changing parameter properties (MarkBind#1075)
  Custom timezone for built-in timestamp (MarkBind#1073)
  Fix reload inconsistency when updating frontmatter (MarkBind#1068)
  Implement an api to ignore content in certain tags (MarkBind#1047)
  Enable AppVeyor CI (MarkBind#1040)
  Add heading and line highlighting to code blocks (MarkBind#1034)
  Add dividers and fix bug in siteNav (MarkBind#1063)
  Fixed navbar no longer covers modals (MarkBind#1070)
  Add copy code-block plugin (MarkBind#1043)
  Render plugins on dynamic resources (MarkBind#1051)
  Documentation for Implement no-* attributes for <box>  (MarkBind#1042)
  Migrate to bootstrap-vue popovers (MarkBind#1033)
  Refactor preprocess and url processing functions (MarkBind#1026)
  Add pageNav to Using Plugins Page (MarkBind#1062)

# Conflicts:
#	docs/userGuide/syntax/siteNavigationMenus.mbdf
Tejas2805 added a commit to Tejas2805/markbind that referenced this pull request Mar 9, 2020
* 'master' of https://github.com/MarkBind/markbind:
  2.12.0
  Update outdated test files
  Update vue-strap version to v2.0.1-markbind.37
  Fix refactor to processDynamicResources (MarkBind#1092)
  Implement lazy page building for markbind serve (MarkBind#1038)
  Add warnings for conflicting/deprecated component attribs (MarkBind#1057)
  Allow changing parameter properties (MarkBind#1075)
  Custom timezone for built-in timestamp (MarkBind#1073)
  Fix reload inconsistency when updating frontmatter (MarkBind#1068)
  Implement an api to ignore content in certain tags (MarkBind#1047)
  Enable AppVeyor CI (MarkBind#1040)
  Add heading and line highlighting to code blocks (MarkBind#1034)
  Add dividers and fix bug in siteNav (MarkBind#1063)
  Fixed navbar no longer covers modals (MarkBind#1070)
  Add copy code-block plugin (MarkBind#1043)
  Render plugins on dynamic resources (MarkBind#1051)
  Documentation for Implement no-* attributes for <box>  (MarkBind#1042)
  Migrate to bootstrap-vue popovers (MarkBind#1033)
  Refactor preprocess and url processing functions (MarkBind#1026)
  Add pageNav to Using Plugins Page (MarkBind#1062)
@nbriannl nbriannl deleted the code-heading-highlights branch April 16, 2020 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr.Enhancement 📈 Enhancement to an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Indicate the language of a code block
6 participants