forked from bytesparadise/libasciidoc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libasciidoc.go
101 lines (93 loc) · 3.73 KB
/
libasciidoc.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
// Package libasciidoc is an open source Go library that converts Asciidoc
// content into HTML.
package libasciidoc
import (
"io"
"os"
"strings"
"time"
"github.com/bytesparadise/libasciidoc/pkg/configuration"
"github.com/bytesparadise/libasciidoc/pkg/parser"
"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"
"github.com/bytesparadise/libasciidoc/pkg/validator"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
var (
// BuildCommit lastest build commit (set by Makefile)
BuildCommit = ""
// BuildTag if the `BuildCommit` matches a tag
BuildTag = ""
// BuildTime set by build script (set by Makefile)
BuildTime = ""
)
// ConvertFile converts the content of the given filename into an output document.
// The conversion result is written in the given writer `output`, whereas the document metadata (title, etc.) (or an error if a problem occurred) is returned
// as the result of the function call. The output format is determined by config.Backend (HTML5 default).
func ConvertFile(output io.Writer, config *configuration.Configuration) (types.Metadata, error) {
file, err := os.Open(config.Filename)
if err != nil {
return types.Metadata{}, errors.Wrapf(err, "error opening %s", config.Filename)
}
defer file.Close()
// use the file mtime as the `last updated` value
stat, err := os.Stat(config.Filename)
if err != nil {
return types.Metadata{}, errors.Wrapf(err, "error opening %s", config.Filename)
}
config.LastUpdated = stat.ModTime()
return Convert(file, output, config)
}
// Convert converts the content of the given reader `r` into a full output document, written in the given writer `output`.
// Returns an error if a problem occurred. The default will be HTML5, but depends on the config.BackEnd value.
func Convert(source io.Reader, output io.Writer, config *configuration.Configuration) (types.Metadata, error) {
var start, endOfPreprocess, emdOfParse, endOfValidate, endOfRender time.Time
start = time.Now()
defer func() {
log.Infof("time to preprocess %d microseconds", endOfPreprocess.Sub(start).Microseconds())
log.Infof("time to parse %d microseconds", emdOfParse.Sub(endOfPreprocess).Microseconds())
log.Infof("time to validate %d microseconds", endOfValidate.Sub(emdOfParse).Microseconds())
log.Infof("time to render %d microseconds", endOfRender.Sub(endOfValidate).Microseconds())
log.Infof("total time %d microseconds", endOfRender.Sub(start).Microseconds())
}()
p, err := parser.Preprocess(source, config)
if err != nil {
return types.Metadata{}, err
}
endOfPreprocess = time.Now()
// log.Debugf("parsing the asciidoc source...")
doc, err := parser.ParseDocument(strings.NewReader(p), config)
if err != nil {
return types.Metadata{}, err
}
emdOfParse = time.Now()
// validate the document
doctype := config.Attributes.GetAsStringWithDefault(types.AttrDocType, "article")
problems, err := validator.Validate(doc, doctype)
if err != nil {
return types.Metadata{}, err
}
endOfValidate = time.Now()
if len(problems) > 0 {
// if any problem found, change the doctype to render the document as a regular article
log.Warnf("changing doctype to 'article' because problems were found in the document: %v", problems)
config.Attributes[types.AttrDocType] = "article" // switch to `article` rendering (in case it was a manpage with problems)
for _, problem := range problems {
switch problem.Severity {
case validator.Error:
log.Error(problem.Message)
case validator.Warning:
log.Warn(problem.Message)
}
}
}
// render
metadata, err := renderer.Render(doc, config, output)
if err != nil {
return types.Metadata{}, err
}
endOfRender = time.Now()
// log.Debugf("Done processing document")
return metadata, nil
}