-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
179 lines (143 loc) · 3.63 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright 2014 The presenti Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/* #nb:
A inline presentation system for Go
The presenti Authors
https://www.github.com/dupoxy/presenti/
*/
package main
import (
"flag"
"fmt"
"go/format"
"log"
"os"
)
/* #nb: * Install
To Install:
$ go get -u github.com/dupoxy/presenti
build status:
.image https://drone.io/github.com/dupoxy/presenti/status.png
* Readme
.code README
* Be nice
It try to be nice to godoc and other Go tools too.
To do so, it uses a notebook marker:
.code main.go /^const/,/\n/
And also by only using top level comments and checking that they have an empty \n after the end.
* why
To keep talks in sync with the code.
* Constrains
- keep it as simple as possible.
- A .go file equal an .article/Slide file to group code by subject.
- do not replace doc.go, godoc and flag.Usage().
- use multiple line comments so they can be minimized if your code editor does that.
*/
const noteBookMarker = "/* #nb:"
func usage() {
txt := `Presenti is an inline present system for Go.
It aim to produce article or slide file by extracting multiples lines
top level comments, from start to end of Go source file.
Usage of %s:
%s [<flags>] input.go
output default to stdout.
Flags:
`
fmt.Fprintf(os.Stderr, txt, os.Args[0], os.Args[0])
flag.PrintDefaults()
end := `
To Displays slide presentations and articles,
use the present command from the go.talks subrepository.
It runs a web server that presents slide and article files
from the current directory.
To Install it:
$ go get -u code.google.com/p/go.talks/present
for more on presenti:
$ cd $GOPATH/src/github.com/dupoxy/presenti
$ present
`
fmt.Fprintln(os.Stderr, end)
}
var (
article = flag.Bool("a", false, "save output to an article file")
slide = flag.Bool("s", false, "save output to a slide file")
)
func main() {
flag.Usage = usage
flag.Parse()
args := flag.Args()
if len(args) == 0 {
flag.Usage()
os.Exit(1)
}
err := do(args[0])
if err != nil {
log.Fatal(err)
}
}
func do(input string) error {
// read args
name, data := readInput(input)
// check if it is a valid source file
data, err := format.Source(data)
if err != nil {
return fmt.Errorf("format.Source: %v", err)
}
// make notebook
noteBook, err := makeNoteBook(name, data)
if err != nil {
return fmt.Errorf("makeNotebook: %v", err)
}
file := false
suf := ""
if *article {
file = true
suf = ".article"
}
if *slide {
file = true
suf = ".slide"
}
switch {
case file: // write output to file
f, err := createAndOpen(input, suf, noteBook)
defer f.Close()
if err != nil {
return fmt.Errorf("createAndOpen: %v", err)
}
// Parse present file to check errors
err = check(f, f.Name())
if err != nil {
del := os.Remove(f.Name())
if del != nil {
return fmt.Errorf("os.Remove: %v", del)
}
return fmt.Errorf("the generated present file as an error : %v", err)
}
default: // write output to stdout
for _, v := range noteBook.All() {
fmt.Fprintf(os.Stdout, v.Text)
}
suf = ".tmp"
f, err := createAndOpen(input, suf, noteBook)
defer f.Close()
if err != nil {
return fmt.Errorf("createAndOpen: %v", err)
}
// Parse present file to check errors
err = check(f, f.Name())
if err != nil {
ren := os.Rename(f.Name(), f.Name()+".err")
if ren != nil {
return fmt.Errorf("os.Rename: %v", ren)
}
return fmt.Errorf("the generated present output as an error: %v\nPlease open %v.err", err, f.Name())
}
err = os.Remove(f.Name())
if err != nil {
return fmt.Errorf("os.Remove: %v", err)
}
}
return nil
}