Skip to content

Conversation

alyip98
Copy link
Contributor

@alyip98 alyip98 commented Jun 10, 2019

What is the purpose of this pull request? (put "X" next to an item, remove the rest)
• [x] New feature

Resolves #877

What is the rationale for this request?

As MarkBind is to be optimized for software documentation, it may be useful to support PlantUML.

PlantUML is a tool written in Java that allows users to write diagrams in a simple and intuitive language. Being able to write (and track) UML diagrams in a text format compared to using tools such as Powerpoint or Photoshop allows better version control and ease of use.

What changes did you make? (Give an overview)
Add ability to include UML diagrams via a <puml> tag. The diagram itself is written in PlantUML syntax in a separate file. The page includes the diagram using the following syntax:
<puml src="diagrams/example.puml"/>

Is there anything you'd like reviewers to focus on?
Due to limitations of htmlparser2, including UML code inline will cause problems as UML syntax violates HTML specifications (e.g. presence of symbols such as <-- which are misinterpreted as HTML tags). Fixing this will require cheerio to use a forked version of htmlparser2, discussed in #582, which in itself is an open problem.

Testing instructions:
The user guide contains an entry

Proposed commit message: (wrap lines at 72 characters)
Markbind page authors can use diagrams in their sites by linking them
in a <pic> tag. This is tedious as it requires the author to generate
the diagrams using an external tool, and the binary files generated by
that tool (e.g. .pptx, .psd) are not version control friendly.

Let's support PlantUML, a tool that allows users to write diagrams in
a simple and intuitive language. Users can then write their diagrams
in a text editor, and Markbind will generate the diagrams using
PlantUML, eliminating the need of an external editor.

@Chng-Zhi-Xuan
Copy link
Contributor

Will it be more advantageous to just use an existing module? node-plantuml is tested, documented, and provides more features. However, not all of its features are relevant to MarkBind (due to it also being a CLI application)

Does your current implementation require the user to already have Java installed? If so it might be problematic to impose installing a JRE / JDK to use this feature.

Having looked through node-plantuml, looks like its more suited for MarkBind.
Seems like we can avoid the "diagrams generated after MarkBind generates the website" problem as well by using a custom tag and cheerio to selectively parse the input into node-plantuml

<plantuml>
Bob->Alice : hello
</plantuml>
Page.prototype.generatePlantuml = function (content) {
  const $ = cheerio.load(content);
  const plantumlContent = $("plantuml");
  ...
  ...
}

Is the delay going to be a problem, especially on large sites with numerous diagrams?

Build times is not really a concern (unless it is a significant increase).

You should take note on how it affects previewing websites for authors. Manually recording some timings on a test page with different number of diagrams & other components can be a good gauge if it is problematic.

Other comments:

  • Looks like your code crashes if an out folder is not created. If a new folder is required, you should place it within _markbind as well as creating that folder on markbind init by modifying code in Site.js.
  • Name the folder storing the generated diagrams something better than out
  • A good enhancement would be to ensure minimal generation of duplicate diagrams (E.G 2 different pages uses the same plantuml markup). Not sure if this is already handled by the plugin/parser.

Although not fully tested, this seems like it is a great feature addition as I can place the plantuml diagrams within MarkBind components.

@alyip98
Copy link
Contributor Author

alyip98 commented Jun 12, 2019

Does your current implementation require the user to already have Java installed? If so it might be problematic to impose installing a JRE / JDK to use this feature.

Yeah, PlantUML is supplied as a JAR, there's no way around it. node-plantuml is also a wrapper that runs the JAR which offers an abstracted API.

Having looked through node-plantuml, looks like its more suited for MarkBind.
Seems like we can avoid the "diagrams generated after MarkBind generates the website" problem as well by using a custom tag and cheerio to selectively parse the input into node-plantuml

Currently I'm using markdown-it to parse since it's more convenient. But I think I'll try using cheerio and see if its better.

My reservation for not using node-plantuml is because all the extra features are unnecessary, and it presents another potential source of errors.

But now I'm encountering a new problem where certain symbols within the PlantUML language are misinterpreted as HTML tags. For now I'll try using cheerio instead and see if it solves this problem

@alyip98 alyip98 force-pushed the 877-plantuml branch 3 times, most recently from d1804f6 to 099093b Compare June 21, 2019 04:25
Copy link
Contributor

@Chng-Zhi-Xuan Chng-Zhi-Xuan left a comment

Choose a reason for hiding this comment

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

Other Comments

  • The .puml files do not end with an empty line. Might want to change it such that parsers will know that is the EOF? (and have Github stop complaining about it)
  • The graphviz not found bug is fixed after installing the stable version of graphviz 2.38.

// Read diagram file
fs.readFile(src, (err, data) => {
if (err) {
throw err;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should log the error with a meaningful message, and continue to generate the website.

Throwing the error would stop the parsing entirely, requiring the user to debug the verbose error on their own.

Since you used error below, you should use it here instead of err for consistency.

Likewise for all error catching code below, we should be able to fail gracefully with a meaningful message. Since we can just not generate this specific plant-uml diagram and continue with parsing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, good point

Copy link
Contributor

@Chng-Zhi-Xuan Chng-Zhi-Xuan Jun 24, 2019

Choose a reason for hiding this comment

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

As discussed in person:

  • Unable to share the same error names as the same name was defined in a higher scope. So we decided to move the verbose error message to the logger file and print out a more meaningful message on the console.

const diagramSrc = src.replace('.puml', '.png');
const rawDiagramPath = path.resolve(path.dirname(sourcePath), src);
const outputFilePath = path.resolve(rootPath, '_site', path.relative(rootPath, rawDiagramPath)).replace('.puml', '.png');
// const outputFilePath = path.resolve(diagramSrc);
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this PR is still [WIP], remember to remove redundant comments + console logging code below.

try {
fs.mkdirSync(outputDir, { recursive: true });
// eslint-disable-next-line no-empty
} catch (_e) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to catch this error but not throw it?

@@ -7,6 +7,7 @@
* [Adding Pages]({{baseUrl}}/userGuide/addingPages.html)
* [MarkBind Syntax Overview]({{baseUrl}}/userGuide/markBindSyntaxOverview.html)
* [Formatting Contents]({{baseUrl}}/userGuide/formattingContents.html)
* [UML]({{baseUrl}}/userGuide/puml.html)
Copy link
Contributor

Choose a reason for hiding this comment

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

Inserting PlantUML Diagrams?


<span id="overview" class="lead">

**MarkBind offers integration with PlantUML in your pages,** allowing you design and write UML diagrams (and more) using PlantUML syntax, which is then compiled and served as images.
Copy link
Contributor

Choose a reason for hiding this comment

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

  • Add a newline after the bold text?
  • (and more) should naturally link to other examples
  • You should put a warning at the top of this page indicating that authors need to have a JRE/JDK installed, along with the graphviz installer to use this feature.

## PlantUML Test

### Sequence Diagram
<puml src="diagrams/sequence.puml" />
Copy link
Contributor

Choose a reason for hiding this comment

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

When I generate this page, the src will be changed to test_site/diagrams/abc.png when the correct one should be without test_site.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems to be an issue with the <pic> component, will look into it

Copy link
Contributor

@Chng-Zhi-Xuan Chng-Zhi-Xuan left a comment

Choose a reason for hiding this comment

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

For the graceful error handling, there is room for some improvement:

  • All errors that result in the diagram not being generated should return immediately.
  • All errors should be logged in logger.debug, not just replaced with a generic error message.
  • We should only show 1 logger.error per diagram (to reduce clutter).

Example

if (criticalErr1) {
  logger.debug(criticalErr1);
  logger.error("Tell user something went wrong");
  return;
} 

if (nonCriticalError1) {
  logger.debug(nonCriticalError1);
}

if (nonCriticalError2) {
  logger.debug(nonCriticalError2);
}

if (criticalError2) {
  logger.debug(criticalError2);
  logger.error("Tell user smth went wrong);
  return;
}

This would ensure we only get 1 console error message per diagram, and all errors that occurred up until the critical error is logged properly.

@damithc
Copy link
Contributor

damithc commented Jun 25, 2019

Use Github's 'draft PR' feature instead of WIP prefix in the PR title.

@alyip98
Copy link
Contributor Author

alyip98 commented Jun 25, 2019

@Chng-Zhi-Xuan

For the graceful error handling, there is room for some improvement:

  • All errors that result in the diagram not being generated should return immediately.
  • All errors should be logged in logger.debug, not just replaced with a generic error message.
  • We should only show 1 logger.error per diagram (to reduce clutter).

This would ensure we only get 1 console error message per diagram, and all errors that occurred up until the critical error is logged properly.

Currently it already does this. There are 2 main locations where errors occur - reading the .puml, and running the jar. If an error occurs during the read, the error is logged and the jar is not run. If an error occurs while running the jar, either the error or close event is triggered, but not both, so it will not be double logged.

@alyip98
Copy link
Contributor Author

alyip98 commented Jun 25, 2019

@damithc there are some issues with Github's draft PR feature, namely not being able to revert back to it or retroactively mark an opened PR as draft

@alyip98 alyip98 changed the title [WIP] Add PlantUML diagrams support Add PlantUML diagrams support Jun 26, 2019
Copy link
Contributor

@Chng-Zhi-Xuan Chng-Zhi-Xuan left a comment

Choose a reason for hiding this comment

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

Other comments:

  • You have not initialised the diagrams folder within _markbind during markbind init. You also have to update the Site.test.js code since an additional folder is expected on initialisation. All sharable assets between pages (such as site-nav) should be in the _markbind folder.
  • Good that you tried to reduce duplicate processing for the same diagrams using Sets.


**[Graphviz](https://www.graphviz.org/download/) must be installed to generate diagrams**, with the exception of sequence and activity diagrams. (_tested with v2.38_)
**[<tooltip content="Tested with v2.38">Graphviz</tooltip>](https://www.graphviz.org/download/) must be installed to generate <tooltip content="with the exception of sequence and activity diagrams">diagrams</tooltip>**
Copy link
Contributor

Choose a reason for hiding this comment

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

Will there be a case where activity and sequence diagrams don't work if they used a certain syntax for another component (without Graphviz) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly, I don't know. What do you mean by a certain syntax for another component?

Copy link
Contributor

Choose a reason for hiding this comment

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

On a separate note, use tooltips only in cases where you want to supply a definition/explanation of a term. Otherwise, the reader will have to retrieve every tooltip to see if there is something relevant in the tooltip. Use dimmed text to provide unimportant details.
recent version is not precise enough. Say something like version 8 or later.

@@ -15,11 +15,11 @@

<box type="warning">

**[Java](https://www.java.com/en/download/) must be installed to use this feature**
**[Java](https://www.java.com/en/download/) must be installed to use this feature**. _(Any recent version should work)_
Copy link
Contributor

Choose a reason for hiding this comment

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

How about "Java must be installed to generate the UML diagrams via a JAR executable"?

To inform the user why is it needed.

</box>
<box type="warning">

**[Graphviz](https://www.graphviz.org/download/) must be installed to generate diagrams**, with the exception of sequence and activity diagrams
**[Graphviz](https://www.graphviz.org/download/) must be installed to generate diagrams**, with the exception of sequence and activity diagrams. (_tested with v2.38_)
Copy link
Contributor

Choose a reason for hiding this comment

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

"... to generate all PlantUML diagrams"?

@alyip98
Copy link
Contributor Author

alyip98 commented Jun 26, 2019

  • You have not initialised the diagrams folder within _markbind during markbind init. You also have to update the Site.test.js code since an additional folder is expected on initialisation.

The diagram files can be in any folder, not necessarily restricted to the diagrams folder. I used diagrams in this case as an example, but it could have been any folder.

@alyip98
Copy link
Contributor Author

alyip98 commented Jun 27, 2019

@Chng-Zhi-Xuan @damithc I've rephrased the requirements section

@Chng-Zhi-Xuan
Copy link
Contributor

Chng-Zhi-Xuan commented Jun 27, 2019

You have not initialised the diagrams folder within _markbind during markbind init. You also have to update the Site.test.js code since an additional folder is expected on initialisation. All sharable assets between pages (such as site-nav) should be in the _markbind folder.

@alyip98 You have not addressed the request above.

In addition, since all the diagrams are in _markbind/diagrams, you can simplify the src specification with some minor tweaks to your code.

<!-- src will search starting from "_markbind/diagrams" -->
<puml src="abc.puml">

@Chng-Zhi-Xuan
Copy link
Contributor

Chng-Zhi-Xuan commented Jun 28, 2019

As discussed in person, since <puml> is eventually going to be replaced with a <img> tag, we should not enforce that diagrams be placed in _markbind/diagrams because we don't enforce that for images as well.

alyip98 added 3 commits June 28, 2019 10:39
Markbind page authors can use diagrams in their sites by linking them
in a `<pic>` tag. This is tedious as it requires the author to generate
the diagrams using an external tool, and the binary files generated by
that tool (e.g. .pptx, .psd) are not version control friendly.

Let's support PlantUML, a tool that allows users to write diagrams in
a simple and intuitive language. Users can then write their diagrams
in a text editor, and Markbind will generate the diagrams using
PlantUML, eliminating the need of an external editor.
@Chng-Zhi-Xuan Chng-Zhi-Xuan changed the title Add PlantUML diagrams support Add support for PlantUML diagrams Jun 28, 2019
@Chng-Zhi-Xuan Chng-Zhi-Xuan merged commit 1912d4a into MarkBind:master Jun 28, 2019
@Chng-Zhi-Xuan Chng-Zhi-Xuan added this to the v2.5.2 milestone Jun 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support embedding PlantUML diagrams
3 participants