Skip to content
Snippets Groups Projects
Verified Commit 7693af6c authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

chore: commit save point

parent 3a97d95f
No related branches found
No related tags found
No related merge requests found
package main
import (
"os"
"path"
"strings"
"time"
"gopkg.in/yaml.v3"
)
type document struct {
ToDos []task `yaml:"-"`
Absolute string `yaml:"-"`
File string `yaml:"-"`
// remember the node structure of yaml
OriginNode *yaml.Node `yaml:"-"`
OriginText string `yaml:"-"`
Title string `yaml:"Title"`
Abbreviation string `yaml:"Abbreviation"`
References []string `yaml:"References"`
Keywords []string `yaml:"Keywords"`
Authors []string `yaml:"Authors"`
Version string `yaml:"Version"`
Created time.Time `yaml:"Created"`
LastUpdate time.Time `yaml:"Last Update"`
Language string `yaml:"Language"`
}
func addDocument() error {
if arguments.Add.Name == "" {
printErrorAndExit(2, "the name must not be empty")
}
p := path.Join(arguments.Path, arguments.Add.Name+".md")
if fileExists(p) {
printErrorAndExit(2, "the document with name already exists", arguments.Add.Name, p)
}
t := config.Document.Template.Add
t = strings.Replace(t, "%%ID%%", arguments.Add.Name, -1)
t = strings.Replace(t, "%%CREATED%%", time.Now().Format("2006-01-02"), -1)
d1 := []byte(t)
err := os.WriteFile(p, d1, 0644)
if err != nil {
return err
}
return nil
}
package main
import "errors"
var (
noGitRepositoryError = errors.New("no git repository found")
notFoundError = errors.New("not found")
notPermittedError = errors.New("not permitted")
)
package main
import (
"bytes"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
func collectStructureFromFiles(directory string) (error, map[string]*documentContent) {
cleanedDirectory, err := filepath.Abs(path.Clean(directory))
pageMap := make(map[string]*documentContent)
err = filepath.Walk(cleanedDirectory,
func(current string, info os.FileInfo, err error) error {
if err != nil {
return err
}
cleanedPath := path.Clean(current)
if info.IsDir() {
return nil
}
ext := filepath.Ext(cleanedPath)
if ext != ".md" {
return nil
}
content, err := ioutil.ReadFile(cleanedPath)
if err != nil {
return err
}
err, p := splitYamlParts(content)
if err != nil {
printWarning("the file contains structural errors. check the YAML and if necessary the template.", cleanedPath, err)
}
bd := []byte(cleanedDirectory)
bp := []byte(cleanedPath)
bs := string(bp[len(bd):len(bp)])
p.meta.File = "." + bs
p.meta.Absolute = cleanedPath
p.meta.ToDos = findTask(content)
k := cleanedPath
pageMap[k] = &p
return nil
})
return err, pageMap
}
func rewriteFiles(pageData map[string]*document) error {
for filename, pd := range pageData {
buf := new(bytes.Buffer)
var encoder = yaml.NewEncoder(buf)
err := encoder.Encode(pd.OriginNode)
if err != nil {
return err
}
encoder.Close()
text := "---\n" + buf.String() + "\n...\n"
text += strings.Trim(pd.OriginText, "\n")
info, err := os.Stat(filename)
if err != nil {
return err
}
mode := info.Mode()
err = os.WriteFile(filename, []byte(text), mode)
if err != nil {
return err
}
}
return nil
}
package main
import (
"fmt"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
"html/template"
"os"
"path"
"time"
)
type PageDataset struct {
Body string
HasBody bool
Created time.Time
CreatedFormat string
Updated time.Time
UpdatedFormat string
Language string
HasLanguage bool
//Config *Configuration
//Meta string
//HasMeta bool
//HasChangelog bool
//Changelog string
//Tasks string
//HasTasks bool
//Documents string
//HasDocuments bool
//Language string
//HasLanguage bool
//Canonical string
//HasCanonical bool
//Description string
//HasDescription bool
//Title string
//HasTitle bool
//Body string
//HasBody bool
//keys []string
}
func createHTML() error {
err, pageData := collectStructureFromFiles(config.Path)
if err != nil {
return err
}
dataset, err := getDataset(pageData, 0)
fmt.Println(dataset)
if err != nil {
return err
}
for _, p := range pageData {
fmt.Println(p.text)
d := &PageDataset{
//Created: p.created,
//CreatedFormat: p.createdFormat,
//Updated: p.updated,
//UpdatedFormat: p.updatedFormat,
//Language: p.language,
//HasLanguage: p.hasLanguage,
}
fmt.Printf(d.CreatedFormat)
//initBody(d, pageData)
//err = createHTMLFile(p, d)
//if err != nil {
// return err
//}
}
return nil
}
//func initBody(d *Dataset, pageData map[string]*documentContent) {
//
// d.Body = ""
// d.HasBody = false
//
// for _, k := range d.keys {
// d.HasBody = true
// p := pageData[k].meta
// d.Body = d.Body + getAdjustedContent(p.Absolute)
// }
//
//}
func convertToHtml(text string) string {
extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.Footnotes | parser.SuperSubscript | parser.Includes | parser.Attributes
parser := parser.NewWithExtensions(extensions)
htmlFlags := html.CommonFlags | html.HrefTargetBlank
opts := html.RendererOptions{Flags: htmlFlags}
renderer := html.NewRenderer(opts)
md := []byte(text)
return string(markdown.ToHTML(md, parser, renderer))
}
func createHTMLFile(p *documentContent, d *PageDataset) error {
if d.Body == "" {
d.HasBody = false
} else {
d.HasBody = true
}
t, err := template.New("pdf").Parse(config.PDF.Template.Internal.MarkdownContent)
if err != nil {
return err
}
outputDir := arguments.Build.HTML.Output
if outputDir == "" {
printErrorAndExit(2, "if the type is html, the output option must be specified")
}
if !path.IsAbs(outputDir) {
outputDir = path.Join(config.Path, outputDir)
}
fileinfo, err := os.Stat(outputDir)
if os.IsNotExist(err) {
printErrorAndExit(2, "The file %s does not exist", outputDir)
}
if !fileinfo.IsDir() {
printErrorAndExit(2, "The file %s is not a directory", outputDir)
}
fileName := path.Join(outputDir, ".html")
file, err := os.Create(fileName)
if err != nil {
return err
}
err = t.Execute(file, d)
if err != nil {
return err
}
return nil
}
package main
import (
"golang.org/x/text/language"
"golang.org/x/text/message"
"golang.org/x/text/message/catalog"
)
type l10nLocaleTranslation struct {
tag string
msg interface{}
}
type l10nKeyTranslation struct {
key string
tm []l10nLocaleTranslation
}
var l10nMap = []l10nKeyTranslation{
{
"does not contain a valid yaml definition",
[]l10nLocaleTranslation{
{"de", "\"%s\" enthält keine gültige yaml Struktur."},
{"en", "\"%s\" does not contain a valid yaml definition."},
},
},
{
"the specified template",
[]l10nLocaleTranslation{
{"de", "Das angegebene AddTemplate \"%s\" wurde nicht gefunden."},
{"en", "the specified template \"%s\" was not found."},
},
},
{
"the due of the todo cannot be parsed",
[]l10nLocaleTranslation{
{"de", "Das Datum %s der Aufgabe \"%s\" kann nicht verarbeitet werden."},
{"en", "the due %s of the todo \"%s\" cannot be parsed."},
},
},
{
"ToDo",
[]l10nLocaleTranslation{
{"de", "Aufgabe"},
{"en", "task"},
},
},
{
"Due",
[]l10nLocaleTranslation{
{"de", "Bis"},
{"en", "due"},
},
}, {
"File",
[]l10nLocaleTranslation{
{"de", "Datei"},
{"en", "file"},
},
}, {
"group",
[]l10nLocaleTranslation{
{"de", "Gruppe"},
{"en", "group"},
},
},
{
"Description",
[]l10nLocaleTranslation{
{"de", "Beschreibung"},
{"en", "Description"},
},
},
{
"Delivery until",
[]l10nLocaleTranslation{
{"de", "Bis"},
{"en", "until"},
},
},
{
"Provided on",
[]l10nLocaleTranslation{
{"de", "Am"},
{"en", "on"},
},
},
{
"Provided by",
[]l10nLocaleTranslation{
{"de", "Von"},
{"en", "by"},
},
},
{
"Type",
[]l10nLocaleTranslation{
{"de", "Typ"},
{"en", "Type"},
},
},
{
"Title",
[]l10nLocaleTranslation{
{"de", "Titel"},
{"en", "Title"},
},
},
{
"Alias",
[]l10nLocaleTranslation{
{"de", "Alias"},
{"en", "Alias"},
},
},
{
"Type",
[]l10nLocaleTranslation{
{"de", "Typ"},
{"en", "Type"},
},
},
{
"Keywords",
[]l10nLocaleTranslation{
{"de", "Schlüsselwörter"},
{"en", "Keywords"},
},
}, {
"Estimation",
[]l10nLocaleTranslation{
{"de", "Schätzung"},
{"en", "Estimation"},
},
}, {
"Source",
[]l10nLocaleTranslation{
{"de", "Quelle"},
{"en", "Source"},
},
},
{
"Author",
[]l10nLocaleTranslation{
{"de", "Autor"},
{"en", "Author"},
},
},
{
"Status",
[]l10nLocaleTranslation{
{"de", "Status"},
{"en", "Status"},
},
},
{
"Complexity",
[]l10nLocaleTranslation{
{"de", "Komplexität"},
{"en", "Complexity"},
},
},
{
"Difficulty",
[]l10nLocaleTranslation{
{"de", "Schwierigkeit"},
{"en", "Difficulty"},
},
},
{
"Priority",
[]l10nLocaleTranslation{
{"de", "Priorität"},
{"en", "Priority"},
},
},
{
"Version",
[]l10nLocaleTranslation{
{"de", "Version"},
{"en", "Version"},
},
},
{
"Milestone",
[]l10nLocaleTranslation{
{"de", "Meilenstein"},
{"en", "Milestone"},
},
},
{
"Created",
[]l10nLocaleTranslation{
{"de", "Erstellt am"},
{"en", "Created"},
},
},
{
"LastUpdate",
[]l10nLocaleTranslation{
{"de", "Letzte Änderung"},
{"en", "LastUpdate"},
},
},
{
"The file cannot be read",
[]l10nLocaleTranslation{
{"de", "Die Datei \"%s\" kann nicht eingelesen werden."},
{"en", "The file \"%s\" cannot be read."},
},
},
{
"The output file cannot be written",
[]l10nLocaleTranslation{
{"de", "Die Ausgabedatei kann nicht geschrieben werden (%s)."},
{"en", "The output file cannot be written (%s)."},
},
}, {
"A temporary file cannot be created",
[]l10nLocaleTranslation{
{"de", "Es kann keine temporäre Datei angelegt werden (%s)."},
{"en", "A temporary file cannot be created (%s)."},
},
}, {
"Checked",
[]l10nLocaleTranslation{
{"de", "Erledigt"},
{"en", "done"},
},
},
{
"Title",
[]l10nLocaleTranslation{
{"de", "Title"},
{"en", "Title"},
},
},
{
"Type",
[]l10nLocaleTranslation{
{"de", "Typ"},
{"en", "Type"},
},
}, {
"RequirementID",
[]l10nLocaleTranslation{
{"de", "Documents"},
{"en", "Anforderungen"},
},
}, {
"the id must not be empty",
[]l10nLocaleTranslation{
{"de", "Die ID muss angegeben werden"},
{"en", "the id must not be empty"},
},
},
{
"the document with name already exists",
[]l10nLocaleTranslation{
{"de", "Das Dokument mit dem Namen %s existiert bereits (%s)."},
{"en", "The document named %s already exists (%s)."},
},
},
{
"YAML parse error",
[]l10nLocaleTranslation{
{"de", "YAML Fehler: %s "},
{"en", "YAML parse error: %s ."},
},
},
{
"if the type is pdf, the output option must be specified",
[]l10nLocaleTranslation{
{"de", "Der Tpy PDF benötigt die Option --output"},
{"en", "if the type is pdf, the output option must be specified"},
},
},
{
"if the type is html, the output option must be specified",
[]l10nLocaleTranslation{
{"de", "Der Tpy HTML benötigt die Option --output"},
{"en", "if the type is html, the output option must be specified"},
},
},
{
"Unknown Error",
[]l10nLocaleTranslation{
{"de", "Unbekannter Fehler: %s"},
{"en", "Unknown Error %s"},
},
},
{
"the file contains structural errors. check the YAML and if necessary the template.",
[]l10nLocaleTranslation{
{"de", "Die Datei %s enthält strukturelle Fehler (%s). Überprüfen Sie die Datei."},
{"en", "the file %s contains structural errors (%s). Check the if necessary the file."},
},
},
{
"the file is empty",
[]l10nLocaleTranslation{
{"de", "Die Datei enthält keinen Inhalt."},
{"en", "the file is empty."},
},
},
{
"the grouping key was not found",
[]l10nLocaleTranslation{
{"de", "Der Schlüssel %s existiert nicht"},
{"en", "the grouping key %s was not found"},
},
},
{
"Ratio",
[]l10nLocaleTranslation{
{"de", "Verhältnis"},
{"en", "Ratio"},
},
},
{
"Standard Deviation",
[]l10nLocaleTranslation{
{"de", "Standardabweichung"},
{"en", "Standard Deviation"},
},
},
{
"Variance",
[]l10nLocaleTranslation{
{"de", "Varianz"},
{"en", "Variance"},
},
},
{
"Average",
[]l10nLocaleTranslation{
{"de", "Mittelwert"},
{"en", "Average"},
},
},
{
"Time Spent",
[]l10nLocaleTranslation{
{"de", "Aufwand"},
{"en", "Time Spent"},
},
},
{
"Estimated",
[]l10nLocaleTranslation{
{"de", "Planwert"},
{"en", "Estimated"},
},
},
{
"unsuported type",
[]l10nLocaleTranslation{
{"de", "nicht unterstützter Typ %s"},
{"en", "unsuported type %s"},
},
},
{
"no value",
[]l10nLocaleTranslation{
{"de", "kein Wert"},
{"en", "no value"},
},
},
{
"opened",
[]l10nLocaleTranslation{
{"de", "offen"},
{"en", "opened"},
},
},
{
"closed",
[]l10nLocaleTranslation{
{"de", "geschlossen"},
{"en", "closed"},
},
},
{
"State",
[]l10nLocaleTranslation{
{"de", "Status"},
{"en", "State"},
},
},
{
"Due date",
[]l10nLocaleTranslation{
{"de", "Fälligkeitsdatum"},
{"en", "Due Date"},
},
},
{
"Labels",
[]l10nLocaleTranslation{
{"de", "Labels"},
{"en", "Labels"},
},
},
{
"Estimate",
[]l10nLocaleTranslation{
{"de", "Planwert"},
{"en", "Estimate"},
},
},
{
"Spent",
[]l10nLocaleTranslation{
{"de", "Aufwand"},
{"en", "Spent"},
},
},
{
"Assignees",
[]l10nLocaleTranslation{
{"de", "Zuweisungen"},
{"en", "Assignees"},
},
}, {
"Statistics",
[]l10nLocaleTranslation{
{"de", "Statistiken"},
{"en", "Statistics"},
},
},
{
"Untitled",
[]l10nLocaleTranslation{
{"de", "Unbenannt"},
{"en", "Untitled"},
},
},
}
func initL10n() {
for _, e := range l10nMap {
key := e.key
for _, f := range e.tm {
tag := language.MustParse(f.tag)
switch msg := f.msg.(type) {
case string:
message.SetString(tag, key, msg)
case catalog.Message:
message.Set(tag, key, msg)
case []catalog.Message:
message.Set(tag, key, msg...)
}
}
}
}
package main
import (
"os"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
// Wird beim Bauen per
// -ldflags "-X main.version=$app_version -X main.build=$(due --iso-8601 | tr -d "-" )"
// gesetzt
var (
version string = "dev"
build string = "dev"
printer *message.Printer
//sugar *zap.SugaredLogger
)
var serverLangs = []language.Tag{
language.English, // en fallback
language.German, // de
}
var matcher = language.NewMatcher(serverLangs)
var userPrefs = []language.Tag{
language.Make(os.Getenv("LANG")),
language.Make("en"),
}
func init() {
initEnvironment()
tag, _, _ := matcher.Match(userPrefs...)
printer = message.NewPrinter(tag)
initL10n()
}
func initEnvironment() {
}
/**
*/
func main() {
executeCommand()
}
package main
import (
"os"
"github.com/gookit/color"
)
var lastBlock string
// print error
func printErrorAndExit(code int, message string, a ...interface{}) {
printError(message, a...)
if code == 0 {
code = exitCodeCatchAll
}
os.Exit(code)
}
func printError(message string, a ...interface{}) {
message = printer.Sprintf(message, a...)
if lastBlock == "error" {
color.Error.Println(" " + message)
return
}
lastBlock = "error"
color.Error.Block(message)
}
func printWarning(message string, a ...interface{}) {
message = printer.Sprintf(message, a...)
if lastBlock == "warning" {
color.Warn.Println(" " + message)
return
}
lastBlock = "warning"
color.Warn.Block(message)
}
func printInfo(message string, a ...interface{}) {
message = printer.Sprintf(message, a...)
if lastBlock == "info" {
color.Info.Println(" " + message)
return
}
lastBlock = "info"
color.Info.Block(message)
}
package main
import (
"fmt"
"os/exec"
)
func runPandoc(source string, outputName string, latexPath string) string {
arguments := "/bin/env pandoc "
arguments += "--number-sections "
arguments += "--variable \"geometry:a4paper,margin=2cm\" "
arguments += "--variable fontsize=12pt "
arguments += "--variable version=2.0 "
arguments += source + " "
arguments += "--pdf-engine=xelatex "
arguments += "--listings "
if latexPath != "" {
arguments += "--template=" + latexPath + " "
}
if luaRawBlockFile != nil {
arguments += "--lua-filter=" + luaRawBlockFile.Name() + " "
}
arguments += "--columns=5 "
arguments += "--highlight-style espresso "
arguments += "--toc "
arguments += "--output=" + outputName + " "
cmd, err := exec.Command("bash", "-c", arguments).Output()
if err != nil {
exitErr, ok := err.(*exec.ExitError)
if ok {
printErrorAndExit(2, string(exitErr.Stderr))
} else {
printErrorAndExit(2, err.Error())
}
}
fmt.Println(string(cmd))
return string(cmd)
}
package main
import (
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"strings"
"text/template"
)
func CreatePDF() error {
err, pageData := collectStructureFromFiles(config.Path)
if err != nil {
return err
}
d, err := getDataset(pageData, flagInitChangelog|flagInitTasks|flagInitDocuments)
if err != nil {
return err
}
outputName := arguments.Build.PDF.Output
if outputName == "" {
printErrorAndExit(2, "if the type is pdf, the output option must be specified")
}
file, err := ioutil.TempFile(os.TempDir(), "docman")
if err != nil {
printErrorAndExit(2, "A temporary file cannot be created", err.Error())
}
defer os.Remove(file.Name())
t, err := template.New("pdf").Parse(config.PDF.Template.Internal.MarkdownContent)
if err != nil {
return err
}
err = t.Execute(file, d)
if err != nil {
return err
}
createLuaFile()
runPandoc(file.Name(), outputName, config.PDF.Template.Latex)
if luaRawBlockFile != nil {
luaRawBlockFile.Close()
}
return nil
}
var luaRawBlockFile *os.File
func createLuaFile() {
var err error
luaRawBlockFile, err = ioutil.TempFile(os.TempDir(), "lua-raw-block")
if err != nil {
printErrorAndExit(2, "A temporary file cannot be created", err.Error())
}
luaRawBlockFile.WriteString(`
function RawBlock (raw)
return raw.format:match 'html'
and pandoc.read(raw.text, 'html').blocks
or raw
end
`)
}
func getAdjustedContent(absolute string) string {
content, err := os.ReadFile(absolute)
if err != nil {
printError("The file cannot be read", absolute)
return ""
}
err, def := splitYamlParts(content)
if err != nil {
printError(err.Error())
return ""
}
s := convertImages(def.text, path.Dir(absolute))
return s
}
func convertImages(content string, absolute string) string {
todoRegEx := regexp.MustCompile(`(?P<match>\!\[(?P<label>[^]]*)\]\((?P<path>[^)]*)\))`)
matches := todoRegEx.FindAllStringSubmatch(content, -1)
if matches == nil {
return content
}
for _, match := range matches {
result := make(map[string]string)
for i, name := range todoRegEx.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
if filepath.IsAbs(result["path"]) {
continue
}
path := path.Clean(absolute + "/" + result["path"])
content = strings.Replace(content, result["match"], "!["+result["label"]+"]("+path+")", -1)
}
return content
}
func convertTemplateLogo(content string, absolute string) string {
todoRegEx := regexp.MustCompile(`(?m)^(?P<match>logo:\s*"?(?P<path>[^"\n]*)"?\s*)$`)
matches := todoRegEx.FindAllStringSubmatch(content, -1)
if matches == nil {
return content
}
for _, match := range matches {
result := make(map[string]string)
for i, name := range todoRegEx.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
if filepath.IsAbs(result["path"]) {
continue
}
path := path.Clean(absolute + "/" + result["path"])
content = strings.Replace(content, result["match"], "logo: \""+path+"\"", -1)
}
return content
}
func convertTemplateLatexLogo(content string, absolute string) string {
todoRegEx := regexp.MustCompile(`(?m)(?P<match>\\includegraphics[^{]*\{(?P<path>[^}]*)\})`)
matches := todoRegEx.FindAllStringSubmatch(content, -1)
if matches == nil {
return content
}
for _, match := range matches {
result := make(map[string]string)
for i, name := range todoRegEx.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
if filepath.IsAbs(result["path"]) {
continue
}
path := path.Clean(absolute + "/" + result["path"])
a := strings.Replace(result["match"], result["path"], path, -1)
content = strings.Replace(content, result["match"], a, -1)
}
return content
}
func convertTemplateImages(content string, absolute string) string {
content = convertTemplateLogo(content, absolute)
content = convertTemplateLatexLogo(content, absolute)
return content
}
package main
import (
"bytes"
"log"
"os/exec"
"syscall"
)
func runCommand(name string, args ...string) (stdout string, stderr string, exitCode int) {
var outbuf, errbuf bytes.Buffer
cmd := exec.Command(name, args...)
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
err := cmd.Run()
stdout = outbuf.String()
stderr = errbuf.String()
if err != nil {
// try to get the exit code
if exitError, ok := err.(*exec.ExitError); ok {
ws := exitError.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
} else {
log.Printf("Could not get exit code for failed program: %v, %v", name, args)
exitCode = exitCodeCatchAll
if stderr == "" {
stderr = err.Error()
}
}
} else {
// success, exitCode should be 0 if go is ok
ws := cmd.ProcessState.Sys().(syscall.WaitStatus)
exitCode = ws.ExitStatus()
}
return
}
package main
import (
"bytes"
"fmt"
"regexp"
"time"
"github.com/olekukonko/tablewriter"
)
type task struct {
due time.Time
text string
checked bool
}
const dateLayout = "2006-01-02 15:04:05 GMT"
func newTask(date string, text string, checked bool) task {
var d time.Time
var err error
if date != "" {
d, err = time.Parse(dateLayout, date+" 00:00:00 GMT")
if err != nil {
printError("the due of the todo cannot be parsed", date, text)
}
}
t := task{
due: d,
text: text,
checked: checked,
}
return t
}
func findTask(content []byte) []task {
toDos := []task{}
todoRegEx := regexp.MustCompile(`(?m)^\- \[(?P<checked>(x|\s?))\]\s*(?P<due>[2][0-9]{3}-[0-9]{2}-[0-9]{2}){0,1}\s*(?P<text>[^\n]*)`)
s := string(content)
matches := todoRegEx.FindAllStringSubmatch(s, -1)
if matches == nil {
return []task{}
}
for _, match := range matches {
result := make(map[string]string)
for i, name := range todoRegEx.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
checked := true
if result["checked"] != "x" {
checked = false
}
t := newTask(result["due"], result["text"], checked)
toDos = append(toDos, t)
}
return toDos
}
func buildTasksTable(pageMap map[string]*documentContent, extended bool) (error, string, bool) {
buf := new(bytes.Buffer)
table := tablewriter.NewWriter(buf)
has := false
header := []string{
printer.Sprintf("ToDo"),
printer.Sprintf("Due"),
printer.Sprintf("Checked")}
if extended == true {
header = append(header, printer.Sprintf("File"))
}
table.SetHeader(header)
table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
table.SetCenterSeparator("|")
var tableData [][]string
for _, pageDoc := range pageMap {
pageData := pageDoc.meta
for _, info := range pageData.ToDos {
has = true
var d string
if info.due.IsZero() {
d = "—"
} else {
d = info.due.Format(config.Locale.DateFormat)
}
checked := "—"
if info.checked == true {
checked = "✓"
}
cols := []string{info.text, d, checked}
if extended == true {
cols = append(cols, pageData.File)
}
tableData = append(tableData, cols)
}
}
table.AppendBulk(tableData) // Add Bulk Data
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.Render()
return nil, buf.String(), has
}
func printTaskTable() error {
err, pageData := collectStructureFromFiles(config.Path)
if err != nil {
return err
}
err, table, _ := buildTasksTable(pageData, true)
fmt.Println(table)
return nil
}
package main
import (
"bytes"
"errors"
"os"
"path/filepath"
"strings"
"text/template"
"gopkg.in/yaml.v3"
)
type documentContent struct {
text string
meta document
}
func splitYamlParts(content []byte) (error, documentContent) {
origin := string(content)
meta := ""
text := ""
before, remaining, found := strings.Cut(origin, "---")
if !found {
t := strings.TrimSpace(origin)
if len(t) == 0 {
return errors.New("the file is empty"), documentContent{
text: origin,
meta: document{},
}
}
return errors.New("the file does not contain a definition block"), documentContent{
text: origin,
meta: document{},
}
}
text += before
a, b, found := strings.Cut(remaining, "\n...")
if !found {
a, b, found = strings.Cut(remaining, "\n---")
if !found {
a, b, found = strings.Cut(remaining, "...")
if !found {
a, b, found = strings.Cut(remaining, "---")
if !found {
return errors.New("the file does not contain a definition block"), documentContent{}
}
}
}
}
meta = a
text += b
t, err := template.New("overview").Parse(text)
if err != nil {
return err, documentContent{}
}
var node yaml.Node
err = yaml.Unmarshal([]byte(meta), &node)
if err != nil {
return err, documentContent{}
}
data := document{}
err = node.Decode(&data)
if err != nil {
return err, documentContent{}
}
req := documentContent{}
req.meta = data
req.meta.OriginNode = &node
req.meta.OriginText = text
var buffer bytes.Buffer
err = t.Execute(&buffer, data)
if err != nil {
printError(err.Error())
return err, documentContent{}
}
req.text = buffer.String()
return nil, req
}
func translateHeaders(columns []string) []string {
result := []string{}
for _, column := range columns {
result = append(result, printer.Sprintf(column))
}
return result
}
func getGitDirectory() (string, error) {
path := config.Path
fileInfo, err := os.Stat(path)
if err != nil {
return "", err
}
if !fileInfo.IsDir() {
path = filepath.Dir(path)
}
return findGitDirectory(path)
}
func findGitDirectory(path string) (string, error) {
if path == "" {
return "", noGitRepositoryError
}
if volume := filepath.VolumeName(path); volume != "" {
if volume == path {
return "", noGitRepositoryError
}
} else {
if path == "/" {
return "", noGitRepositoryError
}
}
if !exists(filepath.Join(path, ".git")) {
return findGitDirectory(filepath.Dir(path))
}
return path, nil
}
func exists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
printErrorAndExit(0, err.Error())
return false
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment