Skip to content

Use a CLI tool for converting MD to HTML and for Sanitizing HTML as a way to not add any new 3rd party dependencies to Dynamo#11

Merged
mjkkirschner merged 34 commits intoSHKnudsen:Node-annotations-doc-browserfrom
sm6srw:DYN-3243
Nov 23, 2020
Merged

Use a CLI tool for converting MD to HTML and for Sanitizing HTML as a way to not add any new 3rd party dependencies to Dynamo#11
mjkkirschner merged 34 commits intoSHKnudsen:Node-annotations-doc-browserfrom
sm6srw:DYN-3243

Conversation

@sm6srw
Copy link

@sm6srw sm6srw commented Nov 18, 2020

Purpose

This Pull Request addresses DYN-3243. Use a CLI tool for converting MD to HTML and for Sanitizing HTML as a way to not add any new 3rd party dependencies to Dynamo.

This Pull Request does

  • add a command line tool, Md2Html.exe, to Dynamo tools.
  • add a command line tool manager class Md2Html, to Dynamo utilities.
  • start using Md2Html for converting MD to Html and for Sanitizing Html in the document browser.
  • remove all 3rd party dependencies that was previously added to the document browser.

Notes:
The command line utility is still work in progress and will be finalized in a separate task.

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated

Reviewers

@pinzart90 @mjkkirschner @aparajit-pratap

FYIs

@SHKnudsen

<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="AngleSharp, Version=0.14.0.0, Culture=neutral, PublicKeyToken=e83494dcdc6d31ea, processorArchitecture=MSIL">
Copy link
Collaborator

Choose a reason for hiding this comment

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

sweet sweet assembly isolation. :)

/// <param name="writer"></param>
/// <param name="mdString"></param>
/// <param name="mdPath"></param>
public void ParseMd2Html(ref StringWriter writer, string mdString, string mdPath)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why use a ref in these parameters - you're not replacing the writer with another writer are you?

Copy link
Author

Choose a reason for hiding this comment

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

I am not. But you are right, this API can be simplified to just return a string.


namespace Dynamo.Utilities
{
public class Md2Html
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we expect others to use this utilty? If not maybe we make it internal?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, internal makes more sense.

/// Destructor
/// Kill the CLI tool, if still running
/// </summary>
~Md2Html()
Copy link
Collaborator

Choose a reason for hiding this comment

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

finalizers.... hmmm
I think IDisposable has a better chance of being deterministic and controllable in testing scenarios -
just some thoughts:
https://www.viva64.com/en/b/0437/


namespace Dynamo.Utilities
{
public class Md2Html
Copy link
Collaborator

Choose a reason for hiding this comment

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

curious what you think about making this IDisposable

Copy link
Author

Choose a reason for hiding this comment

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

I tried IDisposal and yes, much easier to control. I don't need the ProcessExit handler anymore. So I keep the IDisposal implementation for now.

/// referencing it with a relative path "./image.png", when we convert to html
/// we need the full path. This method finds relative image paths and converts them to absolute paths.
/// </summary>
private static void ConvertRelativeLocalImagePathsToAbsolute(string mdFilePath, MarkdownDocument document)
Copy link
Collaborator

@mjkkirschner mjkkirschner Nov 18, 2020

Choose a reason for hiding this comment

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

I feel we've written this method 100 times in the libraryUI at various times, let me see if I can find a version we can reuse/share.

Copy link
Collaborator

Choose a reason for hiding this comment

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

no dice - nevermind.

<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\bin\AnyCPU\Debug\Md2Html\</OutputPath>
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is a props file that needs to be imported to set this automatically I think.

{
static class Program
{
static void Main(string[] args)
Copy link
Collaborator

Choose a reason for hiding this comment

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

have you considered using ndesk options in the repo to list CLI options / help docs

Copy link
Author

Choose a reason for hiding this comment

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

Nop, but I will take a look.

Copy link
Author

Choose a reason for hiding this comment

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

Added basic help

// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we use the shared assembly generator to align the version number of this exe with the dynamo version number?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, that make sense.

Copy link
Author

Choose a reason for hiding this comment

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

Done

EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NodeAutoCompleteViewExtension", "NodeAutoCompleteViewExtension\NodeAutoCompleteViewExtension.csproj", "{51511AFD-F326-4995-8E27-5D711419EF6F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Md2Html", "Tools\MD2HTML\Md2Html.csproj", "{0893F745-CB1A-427A-8E87-CA927273039A}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

if this tool is cross platform does it make sense to add it to the mono.sln as well?

Copy link
Author

Choose a reason for hiding this comment

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

I will give it a try and see if it works in mono.

Copy link
Author

@sm6srw sm6srw Nov 18, 2020

Choose a reason for hiding this comment

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

Mono do compile so keep for now. I will address your other cross platform comments next.


foreach (var image in imageLinks)
{
if (!image.Url.StartsWith("./"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we changes this to Uri.IsWellFormedUriString(url, UriKind.Relative) - otherwise this is windows only.

Copy link
Author

Choose a reason for hiding this comment

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

Done

if (!image.Url.StartsWith("./"))
continue;

var imageName = image.Url.Split(new string[] { "./" }, StringSplitOptions.None);
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we use the system.io.path options to get the filename instead - that will be crossplatform.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@sm6srw
Copy link
Author

sm6srw commented Nov 20, 2020

@pinzart90 @mjkkirschner PTAL!

/// Read data from CLI tool
/// <param name="writer"></param>
/// </summary>
private void GetData(ref StringWriter writer)
Copy link
Collaborator

Choose a reason for hiding this comment

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

still using ref? Intentional?

Copy link
Author

Choose a reason for hiding this comment

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

Old habit. I will get rid of it.

/// <returns>Returns full path to the CLI tool</returns>
private static string GetToolPath ()
{
var rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new ArgumentNullException("Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)");
Copy link
Collaborator

Choose a reason for hiding this comment

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

you can probably use nameof here?

Copy link
Collaborator

@mjkkirschner mjkkirschner left a comment

Choose a reason for hiding this comment

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

it looks good - my biggest concern still is the use of ref - it seems unnecessary / confusing.

private static string GetToolPath ()
{
var rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new ArgumentNullException("Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)");
var toolPath = Path.Combine(rootPath, @"Md2Html\Md2Html.exe");
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know the answer to this - does Path.Combine generate a valid path cross platform even if you use hardcoded directory separator characters?

Copy link
Author

Choose a reason for hiding this comment

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

Good point. Let me fix that.


while (true)
{
var line = Console.ReadLine();

Choose a reason for hiding this comment

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

should we handle exceptions inside the while(true) ? if exception is thrown...it will kill the process right ?

Copy link
Author

Choose a reason for hiding this comment

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

Yes good point. We should exit the process if anything unexpected happens with the communication.

@sm6srw
Copy link
Author

sm6srw commented Nov 20, 2020

@mjkkirschner @pinzart90 PTAL!

/// <returns>Returns error message</returns>
private string GetCantCommunicateErrorMessage()
{
return @"<p>Can't communicate with '" + GetToolPath() + @"'</p>";
Copy link
Collaborator

Choose a reason for hiding this comment

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

last thing - is this intended for us or for users? If it's for users then we should put it in a resx file which the localization team can localize.

Copy link
Author

Choose a reason for hiding this comment

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

They will show up in the document browser window.

Copy link
Author

Choose a reason for hiding this comment

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

I will work adding resources for these strings.

Copy link

@pinzart90 pinzart90 left a comment

Choose a reason for hiding this comment

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

LGTM

@sm6srw
Copy link
Author

sm6srw commented Nov 23, 2020

@mjkkirschner Move error messages to resources. PTAL!

Copy link

@pinzart90 pinzart90 left a comment

Choose a reason for hiding this comment

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

LGTM

@mjkkirschner
Copy link
Collaborator

LGTM

@mjkkirschner mjkkirschner merged commit c8cf9f3 into SHKnudsen:Node-annotations-doc-browser Nov 23, 2020
@sm6srw sm6srw deleted the DYN-3243 branch December 3, 2020 23:03
SHKnudsen added a commit that referenced this pull request Dec 8, 2020
* add packageDocManager to handle package documentation links

* new viewModelEventArgs to send node annotation data to doc browser

* Handle node annotation in doc browser

* support custom NodeModels + fix watcher event bug

* Update NodeAnnotationNotFound.md

* Update NodeAnnotationNotFound.md

* Comment updates

* Update AssemblySharedInfo.cs

* Update src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelEventArgs.cs

* addtional comment updates + clean up

* clean up packageDocManager

* Update DocumentationBrowserViewModel.cs

* handle overloads + fix hot reload bug

* use HtmlSanitizer to clean potential dangerous content from markdown files

* move PackageDocumentationManager to DocumentationBrowser

* update syntax highlighting + markdownStyling updates

* comment updates

* add Markdig to License files

* Change GetPackageName to GetMainCategory

* update markdig + htmlsanitizer version

* fix failing tests + add new node documentaion tests

* fix broken test

* update link to wiki

* Update DocumentationBrowserViewExtension.cs

* Add MD2HTML Tool

* First pass - singleton version

* Revert "Add MD2HTML Tool"

This reverts commit 71509da.

* Revert "First pass - singleton version"

This reverts commit bbefc36.

* fix test

* add doc folder to PackageDirectoryBuilder (#10)

* add doc folder to PackageDirectoryBuilder

* update tests

* comment update

* Use a CLI tool for converting MD to HTML and for Sanitizing HTML as a way to not add any new 3rd party dependencies to Dynamo (#11)

* Revert "Revert "Add MD2HTML Tool""

This reverts commit 99b42f2.

* Revert "Revert "First pass - singleton version""

This reverts commit f655c39.

* Implement HTML Sanitizer

* Remove unneeded dependecies from the doc extension

* Cleanup naming

* More naming cleanups

* Rename files

* Rename folder

* Add comments

* Use literal strings

* Hardening wrapper class

* Simplify API

* Make wrapper API internal

* Add Tools project to Mono solution

* Fix directory name (case)

* Add missing internal

* Use IDispose pattern

* Fix literal string

* Fix cross platform issues

* Use CS.props file

* Undo change to AssemblySharedInfo.cs

* Use shared assembly info

* Add more docs

* Add ndesk support and implement help option

* Rename class

* Add missing change

* Remove the use of ref

* Fix typo

* Fix toolpath and use nameof()

* Improve error handling

* Move strings to resources

* Enhance error messages

* Merge master (#12)

* Fix sorting for number keys in List.SortByKey (DynamoDS#11241)

* fix sorting for number keys in List.SortByKey

* add unit test

* Crash when accessing static hidden methods from zero touch nodes (DynamoDS#11238)

* handle hidden static methods from zero touch nodes

* add images (DynamoDS#11243)

* Revert "Adding copy of missing file from LibG nuget package (DynamoDS#11218)" (DynamoDS#11254)

This reverts commit a71b5c8.

* Revert "Revert "Adding copy of missing file from LibG nuget package (DynamoDS#11218)" (DynamoDS#11254)" (DynamoDS#11255)

This reverts commit 257ac14.

* Undock/redock extension tabs to windows (DynamoDS#11246)

* Somewhat working version

* Pretty much working version

* Finishing touches and test

* Cleanup

* Prevent both window and tab

* Improve method name and comment

* Forgot to include this in last commit

* add analytics to extensions load event (DynamoDS#11258)

* Revert Project Reference Changes (DynamoDS#11256)

* Initial Commit

* fix mono build

* Update to latest libG nuget version

* Cleanup entries VS Studio failed to update

* Fix Mono build

* Add the private flag back (modified by VS Studio)

* Regressions

* Add back missing resource

* Change DefaultValue setter to public (DynamoDS#11251)

* update load asm binaries from registry logic (DynamoDS#11261)

* update load asm binaries from registry

* Add coverage for docking (DynamoDS#11262)

* Adding a public API on the View extension that gets triggered when the view extension is closed. (DynamoDS#11260)

* Adding a public API on the View extension that gets triggered when the view extension is closed.

* Update variable name

* changing the name to ViewExtensionBaseClass

* Addressing some comments.

* Adding unit test.

* Changing the name to Closed()

* Some more comments.

* Adding an additional test

* Adding checks for the Menu items before setting its value.

* Update Style (DynamoDS#11263)

* CustomNodes that replicate do not access trace correctly. (DynamoDS#11244)

* add failing test

* this works, but seems like cheating.
more tests

* new tests, one failing, needs discussion

* fix test - still fails but as expected

* tests all pass with this change - but looking for better alternatives

* add test
use new field - cant find a better way currently
add comments

* revert internal
update test

* reset guid map before each test

* failing test

* reset

* whitespace

* Localize buttons (DynamoDS#11265)

* update version num and tt file (DynamoDS#11269)

* Fix merge error

* Fix merge error

* Revert "Fix merge error"

This reverts commit 0a21ca4.

Co-authored-by: aparajit-pratap <[email protected]>
Co-authored-by: pinzart90 <[email protected]>
Co-authored-by: Sylvester Knudsen <[email protected]>
Co-authored-by: Aaron (Qilong) <[email protected]>
Co-authored-by: Michael Kirschner <[email protected]>
Co-authored-by: Martin Misol Monzo <[email protected]>
Co-authored-by: Ashish Aggarwal <[email protected]>
Co-authored-by: reddyashish <[email protected]>

* Extract more strings (#13)

* Fix failing tests (#14)

* Fix failing tests

* Revert "Fix failing tests"

This reverts commit 824f785.

* Fix failing tests

* Properly dispose all string writers

* More failing test fixes (#15)

* Fix for regression in multi-output node preview  (DynamoDS#11266)

* fix for multi-output node preview regression

* update tests

* add test

* revert unwanted changes

* update test

* Life cycle refactoring: Get rid of singleton. Let the model create and own the MarkdownHandler on first use.

* Fix crash in some document browser tests

* Properly dispose all DocumentBrowserViewExtension objects

* Revert "Fix crash in some document browser tests"

This reverts commit ab146f9.

* Display input port type specific default suggestions only (DynamoDS#11268)

* input port type specific default suggestions

* test fix

* Test fixes

* Use InTestMode flag

* Delete empty lines

* turn off hit testing visibility for DM related render packages (DynamoDS#11282)

* Apply syntax highlighting to multi-line strings (DynamoDS#11289)

* Also sanitize node documentation html

* Save/Load view extension size and location (DynamoDS#11278)

Information of where an extension control was last shown is saved and
retrieved as preference settings. These are actually not directly
visible for the user and are updating automatically, just like the main
Dynamo window size. These settings are used when showing the extension
control, to restore it to how it used to be before closing it.

The available information for each view extension is:

1. How it is shown. For now this can be either as a floating window or
docked to the right-side panel.

2. In case it is shown as a floating window, the following information
about the window is saved:
- Location by Top/Left coordinates
- Size by Width/Height
- Whether the window is maximized

* add revit dlls to assembly conflict checker ignore list (DynamoDS#11285)

* Update StartupUtils.cs

Co-authored-by: pinzart <[email protected]>

* Fix sanitizing log warnings

* Node AutoComplete suggestions sorted alphabetically within the same group (DynamoDS#11280)


* add/update tests

* Address review comments

* Add ILMerge

* Fix typo

* Fix mono build

* Revert "Fix mono build"

This reverts commit 9904525.

* Refine mono solution

* Remove task condition

* Mono build fix

* Add Readme

Co-authored-by: aparajit-pratap <[email protected]>
Co-authored-by: Ashish Aggarwal <[email protected]>
Co-authored-by: Laurence Elsdon <[email protected]>
Co-authored-by: Martin Misol Monzo <[email protected]>
Co-authored-by: pinzart90 <[email protected]>
Co-authored-by: pinzart <[email protected]>

Co-authored-by: Radu Gidei <[email protected]>
Co-authored-by: Jorgen Dahl <[email protected]>
Co-authored-by: Jorgen Dahl <[email protected]>
Co-authored-by: aparajit-pratap <[email protected]>
Co-authored-by: pinzart90 <[email protected]>
Co-authored-by: Aaron (Qilong) <[email protected]>
Co-authored-by: Michael Kirschner <[email protected]>
Co-authored-by: Martin Misol Monzo <[email protected]>
Co-authored-by: Ashish Aggarwal <[email protected]>
Co-authored-by: reddyashish <[email protected]>
Co-authored-by: Laurence Elsdon <[email protected]>
Co-authored-by: pinzart <[email protected]>
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.

3 participants