Generating HMTL and MD files from .TXT in GO
Tags: go, markdown, productivity, cli
Published: 2022-03-13 16:53:09

In this post I'll be describing the code which I wrote to generate HTML (which can be hosted anywhere) and Markdown files from simple .txt file.

###Idea for project
Idea for this project came from a need to quickly generate and share some basic documentation about task or bug needed to be solved by team member.

Working mostly as backend engineer, naturally my 1st idea was to build CLI tool that could easily do this by inputting file path and letting the code do the rest.

###Why GO
I never wrote Go code before but I watched few Go conf's and talks that sparked interest so this was me trying it out.

I really loved how simple it is to execute code in parallel in GO with [goroutines](https://go.dev/tour/concurrency/1), [channels](https://go.dev/tour/concurrency/2) & [wait groups](https://gobyexample.com/waitgroups), so that was the reason for doing this in GO.

###Main idea
Main idea I followed for this project was to read from .txt file line by line and at the same time write to MD & HTML files using Go's goroutines & channels.
This worked out fine for the most part, but I had to make some workarounds for 3rd party libraries which required code blocks and tables syntax to be passed all at the same time instead of line by line.
So I had to come up with a way to detect code blocks and tables, than concatenate them into single block using Go's [strings.Builder](https://pkg.go.dev/strings#Builder) package.

**3rd party libraries:**
[goldmark](https://github.com/yuin/goldmark)
for converting MD syntax to HTML

[quick](https://github.com/alecthomas/chroma/quick)
for generating Html and syntax highlighting code blocks




###Code
Entry point to CLI tool:
{% embed https://gist.github.com/dommyrock/2a58c9cc1bd314febb3ab0e51a614217 %}
In above code I'm declaring map/dictionary of all available custom mappings I will be exposing and parsing from .txt file to MD & HTML format.

Than I'm validating user input Args from CLI in 'shouldExit' func.
{% embed https://gist.github.com/dommyrock/3510b44ddaedb19b02eb682f50956c11 %}
Than I'm validating file path and extension.

After that I'm creating 2 channels.
{% embed https://gist.github.com/dommyrock/b16f269c706116bae557ca694c13c081 %}
* One 'writerChannel' that I'm reading/writing from.
* And 'filesCreated' that I'm using to signal when reading/writing is done to main goroutine so it can stop blocking and continue executing.

####Reading/writing to files
In separate goroutines
{% embed https://gist.github.com/dommyrock/e1f269deef76914552a758dc9cd7e786 %}

####Detecting Table and Code blocks
This is the code that handles writing to MD & html formats.
{% embed https://gist.github.com/dommyrock/ad8d095a7afcb7588210c54029d7285a %}
'htmlStleBuilder' function handles what theme and styling to construct from static files based on passed CLI Args.
{% embed https://gist.github.com/dommyrock/4c4a8fc0f0046cf7bed5ebd806407b4a %}

> err := quick.Highlight(...)

line handles Html syntax highlighting generation for code blocks.

And finally signaling to main goroutine by reading 'done' from 'filesCreated' channel that it can proceed executing after writing and reading is complete.
> <-filesCreated

[Full method on Github](https://github.com/dommyrock/go-txtToMD/blob/b540ed468738b168dfecf61dc496b30a2c638177/library/files/fileProcessing.go#L135)
---
###Source code 
[Github Repo](https://github.com/dommyrock/go-txtToMD)

####Running code locally: (with test files form ./testData directory)
> Generate Html/md files to %HOMEDIR%/Downloads directory:
```
go run . ./testData/test.txt
```
> selecting custom theme:
```
go run . ./testData/test.txt mid
```
> Getting all currently available mappings:
```
go run . -options (or -o)
```

> Note: Currently line break/newline is expected between each mapping element to be parsed into MD/HTML correctly!

---
####Running CLI command globally:
If you want to run this tool globally you can place txtToMD.exe file to 'Path' in windows environment variables.
that way you can use it from anywhere in your system
> txtToMD {txt File Path} [options:light(default),dark,mid]
```
txtToMD D:\Desktop\test.txt dark
```
> Getting all currently available mappings:
```
txtToMD -options
```
![Available mappings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/noukkyfp0nsq5axm710x.png) 

###Comments
Feel free to leave comments if you see some critical antipattern or mistake.
As I said this was my 1st GO project made for fun so it can probably be improved.
 
###About me 
I currently work as backend/fullstack engineer mostly in C#,JS,TS.
With focus on distributed systems area at the moment.

In free time I have been exploring and experimenting with Go and Rust because they seemed fun and enjoyable to work with.
####Contact
[Twitter](https://twitter.com/dompolzer)
[Linkedin](https://www.linkedin.com/in/dominik-polzer-hi-o/)