Skip to content

Commit ce5d450

Browse files
committed
Init
0 parents  commit ce5d450

File tree

11 files changed

+444
-0
lines changed

11 files changed

+444
-0
lines changed

.gitignore

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Created by https://www.toptal.com/developers/gitignore/api/go
2+
# Edit at https://www.toptal.com/developers/gitignore?templates=go
3+
4+
### Go ###
5+
# If you prefer the allow list template instead of the deny list, see community template:
6+
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
7+
#
8+
# Binaries for programs and plugins
9+
*.exe
10+
*.exe~
11+
*.dll
12+
*.so
13+
*.dylib
14+
15+
# Test binary, built with `go test -c`
16+
*.test
17+
18+
# Output of the go coverage tool, specifically when used with LiteIDE
19+
*.out
20+
21+
# Dependency directories (remove the comment below to include it)
22+
# vendor/
23+
24+
# Go workspace file
25+
go.work
26+
27+
### Go Patch ###
28+
/vendor/
29+
/Godeps/
30+
31+
/bin/
32+
*.pdf

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
PROJECT_DIR = $(shell pwd)
2+
PROJECT_BIN = $(PROJECT_DIR)/bin
3+
4+
TOOLKIT = $(PROJECT_BIN)/toolkit
5+
6+
.PHONY: toolkit
7+
toolkit:
8+
go build -o $(TOOLKIT) .

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Defer Panic CLI
2+
3+
Toolkit for managing Defer Panic articles and other stuff.

cmd/article.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package cmd
2+
3+
import "github.com/spf13/cobra"
4+
5+
var articleCmd = &cobra.Command{
6+
Use: "article",
7+
Short: "Manage articles",
8+
}
9+
10+
func init() {
11+
articleCmd.AddCommand(articleGenerateCmd)
12+
articleCmd.AddCommand(articleExportCmd)
13+
}

cmd/article_export.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os/exec"
6+
"path/filepath"
7+
"strings"
8+
9+
"github.com/spf13/cobra"
10+
)
11+
12+
var (
13+
articleExportCmd = &cobra.Command{
14+
Use: "export",
15+
Short: "Export article to PDF (pandoc and xelatex are required)",
16+
Args: cobra.MinimumNArgs(1),
17+
RunE: executeArticleExport,
18+
}
19+
generateTOC bool
20+
pdfEngine string
21+
)
22+
23+
func init() {
24+
articleExportCmd.Flags().BoolVar(&generateTOC, "toc", false, "Generate table of contents")
25+
articleExportCmd.Flags().StringVar(&pdfEngine, "pdf-engine", "xelatex", "PDF engine to use")
26+
}
27+
28+
func executeArticleExport(_ *cobra.Command, args []string) error {
29+
var (
30+
outputFilename = getExportFilename(args)
31+
cmdArgs = []string{
32+
"-o", outputFilename,
33+
args[0],
34+
fmt.Sprintf("--pdf-engine=%s", pdfEngine),
35+
}
36+
)
37+
38+
if generateTOC {
39+
cmdArgs = append(cmdArgs, "--toc")
40+
}
41+
42+
fmt.Println(args[0], outputFilename, cmdArgs)
43+
44+
out, err := exec.Command("pandoc", cmdArgs...).CombinedOutput()
45+
if err != nil {
46+
return err
47+
}
48+
49+
fmt.Println(string(out))
50+
51+
return nil
52+
}
53+
54+
func getExportFilename(args []string) string {
55+
var outputFilename string
56+
57+
if len(args) > 1 {
58+
outputFilename = args[1]
59+
} else {
60+
outputFilename = strings.TrimRight(args[0], filepath.Ext(args[0])) + ".pdf"
61+
}
62+
63+
return outputFilename
64+
}

cmd/article_generate.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package cmd
2+
3+
import (
4+
_ "embed"
5+
"html/template"
6+
"os"
7+
"strconv"
8+
9+
"github.com/erikgeiser/promptkit/selection"
10+
"github.com/erikgeiser/promptkit/textinput"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
var articleGenerateCmd = &cobra.Command{
15+
Use: "generate",
16+
Short: "Generate article",
17+
Args: cobra.ExactArgs(1),
18+
RunE: executeArticleGenerate,
19+
}
20+
21+
func executeArticleGenerate(_ *cobra.Command, args []string) error {
22+
data, err := readDataFromInput()
23+
if err != nil {
24+
return err
25+
}
26+
27+
if err := generate(data, args[0]); err != nil {
28+
return err
29+
}
30+
31+
return nil
32+
}
33+
34+
func readDataFromInput() (*Data, error) {
35+
titleInput := textinput.New("Choose the best article title:")
36+
titleInput.Placeholder = "Think hard!"
37+
38+
title, err := titleInput.RunPrompt()
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
subtitleInput := textinput.New("And well supporting subtitle:")
44+
subtitleInput.Placeholder = "Think harder!"
45+
46+
subtitle, err := subtitleInput.RunPrompt()
47+
if err != nil {
48+
return nil, err
49+
}
50+
51+
authorInput := textinput.New("Who is the author of this masterpiece?")
52+
authorInput.Placeholder = "Look at yourself in the mirror"
53+
authorInput.InitialValue = "Ильдар Карымов <[email protected]>, Алексей Ким <[email protected]>"
54+
55+
author, err := authorInput.RunPrompt()
56+
if err != nil {
57+
return nil, err
58+
}
59+
60+
languageSelection := selection.New(
61+
"What language is this article written in?",
62+
[]*selection.Choice{
63+
selection.NewChoice("ru"),
64+
selection.NewChoice("en"),
65+
},
66+
)
67+
languageSelection.Filter = nil
68+
69+
language, err := languageSelection.RunPrompt()
70+
if err != nil {
71+
return nil, err
72+
}
73+
74+
documentClassSelection := selection.New(
75+
"What document class should be used?",
76+
[]*selection.Choice{
77+
selection.NewChoice("report"),
78+
selection.NewChoice("article"),
79+
selection.NewChoice("book"),
80+
},
81+
)
82+
documentClassSelection.Filter = nil
83+
84+
documentClass, err := documentClassSelection.RunPrompt()
85+
if err != nil {
86+
return nil, err
87+
}
88+
89+
paperSizeSelection := selection.New(
90+
"What paper size should be used?",
91+
[]*selection.Choice{
92+
selection.NewChoice("a4"),
93+
selection.NewChoice("letter"),
94+
},
95+
)
96+
paperSizeSelection.Filter = nil
97+
98+
paperSize, err := paperSizeSelection.RunPrompt()
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
lineStretchInput := textinput.New("What line stretch should be used?")
104+
lineStretchInput.InitialValue = "1.5"
105+
106+
lineStretchStr, err := lineStretchInput.RunPrompt()
107+
if err != nil {
108+
return nil, err
109+
}
110+
111+
lineStretch, err := strconv.ParseFloat(lineStretchStr, 64)
112+
if err != nil {
113+
return nil, err
114+
}
115+
116+
mainFontInput := textinput.New("What main font should be used?")
117+
mainFontInput.InitialValue = "Times New Roman"
118+
119+
mainFont, err := mainFontInput.RunPrompt()
120+
if err != nil {
121+
return nil, err
122+
}
123+
124+
monoFontInput := textinput.New("What monospace font should be used?")
125+
monoFontInput.InitialValue = "Fira Code"
126+
127+
monoFont, err := monoFontInput.RunPrompt()
128+
if err != nil {
129+
return nil, err
130+
}
131+
132+
return &Data{
133+
Title: title,
134+
Subtitle: subtitle,
135+
Author: author,
136+
Language: language.String,
137+
DocumentClass: documentClass.String,
138+
PaperSize: paperSize.String,
139+
LineStretch: lineStretch,
140+
MainFont: mainFont,
141+
MonoFont: monoFont,
142+
}, nil
143+
}
144+
145+
//go:embed resources/article.tpl.md
146+
var tpl string
147+
148+
func generate(data *Data, outputFileName string) error {
149+
tpl, err := template.New("article").Parse(tpl)
150+
if err != nil {
151+
return err
152+
}
153+
154+
outFile, err := os.Create(outputFileName)
155+
if err != nil {
156+
return err
157+
}
158+
defer outFile.Close()
159+
160+
return tpl.Execute(outFile, data)
161+
}
162+
163+
type Data struct {
164+
Title string
165+
Subtitle string
166+
Author string
167+
Language string
168+
DocumentClass string
169+
PaperSize string
170+
LineStretch float64
171+
MainFont string
172+
MonoFont string
173+
}

cmd/resources/article.tpl.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
title: {{.Title}}
3+
subtitle: {{.Subtitle}}
4+
author: {{.Author}}
5+
lang: {{.Language}}
6+
documentclass: {{.DocumentClass}}
7+
papersize: {{.PaperSize}}
8+
linestretch: {{.LineStretch}}
9+
mainfont: {{.MainFont}}
10+
monofont: {{.MonoFont}}
11+
header-includes:
12+
- \usepackage{geometry}
13+
- \geometry{margin=1in}
14+
- \usepackage{hyperref}
15+
---
16+
17+
Start right here!

cmd/root.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package cmd
2+
3+
import "github.com/spf13/cobra"
4+
5+
var rootCmd = &cobra.Command{
6+
Use: "dp-cli",
7+
Short: "Toolkit for managing Defer Panic articles and other stuff",
8+
}
9+
10+
func init() {
11+
rootCmd.AddCommand(articleCmd)
12+
}
13+
14+
func Execute() error {
15+
return rootCmd.Execute()
16+
}

go.mod

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module github.com/defer-panic/dp-cli
2+
3+
go 1.19
4+
5+
require (
6+
github.com/charmbracelet/bubbles v0.14.0
7+
github.com/charmbracelet/bubbletea v0.22.1
8+
)
9+
10+
require (
11+
github.com/atotto/clipboard v0.1.4 // indirect
12+
github.com/charmbracelet/lipgloss v0.5.0 // indirect
13+
github.com/containerd/console v1.0.3 // indirect
14+
github.com/erikgeiser/promptkit v0.7.0 // indirect
15+
github.com/inconshreveable/mousetrap v1.0.1 // indirect
16+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
17+
github.com/mattn/go-isatty v0.0.16 // indirect
18+
github.com/mattn/go-localereader v0.0.1 // indirect
19+
github.com/mattn/go-runewidth v0.0.13 // indirect
20+
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
21+
github.com/muesli/cancelreader v0.2.2 // indirect
22+
github.com/muesli/reflow v0.3.0 // indirect
23+
github.com/muesli/termenv v0.12.0 // indirect
24+
github.com/rivo/uniseg v0.2.0 // indirect
25+
github.com/spf13/cobra v1.5.0 // indirect
26+
github.com/spf13/pflag v1.0.5 // indirect
27+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
28+
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
29+
golang.org/x/text v0.3.7 // indirect
30+
)

0 commit comments

Comments
 (0)