Skip to content

Commit

Permalink
Refactored code to improve maintainability
Browse files Browse the repository at this point in the history
 * split utils into smaller files

 * refactor accepted filetypes

 * refactor name and extension conversion

 * refactor inline markdown parsing

 * Implemented italics, bold, and href using regexp
  • Loading branch information
devils2ndself committed Oct 12, 2022
1 parent 55f86d0 commit 1bbc92d
Show file tree
Hide file tree
Showing 8 changed files with 448 additions and 438 deletions.
10 changes: 3 additions & 7 deletions ssgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,24 @@ import (
"fmt"
"os"

"github.com/devils2ndself/SSGo/utils"
utils "github.com/devils2ndself/SSGo/utils"
flag "github.com/spf13/pflag"
)

const version string = "0.3"

const defaultOutput string= "dist"

func main() {

var (
input string = ""
output string = defaultOutput
output string = utils.DefaultOutput
displayHelp bool = false
displayVersion bool = false
config string = ""
)

// Flag initialization
flag.StringVarP(&input, "input", "i", "", utils.InputHelpMessage)
flag.StringVarP(&output, "output", "o", defaultOutput, utils.OutputHelpMessage)
flag.StringVarP(&output, "output", "o", utils.DefaultOutput, utils.OutputHelpMessage)
flag.BoolVarP(&displayHelp, "help", "h", false, utils.HelpHelpMessage)
flag.BoolVarP(&displayVersion, "version", "v", false, utils.VersionHelpMessage)
flag.StringVarP(&config, "config", "c", "", utils.ConfigHelpMessage)
Expand All @@ -47,5 +44,4 @@ func main() {
fmt.Println("Invalid call. Use 'ssgo [-h | --help]' for available commands.")
}
}

}
6 changes: 4 additions & 2 deletions test/Markdown File.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ This is a paragraph with `inline code`, isn't it `cool`??``


# Heading 1 with `code`
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sit amet tincidunt nulla. Maecenas nec felis vel nulla faucibus ornare. Integer vitae ipsum fringilla, dapibus enim ac, imperdiet felis. Fusce placerat tortor vitae tortor laoreet vehicula. Donec dictum sit amet quam ut faucibus. Mauris vel tellus tristique, congue sem ut, condimentum erat. Aliquam erat volutpat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris volutpat erat lacus, egestas viverra enim mattis sed.
Lorem **ipsum dolor** *sit* _amet_, __consectetur adipiscing__ elit. Nunc sit amet tincidunt nulla. Maecenas nec felis vel nulla faucibus ornare. Integer vitae ipsum fringilla, dapibus enim ac, imperdiet felis. Fusce placerat tortor vitae tortor laoreet vehicula. Donec dictum sit amet quam ut faucibus. Mauris vel tellus tristique, congue sem ut, condimentum erat. Aliquam erat volutpat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris volutpat erat lacus, egestas viverra enim mattis sed.

Here's a link to Google: [Google](google.com)

---
Testing horizontal Rule
Expand All @@ -21,7 +23,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit.

---

Vivamus ultrices erat in maximus pellentesque. Donec ut dui velit. Fusce convallis rutrum pharetra. Aliquam turpis leo, cursus sit amet tincidunt sed, sodales at odio. Phasellus sollicitudin turpis nisl, vitae elementum massa tincidunt volutpat. Donec porttitor venenatis libero, vitae bibendum nunc consectetur sit amet.
__Vivamus ultrices erat in maximus pellentesque.__ _Donec ut dui velit._ **Fusce convallis rutrum pharetra.** *Aliquam turpis leo, cursus sit amet tincidunt sed, **sodales at odio.*** Phasellus sollicitudin turpis nisl, vitae elementum massa tincidunt volutpat. Donec porttitor venenatis libero, vitae bibendum nunc consectetur sit amet.
---
Praesent dignissim, eros pellentesque maximus facilisis, dui odio hendrerit purus, nec condimentum nibh risus et neque. Morbi bibendum eros nec pulvinar molestie. Mauris venenatis nec quam sit amet fringilla. Vivamus auctor dictum ante, finibus aliquam ante tincidunt ac. Quisque in pulvinar neque. Aliquam id est lacus. Ut est ipsum, volutpat nec nisl ac, ornare ultricies metus. Vivamus ornare, sem in molestie dapibus, metus urna consectetur diam, non posuere ante odio quis eros. Interdum et malesuada fames ac ante ipsum primis in faucibus.

Expand Down
23 changes: 23 additions & 0 deletions utils/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package utils

import "fmt"

const (
InputHelpMessage string = "Path to a .txt / .md file OR a folder containing .txt / .md files to be turned into HTML"
OutputHelpMessage string = "Optional. Additionaly changes the output path of generated HTML"
HelpHelpMessage string = "Display detailed help message"
VersionHelpMessage string = "Display installed version of SSGo"
ConfigHelpMessage string = "Path to a .json file containing SSGo configuration options"
)

func PrintHelp() {
fmt.Println("Basic usage: ssgo [flag] [value]")
fmt.Println("Flags:")
fmt.Println("\t[-i | --input] [path] \t- " + InputHelpMessage)
fmt.Println("\t \t For paths with spaces, please enclose them into double quotation marks, e.g. \"some path\"")
fmt.Println("\t \t By default, places generated HTML into ./dist.")
fmt.Println("\t[-o | --output] [out path] \t- " + OutputHelpMessage)
fmt.Println("\n\t[-v | --version] \t- " + HelpHelpMessage)
fmt.Println("\t[-h | --help] \t- " + VersionHelpMessage)
fmt.Println("\t[-c | --config] \t- " + ConfigHelpMessage)
}
193 changes: 193 additions & 0 deletions utils/html-generation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package utils

import (
"bufio"
"fmt"
"log"
"os"
"path/filepath"
"strings"
)

const (
beforeTitleHTML string = "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/water.css@2/out/water.css\">\n<title>"
afterTitleHTML string = "</title>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n</head>\n<body>\n"
closingHTML string = "\n</body>\n</html>"
)

// Takes path to .txt file as an input, reads it, and creates name.html in output folder
func GenerateHTML(input string, output string, name string) {

// Create new empty .html file
newFile, err := os.Create(output + "/" + name + ".html")
if err != nil {
log.Fatal(err)
}
if debug {
log.Println("File created at " + output + "/" + name + ".html")
}
defer newFile.Close()

txtFile, err := os.Open(input)
if err != nil {
log.Fatal(err)
}
defer txtFile.Close()

scanner := bufio.NewScanner(txtFile)

var titleExists bool = true
var title string = name

// Check title
scanner.Scan()
firstLine := scanner.Text()
if len(firstLine) != 0 {
for i := 0; i < 2; i++ {
if !scanner.Scan() {
break
}
if len(scanner.Text()) != 0 {
titleExists = false
}
}
if titleExists {
title = firstLine
}
}

// Writing HTML head to buffer
writer := bufio.NewWriter(newFile)
_, werr := writer.WriteString(beforeTitleHTML + title + afterTitleHTML)
if werr != nil {
log.Fatal("Error writing to buffer!")
}

// Write title or restart Scanner
if titleExists {
if debug {
fmt.Println("Title:", title)
}
firstLine = "<h1>" + title + "</h1>\n"
_, werr = writer.WriteString(firstLine)
if werr != nil {
log.Fatal("Error writing to buffer!")
}
} else {
if debug {
fmt.Println("No title found")
}
// If title does not exist, restart Scanner by opening another instance of the same file
// This way, it will read again from the first line
reTxtFile, err := os.Open(input)
if err != nil {
log.Fatal(err)
}
defer reTxtFile.Close()

scanner = bufio.NewScanner(reTxtFile)
}

paragraphOpen := false
paragraphDelimiterFound := false
firstNonMarkdownLineWritten := false

// Scan line by line and append to html buffer
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
if text != "" {
// Write closing </p> tag if delimiter was found and opening <p> was previously written
if paragraphOpen && paragraphDelimiterFound {
_, werr = writer.WriteString("</p>\n")
if werr != nil {
log.Fatal("Error writing to new file!")
}
paragraphOpen = false
}

// Parse markdown file
markdownValid := false

if filepath.Ext(input) == ".md" {
if CheckHorizontalRule(text) {
// First, close existing paragraph
if paragraphOpen {
_, werr = writer.WriteString("</p>\n")
if werr != nil {
log.Fatal("Error writing to new file!")
}
paragraphOpen = false
}
// Set delimeter to true, as this is exactly as blank line
paragraphDelimiterFound = true
_, werr = writer.WriteString("<hr>\n")
if werr != nil {
log.Fatal("Error writing to new file!")
}
markdownValid = true

} else {
// Turn inline Markdown features to HTML
text = GenerateInlineMarkdownHtml(text)
// If prefix is a heading or similar markdown feature
// that overwrites regular paragraph, change it
if prefix, validPrefix := CheckMarkdownPrefix(text); validPrefix {
// We don't want to put headers inside <p> tags
if paragraphOpen {
_, werr = writer.WriteString("</p>\n")
if werr != nil {
log.Fatal("Error writing to new file!")
}
paragraphOpen = false
// This is set to true so for next non markdown text a new <p> is written first
paragraphDelimiterFound = true
}
_, werr = writer.WriteString(GeneratePrefixMarkdownHtml(prefix, text))
if werr != nil {
log.Fatal("Error writing to new file!")
}
markdownValid = true
}
}
}

if !markdownValid {
// Write opening <p> tag is this is the first non markdown line
if !firstNonMarkdownLineWritten {
text = "<p>" + text
paragraphOpen = true
firstNonMarkdownLineWritten = true
}

// If last read line was a paragraph delimiter, write opening <p> first
if !paragraphOpen && paragraphDelimiterFound {
text = "<p>" + text
paragraphOpen = true
paragraphDelimiterFound = false
}
_, werr = writer.WriteString(text)
if werr != nil {
log.Fatal("Error writing to new file!")
}
}
} else {
paragraphDelimiterFound = true
}
}

if err := scanner.Err(); err != nil {
log.Fatal(err)
}

// Writing closing HTML tags to buffer
_, w2err := writer.WriteString("</p>" + closingHTML)
if w2err != nil {
log.Fatal("Error writing to new file!")
}

// Writing buffer to the file
if debug {
log.Println("Writing buffer to file...")
}
writer.Flush()
}
Loading

0 comments on commit 1bbc92d

Please sign in to comment.