-
Notifications
You must be signed in to change notification settings - Fork 142
Move markdown-it parsing to /markbind #975
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
Conversation
ang-zeyu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully these comments make reviewing easier!
| *.min.* | ||
| src/lib/markbind/src/lib/markdown-it/* | ||
| src/lib/markbind/src/lib/markdown-it-attributes/* | ||
| src/lib/markbind/src/lib/markdown-it-shared/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Result of moving the vue-strap version of markdown-it over
.eslintrc.js
Outdated
| "no-underscore-dangle": "off", | ||
| "function-paren-newline": "off", | ||
| "implicit-arrow-linebreak": "off", | ||
| "class-methods-use-this": "off", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule requires methods inside es6 classes to have some reference to this keyword,
which dosen't fit with current rules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule exist, because these methods flagged by eslint do not need to be instance methods. They can instead be class methods instead, by putting a static keyword in front (e.g. static someClassMethods() {.
This rule can be quite useful in some situation. Possible to keep it enabled and use the static keyword where appropriate instead?
| top: 0; | ||
| } | ||
|
|
||
| /* TODO move this back to markdown-it-attr if bundling is implemented */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed for markdown-it-dimmed to work which is used in vue-strap version of markdown-it
| @@ -70,7 +70,7 @@ The example paragraph below has the following dynamic elements: a tooltip, a pop | |||
|
|
|||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly attribute name standardisation for docs, with some misc fixes
| header <hr style="margin-top:0.2rem; margin-bottom:0" /> <small>`modal-header` <br> (deprecated)</small> | `modal-title` | | ||
| footer <hr style="margin-top:0.2rem; margin-bottom:0" /> <small>`modal-footer` <br> (deprecated)</small> | `modal-footer` | Specifying `modal-footer` will override the `ok-text` attribute, and the OK button will not render. | ||
|
|
||
| **Popover Slot Options:** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed this wasn't there, but was shown in the examples in the popover section, so I added it in
| "outer-nested-panel": "Outer nested panel", | ||
| "outer-nested-panel-without-src": "Outer nested panel without src", | ||
| "panel-with-src-from-another-markbind-site-header": "Panel with src from another Markbind site header", | ||
| "panel-with-src-from-another-markbind-site-header-2": "Panel with src from another Markbind site header", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A side benefit of per file conflict resolution and moving header attribute parsing to dom
| "headings": { | ||
| "should-have-anchor": "should have anchor", | ||
| "should-have-anchor-7": "should have anchor", | ||
| "should-have-anchor-20": "should have anchor", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ordering changed due to different id assigning location, but end result is as expected.
Last number 24 -> 26 due to two addition heading ids now assigned to the below panel's headers correctly
| </panel> | ||
| <p><strong>Popover content should have algolia-no-index class</strong></p> | ||
| <popover effect="fade" title="Title" placement="top"> | ||
| <popover effect="fade" placement="top"><template slot="header">Title</template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some attribute names stayed in full the "header" vs "h" as using <slot "header">s was already a feature of the component
| <div class="border-left-grey nav-inner position-sticky slim-scroll"> | ||
| <a class="navbar-brand page-nav-title" href="#">Chapters of This Page</a> | ||
| <nav class="nav nav-pills flex-column my-0 small no-flex-wrap"> | ||
| <a class="nav-link py-1" href="#landing-page-title">Landing Page Title‎</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/template/default/index.md had a pure html <h1> heading not indexed before
| { | ||
| "headings": { | ||
| "undefined": "Landing Page Title", | ||
| "landing-page-title": "Landing Page Title", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/template/default/index.md had a pure html <h1> heading not indexed before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This heading should not be indexed at all. Add a "no-index" class to it.
|
Thanks for working on this. Will look into this soon. In the meantime, since we now have a proper implementation, would you mind running these with the cs2103 website again? So that now we have an actual statistics of how much overhead is reduced + the increase in file sizes as a result of the shift. |
|
The average ( roughly just from eyeballing ) increase seems to be much less than the initial estimated +20kb per file. The largest html file ( print.html ) increased by 21kb only. The worst increase of these is forumParticipation.html, which has about 500 panels from a ctrl-f ( many of which don't have headings though ). Even then its a ~50kb increase Diff of ls -s file sizes of .html files For/vue-strap, the file size change is as was before ( -= ~180kb ish ), which is expected since not much template changes were required |
|
Thanks for tackling this as MarkBind is in need of some hardcore code/design improvements. Is there any performance impact, w.r.t
Note that we use |
Definitely, they seem pretty small though: Before: After:
Thanks! didn't take note of this earlier. Alternatives:
|
Bootstrap 4's |
|
I assume the performance loss (although small) is worth the code quality gain? w.r.t. header/title etc. I'm OK with any, even |
Yup, in practice it should be hardly noticeable, if not negated by decreasing client side rendering and bundle size. On performance, I think a good next step would be to get a more specific stats on how much each stage of page generation takes, that maybe runs only in a "dev" mode. e.g. Individual statistics for Preferably, this comes after any architecture reorganizing though.
Hmm, I personally think Otherwise, I think it'd be good to stick with |
|
I recommend aligning with Bootstrap 4. Each component can have its own header; a page header is distinct enough from a popover header. Please avoid I would consider |
Good read, thanks! Will go with Update commit is for correcting my misuse of Will squash if its fine |
|
This PR is quite big. 😅 Is it possible for you to split the commits such that tests and docs update are in separate commits? The best commit organization would be that each commit contains the smallest possible change that cannot be broken down further. Also a side remark: if there are any changes that are unrelated to the |
👍 The unit tests haven't yet been pr-ed though 😅, I could lump it in this pr as a separate commit, or as an entirely new pr. Proposed commit structure (5 commits):
I originally intended to continue with #966 ( heading indexing ), but found it rather coupled to the markdown parsing changes.
I could continue with #966 if breaking it temporarily is fine and makes it easier to review though; its also a minor issue that existed before this. |
Seems fine as a start. For implementation wise could break it down even further like:
Hopefully this way the commits themselves get easier to review on their own. |
Thanks for the suggestions! Will include those in and see if it can't be split up further |
9aba662 to
972538b
Compare
|
Split and updated; |
yamgent
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for breaking up the commits, some preliminary comments:
docs/userGuide/syntax/badges.mbdf
Outdated
| ### Feature X <span class="badge badge-danger">beta</span> | ||
| ##### Feature Y <span class="badge badge-pill badge-success">stable</span> | ||
| <h3 class="no-index">Feature X <span class="badge badge-danger">beta</span></h3> | ||
| <h5 class="no-index">Feature Y <span class="badge badge-pill badge-success">stable</span></h5> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should encourage the use of ### by default, hence the change to <h3> and <h5> doesn't seem to be useful.
If we want to avoid getting it indexed, we can use the {.no-index} attribute for the output instead. I.e. the change should just be:
##### Feature Y <span class="badge badge-pill badge-success">stable</span> {.no-index}`
I understand that some other parts of the documents may be using <h1> and etc. This is due to legacy reasons (the documentation was ported from a source that had no access to markdown syntax). The standardization should be done in a separate PR if needed (in fact, I encourage opening an issue on the issue tracker since this can be tackled at any time).
| linkify: true | ||
| }); | ||
|
|
||
| markdownIt.use(require('markdown-it-mark')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like these changes can just be integrated into src/lib/markbind/src/lib/markdown-it/index.js? I didn't really understand why we have a separate version here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opted for maintaining parity with past behaviours for now for this, as the reasoning for the omission of some of the plugins are clear ( e.g. markdown-it-task-lists wouldn't be used in attributes ), while I'm not so sure about some other plugins.
Markdown-it plugins vue-strap has but MarkBind dosen't:
- markdown-it-sub
- markdown-it-sup
Markdown-it plugins MarkBind has but vue-strap dosen't:
- markdown-it-attrs
- markdown-it-footnotes
- markdown-it-linkify-images
Markdown-it plugins MarkBind has but vue-strap dosen't, but would not be used in attributes anyway:
- markdown-it-table-of-contents
- markdown-it-task-lists
- markdown-it-block-embed
- markdown-it-radio-button
It might be good to reach a standardisation decision for this in a separate PR instead, in case it has some side effects
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok good point, thanks for clarifying. You might want to put this as part of your commit message for this commit, so that it is clearer to future developers why there was a decision to make it separate, and that this is a temporary measure until we can finally merge both together (the most ideal case).
Also with that reasoning you had, markdown-it-attributes would actually not be a very useful name (it can be misread as a library that handles markdown attributes similar to markdown-it-attrs, rather than handling Vue attributes). Maybe it should be called vue-attribute-renderer or something else?
.eslintrc.js
Outdated
| "no-underscore-dangle": "off", | ||
| "function-paren-newline": "off", | ||
| "implicit-arrow-linebreak": "off", | ||
| "class-methods-use-this": "off", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule exist, because these methods flagged by eslint do not need to be instance methods. They can instead be class methods instead, by putting a static keyword in front (e.g. static someClassMethods() {.
This rule can be quite useful in some situation. Possible to keep it enabled and use the static keyword where appropriate instead?
yamgent
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have combed through the commit Add unit tests for ComponentParser, the specification seems pretty satisfactory, I will do another look at the implementation of ComponentParser tomorrow.
| linkify: true | ||
| }); | ||
|
|
||
| markdownIt.use(require('markdown-it-mark')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok good point, thanks for clarifying. You might want to put this as part of your commit message for this commit, so that it is clearer to future developers why there was a decision to make it separate, and that this is a temporary measure until we can finally merge both together (the most ideal case).
Also with that reasoning you had, markdown-it-attributes would actually not be a very useful name (it can be misread as a library that handles markdown attributes similar to markdown-it-attrs, rather than handling Vue attributes). Maybe it should be called vue-attribute-renderer or something else?
e22f1b9 to
f4a44ae
Compare
|
Updated:
Code identical to the cheerio version we are currently using: Updated code after cheerio also excluded <script> and <style> tags from the concatenation ( not the version we are using though ): The code is quite different, as cheerio uses their internal root() function to recursively retrieve the next node in the dfs. This is not possible here, and not needed, as the loaded cheerio dom is not available in the _parse process. I used a stack for the dfs here to make it easier to read ( personal opinion ), but I could change it to use recursive calls if that's preferred. |
f4a44ae to
b27c937
Compare
|
Rebased, only updated expected test files for new expressive layouts test site ( 2nd last commit ) |
b27c937 to
2bbe87d
Compare
|
Updated to resolve conflicts with es6 classes pr |
yamgent
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience! Overall the implementation is pretty satisfactory. There could be some minor details hiccup that I missed, but in view of time, I am OK with getting this merged first, and then doing touch up if necessary in the future.
Some final minor nits:
docs/userGuide/syntax/tabs.mbdf
Outdated
| <tabs> | ||
| <tab header="First tab"> | ||
| ... | ||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ullamcorper ultrices lobortis. Aenean leo lacus, congue vel auctor a, tincidunt sed nunc. Integer in odio sed nunc porttitor venenatis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam fringilla tincidunt augue a pulvinar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The text should be shorten (we can also shorten the actual displayed text). The code snippet has a scrollbar now.
| { | ||
| "headings": { | ||
| "undefined": "Landing Page Title", | ||
| "landing-page-title": "Landing Page Title", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This heading should not be indexed at all. Add a "no-index" class to it.
src/lib/markbind/src/utils.js
Outdated
| return undefined; | ||
| } | ||
|
|
||
| const elementStack = elements.slice(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.slice() will do.
Markdown-it in /vue-strap uses different plugins for parsing its markdown content inside component attributes. In preparation for moving markdown-it parsing to /markbind, let's move the markdown-it variant from /vue-strap over to maintain parity with the past markdown rendering behaviour for attributes in vue components. Let's also restructure the directory hierarchy for markdown-it in here, to reduce code duplication between the two variants.
Markdown passed in attributes are being rendered in the client. This results in a dependency on the markdown parsing library (markdown-it) on the client, bloating the resulting client bundle size. It also slows webpage loading, especially on older devices. Moreover, /markbind already parses some amount of markdown in attributes for other purposes when building the site. This results in a less cohesive codebase. Let's move all markdown-it parsing from /vue-strap to /markbind, passing the rendered html into vue slots. Additionally, let's conveniently standardise the attribute naming for these components at the same time.
Markdown in attributes are now being parsed at build time. Let’s adapt the panel header indexing, so that it appropriately indexes the header in the correct slot.
2bbe87d to
9d5e899
Compare
Moving markdown parsing to build time results in markdown in attributes being parsed into html in the dom. Let’s update the expected test files to reflect these changes.
9d5e899 to
26c36a4
Compare
Updated.
Thanks for taking your time to review this as well! Its quite a large PR.
I'm not in a hurry to get this merged though, I'm fine with touching it up later as well if needed, but if you feel it still needs more reviewing on your end, please do haha 😁 |
What is the purpose of this pull request? (put "X" next to an item, remove the rest)
• [x] Documentation update
• [x] Other, please explain:
Resolves #969 - move attribute markdown parsing to /markbind, removing markdown-it as a dependency from vue-strap
Resolves #36 - standardise attribute naming for "header", "title", etc.
As a result,
Fixes #967 - some unexpected behaviours related to panel heading indexing
Combined with #966 ( closed ) - fix heading indexing for pure html headings, which is necessary for #969
Requires MarkBind/vue-strap#120 for the corresponding vue-strap template changes
What is the rationale for this request?
(1) To move all markdown parsing from the client to site building, which has benefits elaborated in #969 . Briefly,
(2) Fix heading indexing for pure html headings ( originaly in #966 ). This is required for moving markdown parsing, as headings are now rendered in the dom as tags.
(3) Following the attribute parsing, attribute naming is conveniently standardised as well, and existing docs / srces / other usages updated. Deprecated attributes are still supported and documented. Components affected:
What changes did you make? (Give an overview)
(1) Introduce html heading id assigning identical to markdown-it-anchor for heading indexing, but for all types of headings. Consequently removed markdown-it-anchor plugin. Integrated this into
_parseprocess.(2) Introduced a generic per-component parser class housing all the new logic. Currently this only contains logic for parsing markdown in attributes. Integrated this into
_parseprocess as well.Provide some example code that this change will affect:
The main changes are summarised in the
_parsefunction on a high level.Is there anything you'd like reviewers to focus on?
ComponentParseris quite unit - testable. This pr is getting a little large though - should it be done in a follow up instead?Testing instructions:
npm run testwill verify the dom changes to the test files, which have been checked.Proposed commit message: (wrap lines at 72 characters)
Move markdown-it parsing to /markbind
Markdown passed in attributes are being rendered in
the client.
This results in a dependency on the markdown parsing
library ( markdown-it ) on the client bloating the resulting
bundle size for /vue-strap.
It also slows webpage loading, especially on older devices.
Moreover, /markbind already parses some amount of
markdown in attributes for other purposes when building
the site. This results in a less cohesive codebase.
Let's move all markdown-it parsing to /markbind from
/vue-strap, passing the rendered html into vue slots.
Additionally, let's add heading indexing for pure html
headings, which is required for heading indexing to
function correctly after this change.