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

chore: commit save point

parent b6d7f1b5
No related branches found
No related tags found
No related merge requests found
Showing
with 796 additions and 270 deletions
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="go build requirements-manager and run add requirement" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="requirements-manager" />
<working_directory value="$PROJECT_DIR$/application/source" />
<parameters value="requirements add --id 144444 -p $PROJECT_DIR$/development/examples/example1" />
<kind value="DIRECTORY" />
<package value="gitlab.schukai.com/oss/utilities/requirements-manager" />
<directory value="$PROJECT_DIR$/application/source" />
<filePath value="$PROJECT_DIR$/application/source/main.go" />
<output_directory value="$PROJECT_DIR$/deployment/build" />
<method v="2" />
</configuration>
</component>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<configuration default="false" name="go build requirements-manager and run print overview" type="GoApplicationRunConfiguration" factoryName="Go Application">
<module name="requirements-manager" />
<working_directory value="$PROJECT_DIR$/application/source" />
<parameters value="overview print -c ID -c Title -c Version -p $PROJECT_DIR$/development/examples/example1 -o /tmp/overview.pdf -f pdf -t $PROJECT_DIR$/development/examples/example1/overview.template" />
<parameters value="overview print -c ID -c Title -c Version -p $PROJECT_DIR$/development/examples/example1 -o /tmp/overview.pdf -f pdf -t $PROJECT_DIR$/development/examples/overview.template" />
<kind value="DIRECTORY" />
<package value="gitlab.schukai.com/oss/utilities/requirements-manager" />
<directory value="$PROJECT_DIR$/application/source" />
......
package main
import "fmt"
type commandLineOptions struct {
Path string `short:"p" long:"path" description:"define the path where the specifications are located" default:"."`
DateFormat string `short:"f" long:"date-format" description:"date format" default:"2006-01-02"`
Requirements struct {
Print struct {
Columns []string `short:"c" long:"column" description:"defines the columns used"`
} `command:"print"`
Add struct {
ID string `long:"id" required:"true" description:"new requirement id"`
} `command:"add"`
} `command:"requirements"`
Tasks struct {
Print struct {
} `command:"print"`
} `command:"tasks"`
Items struct {
Print struct {
} `command:"print"`
} `command:"items"`
Overview struct {
Print struct {
Columns []string `short:"c" long:"column" description:"defines the columns used"`
TemplatePath string `short:"t" long:"template" description:"file name of the template of the overview page"`
Output string `short:"o" long:"output" description:"redirect output to a file"`
Format string `short:"f" long:"format" description:"the desired output format (pdf, md)"`
} `command:"print"`
} `command:"overview"`
Version struct {
} `command:"version"`
}
func executeCommand() {
activeCommand, arguments, config := NewConfiguration()
version = "development"
build = "1.1.1"
//
switch activeCommand.Name {
case "version":
fmt.Println("Version " + version + " (" + build + ")")
case "overview":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := PrintOverview(config, arguments)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
case "requirements":
subcommand := activeCommand.Active
switch subcommand.Name {
case "add":
err := addRequirement(config, arguments)
if err != nil {
printErrorAndExit(2, err.Error())
}
case "print":
err := printRequirements(config)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
case "tasks":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := printTaskTable(config)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
case "items":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := printItemTable(config)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
}
}
package main
import (
"log"
"os"
"os/user"
"path"
"path/filepath"
"regexp"
"strings"
"github.com/jessevdk/go-flags"
"gopkg.in/yaml.v3"
......@@ -23,28 +27,6 @@ var (
}
)
const defaultTemplate = `
## Overview
Created: {{ .created }}
{{.Meta}}
## Tasks
{{.Tasks}}
## Items
{{.Items}}
## requirements
{{.Requirements}}
`
// Exporting interface instead of struct
//type Configuration interface{}
......@@ -63,6 +45,10 @@ type Configuration struct {
Overview struct {
Template string `yaml:"template"`
} `yaml:"overview"`
Requirement struct {
Template string `yaml:"template"`
} `yaml:"requirement"`
}
func fileExists(name string) (found bool) {
......@@ -72,34 +58,6 @@ func fileExists(name string) (found bool) {
return false
}
type commandLineOptions struct {
Path string `short:"p" long:"path" description:"define the path where the specifications are located" default:"."`
DateFormat string `short:"f" long:"date-format" description:"date format" default:"2006-01-02"`
Meta struct {
Print struct {
Columns []string `short:"c" long:"column" description:"defines the columns used"`
} `command:"print"`
} `command:"meta"`
ToDos struct {
Print struct {
} `command:"print"`
} `command:"todos"`
Items struct {
Print struct {
} `command:"print"`
} `command:"items"`
Overview struct {
Print struct {
Columns []string `short:"c" long:"column" description:"defines the columns used"`
TemplatePath string `short:"t" long:"template" description:"file name of the template of the overview page"`
Output string `short:"o" long:"output" description:"redirect output to a file"`
Format string `short:"f" long:"format" description:"the desired output format (pdf, md)"`
} `command:"print"`
} `command:"overview"`
Version struct {
} `command:"version"`
}
// NewConfiguration
func NewConfiguration() (*flags.Command, *commandLineOptions, *Configuration) {
......@@ -161,22 +119,37 @@ func NewConfiguration() (*flags.Command, *commandLineOptions, *Configuration) {
}
if arguments.Overview.Print.TemplatePath != "" {
template, err := os.ReadFile(arguments.Overview.Print.TemplatePath)
p := arguments.Overview.Print.TemplatePath
current, err := os.Getwd()
if err != nil {
log.Println(err)
}
if !filepath.IsAbs(p) {
p = path.Clean(current + "/" + p)
}
template, err := os.ReadFile(p)
if err != nil {
printErrorAndExit(exitCodeCatchAll,
"the specified template", arguments.Overview.Print.TemplatePath)
}
cfg.Overview.Template = string(template)
cfg.Overview.Template = convertTemplateImages(string(template), path.Dir(p))
} else {
cfg.Overview.Template = defaultTemplate
cfg.Overview.Template = defaultOverviewTemplate
}
}
case "meta":
case "requirements":
subcommand := activeCommand.Active
switch subcommand.Name {
case "add":
cfg.Requirement.Template = defaultNewRequirementTemplate
case "print":
if len(arguments.Meta.Print.Columns) > 0 {
cfg.Table.Columns = validateColumns(arguments.Meta.Print.Columns)
if len(arguments.Requirements.Print.Columns) > 0 {
cfg.Table.Columns = validateColumns(arguments.Requirements.Print.Columns)
}
}
}
......@@ -184,6 +157,71 @@ func NewConfiguration() (*flags.Command, *commandLineOptions, *Configuration) {
return p.Command.Active, arguments, &cfg
}
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
}
func validateColumns(columns []string) []string {
//for i, column := range columns {
......@@ -193,7 +231,7 @@ func validateColumns(columns []string) []string {
// VALIDATE COLUMS NAME
//
//for _, name := range config.Meta.Columns {
//for _, name := range config.Requirements.Columns {
//
// field := reflect.Indirect(r).FieldByName(name)
// if field == (reflect.Value{}) {
......
package main
const exitOK = 0
// - Catchall for general errors
const exitCodeCatchAll = 1
// Invalid argument to exit
const exitCodeInvalidArgument = 128
package main
const exitOK = 0
// - Catchall for general errors
const exitCodeCatchAll = 1
// Invalid argument to exit
const exitCodeInvalidArgument = 128
const defaultOverviewTemplate = `
---
titlepage: false
...
## Overview
{{.Meta}}
## Tasks
{{.Tasks}}
## Items
{{.Items}}
## Requirements
{{.Requirements}}
`
//
const defaultNewRequirementTemplate = `
---
ID: {{ .ID }}
title:
subtitle:
tags: []
percent:
Estimation:
items:
-
Group:
ID:
Name:
Description:
Delivery until:
Provided by:
Provided on:
Type:
...
## Headline
### Subheading
- [ ] task 1
- [ ] task 2
`
......@@ -12,10 +12,13 @@ import (
)
//
func GetPageData(directory string) (error, []pageData) {
func GetPageData(directory string) (error, map[string]requirement) {
cleanedDirectory := path.Clean(directory)
pageDataList := []pageData{}
pageMap := make(map[string]requirement)
//pageMap := []requirement{}
err := filepath.Walk(cleanedDirectory,
func(current string, info os.FileInfo, err error) error {
......@@ -25,7 +28,14 @@ func GetPageData(directory string) (error, []pageData) {
cleanedPath := path.Clean(current)
if !info.IsDir() {
if info.IsDir() {
return nil
}
ext := filepath.Ext(cleanedPath)
if ext != ".md" {
return nil
}
content, err := ioutil.ReadFile(cleanedPath)
......@@ -46,27 +56,27 @@ func GetPageData(directory string) (error, []pageData) {
p.File = "." + bs
p.Absolute = cleanedPath
p.ToDos = findToDos(content)
//pageData[cleanedPath] = pageData
p.ToDos = findTask(content)
//requirement[cleanedPath] = requirement
pageDataList = append(pageDataList, p)
k := cleanedPath
}
pageMap[k] = p
return nil
})
return err, pageDataList
return err, pageMap
}
func importData(content []byte) (error, pageData) {
func importData(content []byte) (error, requirement) {
data := pageData{}
data := requirement{}
s := string(content)
a := strings.Index(s, "\n---")
if a == -1 {
return errors.New("the file does not contain a definition block"), pageData{}
return errors.New("the file does not contain a definition block"), requirement{}
}
s = s[a+4 : len(s)-1]
b := strings.Index(s, "\n...")
......@@ -82,7 +92,7 @@ func importData(content []byte) (error, pageData) {
err := yaml.Unmarshal([]byte(s), &data)
if err != nil {
return err, pageData{}
return err, requirement{}
}
return nil, data
......
......@@ -9,6 +9,9 @@ import (
)
type Item struct {
ID string `yaml:"ID"`
Name string `yaml:"Name"`
Type string `yaml:"Type"`
Group string `yaml:"Group"`
Description string `yaml:"Description"`
DeliveryUntil time.Time `yaml:"Delivery until"`
......@@ -16,47 +19,115 @@ type Item struct {
ProvidedBy string `yaml:"Provided by"`
}
func buildItemTable(config *Configuration, pageDataList []pageData) (error, string) {
func buildItemOverviewTable(config *Configuration, pageMap map[string]requirement, extended bool) (error, string) {
buf := new(bytes.Buffer)
table := tablewriter.NewWriter(buf)
table.SetHeader([]string{
var header []string
if extended {
header = []string{
printer.Sprintf("ID"),
printer.Sprintf("Group"),
printer.Sprintf("Name"),
printer.Sprintf("Type"),
printer.Sprintf("Description"),
printer.Sprintf("Delivery until"),
printer.Sprintf("Checked"),
printer.Sprintf("Provided on"),
printer.Sprintf("Provided by"),
printer.Sprintf("File"),
})
}
} else {
header = []string{
printer.Sprintf("ID"),
printer.Sprintf("Name"),
printer.Sprintf("Delivery until"),
printer.Sprintf("Checked"),
}
}
table.SetHeader(header)
table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
table.SetCenterSeparator("|")
var tableData [][]string
for _, pageData := range pageDataList {
for _, pageData := range pageMap {
for _, info := range pageData.Items {
var db, do string
var deliveryUntilFormatted, providedOnDate, checked string
if info.DeliveryUntil.IsZero() {
db = "—"
deliveryUntilFormatted = "—"
} else {
db = info.DeliveryUntil.Format(config.Locale.DateFormat)
deliveryUntilFormatted = info.DeliveryUntil.Format(config.Locale.DateFormat)
}
if info.ProvidedOn.IsZero() {
providedOnDate = "—"
} else {
providedOnDate = info.ProvidedOn.Format(config.Locale.DateFormat)
}
if info.DeliveryUntil.IsZero() {
deliveryUntilFormatted = "—"
} else {
deliveryUntilFormatted = info.DeliveryUntil.Format(config.Locale.DateFormat)
}
if info.ProvidedOn.IsZero() {
do = "—"
checked = "—"
} else {
do = info.ProvidedOn.Format(config.Locale.DateFormat)
checked = "✓"
}
id := "—"
if info.ID != "" {
id = info.ID
}
//text := info.Description + ", "
//text += printer.Sprintf("Group") + ": " + info.Group + ", "
//text += printer.Sprintf("File") + ": " + pageData.File
//text += printer.Sprintf("File") + ": " + requirement.File
var col []string
/*
header = []string{
printer.Sprintf("ID"),
printer.Sprintf("Name"),
printer.Sprintf("Delivery until"),
printer.Sprintf("Checked"),
}
} else {
header = []string{
printer.Sprintf("ID"),
printer.Sprintf("Group"),
printer.Sprintf("Name"),
printer.Sprintf("Type"),
printer.Sprintf("Description"),
printer.Sprintf("RequirementID"),
printer.Sprintf("Delivery until"),
printer.Sprintf("Checked"),
printer.Sprintf("Provided on"),
printer.Sprintf("Provided by"),
}
*/
if extended {
col = []string{id, info.Group, info.Name, info.Type, info.Description, deliveryUntilFormatted, checked, providedOnDate, info.ProvidedBy, pageData.File}
} else {
col = []string{id, info.Name, deliveryUntilFormatted, deliveryUntilFormatted, checked}
}
tableData = append(tableData, []string{info.Group, info.Description, db, do, info.ProvidedBy, pageData.File})
//tableData = append(tableData, []string{text, db, do, info.ProvidedBy})
tableData = append(tableData, col)
//tableData = append(tableData, []string{text, deliveryUntilFormatted, checked, info.ProvidedBy})
}
}
......@@ -69,12 +140,12 @@ func buildItemTable(config *Configuration, pageDataList []pageData) (error, stri
}
func printItemTable(config *Configuration) error {
err, pageData := GetPageData(config.Path)
err, pageMap := GetPageData(config.Path)
if err != nil {
return err
}
err, table := buildItemTable(config, pageData)
err, table := buildItemOverviewTable(config, pageMap, true)
fmt.Println(table)
return nil
......
......@@ -125,6 +125,18 @@ var l10nMap = []l10nKeyTranslation{
{"de", "Schlüsselwörter"},
{"en", "Keywords"},
},
}, {
"Estimation",
[]l10nLocaleTranslation{
{"de", "Schätzung"},
{"en", "Estimation"},
},
}, {
"Source",
[]l10nLocaleTranslation{
{"de", "Quelle"},
{"en", "Source"},
},
},
{
"Author",
......@@ -208,6 +220,44 @@ var l10nMap = []l10nKeyTranslation{
{"de", "Es kann keine temporäre Datei angelegt werden (%s)."},
{"en", "A temporary file cannot be created (%s)."},
},
}, {
"Checked",
[]l10nLocaleTranslation{
{"de", "Erledigt"},
{"en", "done"},
},
},
{
"Name",
[]l10nLocaleTranslation{
{"de", "Name"},
{"en", "Name"},
},
},
{
"Type",
[]l10nLocaleTranslation{
{"de", "Typ"},
{"en", "Type"},
},
}, {
"RequirementID",
[]l10nLocaleTranslation{
{"de", "Requirements"},
{"en", "Anforderungen"},
},
}, {
"the id must not be empty",
[]l10nLocaleTranslation{
{"de", "Die ID muss angegeben werden"},
{"en", "the id must not be empty"},
},
}, {
"the request with id already exists",
[]l10nLocaleTranslation{
{"de", "Die Anforderung mit der ID %s existiert bereits (%s)."},
{"en", "the request with id %s already exists (%s)."},
},
},
}
......
package main
import (
"fmt"
"os"
"golang.org/x/text/language"
......@@ -65,55 +64,6 @@ func initEnvironment() {
*/
func main() {
activeCommand, arguments, config := NewConfiguration()
version = "development"
build = "1.1.1"
//
switch activeCommand.Name {
case "version":
fmt.Println("Version " + version + " (" + build + ")")
case "overview":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := PrintOverview(config, arguments)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
case "meta":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := printMeta(config)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
case "todos":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := printToDoTable(config)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
case "items":
subcommand := activeCommand.Active
switch subcommand.Name {
case "print":
err := printItemTable(config)
if err != nil {
printErrorAndExit(2, err.Error())
}
}
}
executeCommand()
}
......@@ -4,6 +4,10 @@ import (
"html/template"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
)
......@@ -15,6 +19,7 @@ type Dataset struct {
Items string
Requirements string
Created time.Time
CreatedFormat string
}
func PrintOverview(config *Configuration, arguments *commandLineOptions) error {
......@@ -24,17 +29,17 @@ func PrintOverview(config *Configuration, arguments *commandLineOptions) error {
return err
}
err, meta := buildMeta(config, pageData)
err, meta := buildRequirements(config, pageData)
if err != nil {
return err
}
err, tasks := buildToDosTable(config, pageData)
err, tasks := buildTasksTable(config, pageData, false)
if err != nil {
return err
}
err, items := buildItemTable(config, pageData)
err, items := buildItemOverviewTable(config, pageData, false)
if err != nil {
return err
}
......@@ -46,8 +51,16 @@ func PrintOverview(config *Configuration, arguments *commandLineOptions) error {
requirements := ""
for _, p := range pageData {
requirements = requirements + getOverviewContent(p.Absolute)
keys := make([]string, 0, len(pageData))
for k := range pageData {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
p := pageData[k]
requirements = requirements + getAdjustedContent(p.Absolute)
}
d := new(Dataset)
......@@ -57,7 +70,8 @@ func PrintOverview(config *Configuration, arguments *commandLineOptions) error {
d.Items = items
d.Requirements = requirements
d.Created = time.Now()
//d.pageData = pageData
d.CreatedFormat = time.Now().Format(config.Locale.DateFormat)
//d.requirement = requirement
if arguments.Overview.Print.Output == "" {
err = t.Execute(os.Stdout, d)
......@@ -107,7 +121,7 @@ func PrintOverview(config *Configuration, arguments *commandLineOptions) error {
}
func getOverviewContent(absolute string) string {
func getAdjustedContent(absolute string) string {
content, err := os.ReadFile(absolute)
if err != nil {
......@@ -132,5 +146,36 @@ func getOverviewContent(absolute string) string {
s = s[b+4 : len(s)-1]
}
s = convertImages(s, 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
}
package main
import "time"
type pageData struct {
ToDos []toDo
Absolute string
File string
ID string `yaml:"ID"`
Type string `yaml:"Type"` // Display, Functional, Performance, Printing, Report, Testing and Validate
Title string `yaml:"Title"`
Alias []string `yaml:"Alias"`
Keywords []string `yaml:"Keywords"`
Author string `yaml:"Author"`
Status string `yaml:"Status"`
Complexity string `yaml:"Complexity"`
Difficulty string `yaml:"Difficulty"` // Low, Medium, High
Priority string `yaml:"Priority"` // Low, Medium, High
Version string `yaml:"Version"`
Milestone string `yaml:"Milestone"`
Created time.Time `yaml:"Created"`
LastUpdate time.Time `yaml:"Last Update"`
Items []Item `yaml:"items"`
}
......@@ -18,6 +18,7 @@ func convertToPDF(source string, output string) string {
arguments += "--listings "
arguments += "--template /home/volker.schukai/Downloads/eisvogel/eisvogel.latex "
arguments += "--columns=5 "
arguments += "--highlight-style espresso "
arguments += "--toc "
arguments += "--output=" + output
......
......@@ -3,13 +3,79 @@ package main
import (
"bytes"
"fmt"
"html/template"
"os"
"path"
"reflect"
"time"
"github.com/olekukonko/tablewriter"
)
func translateMetaHeaders(columns []string) []string {
type requirement struct {
ToDos []task
Absolute string
File string
Items []Item `yaml:"items"`
ID string `yaml:"ID"`
References []string `yaml:"References"`
Type string `yaml:"Type"` // Display, Functional, Performance, Printing, Report, Testing and Validate
Title string `yaml:"Title"`
Alias []string `yaml:"Alias"`
Keywords []string `yaml:"Keywords"`
Author string `yaml:"Author"`
Status string `yaml:"Status"`
Complexity string `yaml:"Complexity"`
Difficulty string `yaml:"Difficulty"` // Low, Medium, High
Priority string `yaml:"Priority"` // Low, Medium, High
Version string `yaml:"Version"`
Milestone string `yaml:"Milestone"`
Estimation int `yaml:"Estimation"` // 0, 1, 2, 3, 5, 8, 13, 20, 40, 100
Source string `yaml:"Source"`
Created time.Time `yaml:"Created"`
LastUpdate time.Time `yaml:"Last Update"`
}
type addRequirementDataset struct {
ID string
}
func addRequirement(config *Configuration, arguments *commandLineOptions) error {
if arguments.Requirements.Add.ID == "" {
printErrorAndExit(2, "the id must not be empty")
}
p := path.Join(arguments.Path, arguments.Requirements.Add.ID+".md")
if fileExists(p) {
printErrorAndExit(2, "the request with id already exists", arguments.Requirements.Add.ID, p)
}
t, err := template.New("requirement").Parse(config.Requirement.Template)
if err != nil {
return err
}
d := new(addRequirementDataset)
d.ID = arguments.Requirements.Add.ID
f, err := os.Create(p)
if err != nil {
return err
}
defer f.Close()
err = t.Execute(f, d)
if err != nil {
return err
}
return nil
}
func translateRequirementHeaders(columns []string) []string {
result := []string{}
......@@ -21,13 +87,13 @@ func translateMetaHeaders(columns []string) []string {
}
func buildMeta(config *Configuration, pageDataList []pageData) (error, string) {
func buildRequirements(config *Configuration, pageMap map[string]requirement) (error, string) {
buf := new(bytes.Buffer)
table := tablewriter.NewWriter(buf)
translateMetaColumns := translateMetaHeaders(config.Table.Columns)
translateMetaColumns := translateRequirementHeaders(config.Table.Columns)
table.SetHeader(translateMetaColumns)
table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
......@@ -35,7 +101,7 @@ func buildMeta(config *Configuration, pageDataList []pageData) (error, string) {
var tableData [][]string
for _, pd := range pageDataList {
for _, pd := range pageMap {
r := reflect.ValueOf(pd)
......@@ -100,13 +166,13 @@ func buildMeta(config *Configuration, pageDataList []pageData) (error, string) {
}
func printMeta(config *Configuration) error {
func printRequirements(config *Configuration) error {
err, pageData := GetPageData(config.Path)
if err != nil {
return err
}
err, table := buildMeta(config, pageData)
err, table := buildRequirements(config, pageData)
fmt.Println(table)
return err
}
......@@ -9,14 +9,15 @@ import (
"github.com/olekukonko/tablewriter"
)
type toDo struct {
type task struct {
due time.Time
text string
checked bool
}
const dateLayout = "2006-01-02 15:04:05 GMT"
func newToDo(date string, text string) toDo {
func newTask(date string, text string, checked bool) task {
var d time.Time
var err error
......@@ -28,24 +29,25 @@ func newToDo(date string, text string) toDo {
}
}
t := toDo{
t := task{
due: d,
text: text,
checked: checked,
}
return t
}
func findToDos(content []byte) []toDo {
func findTask(content []byte) []task {
toDos := []toDo{}
toDos := []task{}
todoRegEx := regexp.MustCompile(`@todo\s*(?P<due>[2][0-9]{3}-[0-9]{2}-[0-9]{2}\s*){0,1}(?P<text>[^\n]*)`)
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 []toDo{}
return []task{}
}
for _, match := range matches {
......@@ -56,7 +58,13 @@ func findToDos(content []byte) []toDo {
}
}
t := newToDo(result["due"], result["text"])
checked := true
if result["checked"] != "x" {
checked = false
}
t := newTask(result["due"], result["text"], checked)
toDos = append(toDos, t)
}
......@@ -64,22 +72,28 @@ func findToDos(content []byte) []toDo {
return toDos
}
func buildToDosTable(config *Configuration, pageDataList []pageData) (error, string) {
func buildTasksTable(config *Configuration, pageMap map[string]requirement, extended bool) (error, string) {
buf := new(bytes.Buffer)
table := tablewriter.NewWriter(buf)
table.SetHeader([]string{
header := []string{
printer.Sprintf("ToDo"),
printer.Sprintf("Due"),
printer.Sprintf("File")})
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 _, pageData := range pageDataList {
for _, pageData := range pageMap {
for _, info := range pageData.ToDos {
var d string
......@@ -90,7 +104,18 @@ func buildToDosTable(config *Configuration, pageDataList []pageData) (error, str
d = info.due.Format(config.Locale.DateFormat)
}
tableData = append(tableData, []string{info.text, d, pageData.File})
checked := "—"
if info.checked == true {
checked = "✓"
}
cols := []string{info.text, d, checked}
if extended == true {
cols = append(cols, pageData.File)
}
tableData = append(tableData, cols)
}
}
......@@ -102,13 +127,13 @@ func buildToDosTable(config *Configuration, pageDataList []pageData) (error, str
return nil, buf.String()
}
func printToDoTable(config *Configuration) error {
func printTaskTable(config *Configuration) error {
err, pageData := GetPageData(config.Path)
if err != nil {
return err
}
err, table := buildToDosTable(config, pageData)
err, table := buildTasksTable(config, pageData, true)
fmt.Println(table)
return nil
......
development/examples/assets/schukai-weiss-1000-210.png

10.3 KiB

---
ID: 144444
title:
subtitle:
tags: []
percent:
Estimation:
items:
-
Group:
ID:
Name:
Description:
Delivery until:
Provided by:
Provided on:
Type:
...
##
###
- [ ] task 1
- [ ] task 2
development/examples/example1/assets/demo.png

65.8 KiB

---
Author: "Me"
title: "The Document Title"
author: [Example Author, Another Author]
date: "2017-02-20"
keywords: [Markdown, Example]
lang: de
titlepage: true
titlepage-color: "CE0000"
titlepage-text-color: "FFFFFF"
titlepage-rule-color: "FFFFFF"
titlepage-rule-height: 2
logo: "/home/volker.schukai/projekte/local/marketing/logos/varianten/schukai-weiss-1000-210.png"
logo-width: "6cm"
toc-own-page: true
table-use-row-colors: true
subtitle: document subtitle, included in HTML, EPUB, LaTeX, ConTeXt, and docx documents
abstract: document summary, included in LaTeX, ConTeXt, AsciiDoc, and docx documents
subject: document subject, included in ODT, PDF, docx, EPUB, and pptx metadata
...
## Overview
Created: {{ .Created.Format "02.Jan.2006" }}
{{.Meta}}
## Tasks
{{.Tasks}}
## Items
{{.Items}}
## Requirements
***
BBBBBB
{{.Requirements}}
AAAAAA
***
---
Title: Value1
Created: 2022-02-21
Version: 1.0
ID: 9999
...
## Anforderung 1425
das ist ein test
Here is a footnote reference,[^1] and another.[^longnote]
[^1]: Here is the footnote.
[^longnote]: Here's one with multiple blocks.
This paragraph won't be part of the note, because it
isn't indented.
- [ ] das ist das erste todo 1
- [x] 2020-12-02 das ist das erste todo 2
- [ ] 2020-12-03 das ist das erste todo 3
- [x ] 2020-12-03 das ist das erste todo 3
### Headline 1
HIER IST EIN BILD
![DAS IST EIN BILD](../assets/demo.png)
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
### Headline 2
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment