Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cmd): add command line interface #78

Merged
merged 4 commits into from
Apr 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ tmp
# exclude code coverage merged results
coverage.txt
*.html
.DS_Store
20 changes: 19 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@
[prune]
go-tests = true
unused-packages = true

[[constraint]]
name = "github.com/spf13/cobra"
version = "0.0.2"
21 changes: 17 additions & 4 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ It is is available under the terms of the https://raw.githubusercontent.com/byte
* Inline images in paragraphs (`image://`)
* Block images (`image:://`)
* Element attributes (`ID`, `link` and `title`, where applicable) on block images, paragraphs, lists and sections
* Labeled, ordered and unordered lists (with nesting and attributes)


See the http://LIMITATIONS.adoc[known limitations] page for differences between Asciidoc/Asciidoctor and Libasciidoc.
Expand All @@ -33,18 +34,30 @@ Further elements will be supported in the future. Feel free to open issues https

== Usage

=== Command Line

The libasciidoc library includes a minimalist command line interface to generate the HTML content from a given file:

```
$ libasciidoc -s content.adoc
```

=== Code integration

Libasciidoc provides 2 functions to convert an Asciidoc content into HTML:

1. Converting to a complete HTML document:
1. Converting an `io.Reader` into an HTML document:

func ConvertToHTML(context.Context, io.Reader, io.Writer, renderer.Option...) (map[string]interface{}, error)
func ConvertToHTML(ctx context.Context, source io.Reader, output io.Writer, options renderer.Option...) (map[string]interface{}, error)

2. Converting to a `body` element only:
2. Converting a file (giving its name) into an HTML document:

func ConvertToHTMLBody(context.Context, io.Reader, io.Writer) (map[string]interface{}, error)
func ConvertFileToHTML(ctx context.Context, filename string, output io.Writer, options renderer.Option...) (map[string]interface{}, error)

where the returned `map[string]interface{}` object contains the document's title (which is not rendered in the HTML's body) and its other attributes.

The currently available option to pass as a last argument is `renderer.IncludeHeaderFooter(false)` to limit the generation to the body of the HTML document.

== How to contribute

Please refer to the http://CONTRIBUTE.adoc[Contribute] page.
13 changes: 13 additions & 0 deletions cmd/libasciidoc/cmd_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestCmd(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Cmd Suite")
}
43 changes: 43 additions & 0 deletions cmd/libasciidoc/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"fmt"
"os"
"strings"

"github.com/pkg/errors"
"github.com/spf13/cobra"
)

func main() {
rootCmd := NewRootCmd()
rootCmd.AddCommand(versionCmd)
rootCmd.SetHelpCommand(helpCommand)
// rootCmd.SetHelpTemplate(helpTemplate)
// rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage")
// rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help")
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

var helpTemplate = `
{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`

var helpCommand = &cobra.Command{
Use: "help [command]",
Short: "Help about the command",
PersistentPreRun: func(cmd *cobra.Command, args []string) {},
PersistentPostRun: func(cmd *cobra.Command, args []string) {},
RunE: func(c *cobra.Command, args []string) error {
cmd, args, e := c.Root().Find(args)
if cmd == nil || e != nil || len(args) > 0 {
return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
}

helpFunc := cmd.HelpFunc()
helpFunc(cmd, args)
return nil
},
}
33 changes: 33 additions & 0 deletions cmd/libasciidoc/root_cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

import (
"context"
"fmt"

"github.com/bytesparadise/libasciidoc"
"github.com/bytesparadise/libasciidoc/renderer"
"github.com/spf13/cobra"
)

// NewRootCmd returns the root command
func NewRootCmd() *cobra.Command {
var source string
rootCmd := &cobra.Command{
Use: "libasciidoc",
Short: "libasciidoc is a tool to generate an html output from an asciidoc file",
RunE: func(cmd *cobra.Command, args []string) error {
if cmd.Flag("source").Value.String() == "" {
return fmt.Errorf("flag 'source' is required")
}
source := cmd.Flag("source").Value.String()
_, err := libasciidoc.ConvertFileToHTML(context.Background(), source, cmd.OutOrStdout(), renderer.IncludeHeaderFooter(true)) //renderer.IncludeHeaderFooter(true)
if err != nil {
return err
}
return nil
},
}
flags := rootCmd.Flags()
flags.StringVarP(&source, "source", "s", "", "the path to the asciidoc source to process")
return rootCmd
}
44 changes: 44 additions & 0 deletions cmd/libasciidoc/root_cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main_test

import (
"bytes"
"testing"

main "github.com/bytesparadise/libasciidoc/cmd/libasciidoc"
"github.com/stretchr/testify/require"
)

import . "github.com/onsi/ginkgo"

var _ = Describe("root cmd", func() {

It("ok", func() {
// given
root := main.NewRootCmd()
buf := new(bytes.Buffer)
root.SetOutput(buf)
root.SetArgs([]string{"-s", "test/test.adoc"})
// when
err := root.Execute()
// then
require.NoError(GinkgoT(), err)
require.NotEmpty(GinkgoT(), buf)
})

It("missing source flag", func() {
// given
root := main.NewRootCmd()
buf := new(bytes.Buffer)
root.SetOutput(buf)
// when
err := root.Execute()
// then
GinkgoT().Logf("command output: %v", buf.String())
require.Error(GinkgoT(), err)
})

})

func TestRootCommand(t *testing.T) {

}
1 change: 1 addition & 0 deletions cmd/libasciidoc/test/test.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
some *asciidoc* content
15 changes: 15 additions & 0 deletions cmd/libasciidoc/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import (
"fmt"

"github.com/spf13/cobra"
)

var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of libasciidoc",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("~HEAD")
},
}
28 changes: 12 additions & 16 deletions libasciidoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,29 @@ import (
log "github.com/sirupsen/logrus"
)

// ConvertToHTMLBody converts the content of the given reader `r` into an set of <DIV> elements for an HTML/BODY document.
// The conversion result is written in the given writer `w`, whereas the document metadata (title, etc.) (or an error if a problem occurred) is returned
// ConvertFileToHTML converts the content of the given filename into an HTML 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.
func ConvertToHTMLBody(ctx context.Context, r io.Reader, w io.Writer) (map[string]interface{}, error) {
doc, err := parser.ParseReader("", r)
func ConvertFileToHTML(ctx context.Context, filename string, output io.Writer, options ...renderer.Option) (map[string]interface{}, error) {
doc, err := parser.ParseFile(filename)
if err != nil {
return nil, errors.Wrapf(err, "error while parsing the document")
}
options := []renderer.Option{renderer.IncludeHeaderFooter(false)}
metadata, err := htmlrenderer.Render(renderer.Wrap(ctx, doc.(types.Document), options...), w)
if err != nil {
return nil, errors.Wrapf(err, "error while rendering the document")
}
log.Debugf("Done processing document")
return metadata, nil
return convertToHTML(ctx, doc, output, options...)
}

// ConvertToHTML converts the content of the given reader `r` into a full HTML document, written in the given writer `w`.
// ConvertToHTML converts the content of the given reader `r` into a full HTML document, written in the given writer `output`.
// Returns an error if a problem occurred
func ConvertToHTML(ctx context.Context, r io.Reader, w io.Writer, options ...renderer.Option) (map[string]interface{}, error) {
func ConvertToHTML(ctx context.Context, r io.Reader, output io.Writer, options ...renderer.Option) (map[string]interface{}, error) {
doc, err := parser.ParseReader("", r)
if err != nil {
return nil, errors.Wrapf(err, "error while parsing the document")
}
// force/override value
options = append(options, renderer.IncludeHeaderFooter(true))
metadata, err := htmlrenderer.Render(renderer.Wrap(ctx, doc.(types.Document), options...), w)
return convertToHTML(ctx, doc, output, options...)
}

func convertToHTML(ctx context.Context, doc interface{}, output io.Writer, options ...renderer.Option) (map[string]interface{}, error) {
metadata, err := htmlrenderer.Render(renderer.Wrap(ctx, doc.(types.Document), options...), output)
if err != nil {
return nil, errors.Wrapf(err, "error while rendering the document")
}
Expand Down
4 changes: 2 additions & 2 deletions libasciidoc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func verifyDocumentBody(t GinkgoTInterface, expectedRenderedTitle *string, expec
t.Logf("processing '%s'", source)
sourceReader := strings.NewReader(source)
resultWriter := bytes.NewBuffer(nil)
metadata, err := ConvertToHTMLBody(context.Background(), sourceReader, resultWriter)
metadata, err := ConvertToHTML(context.Background(), sourceReader, resultWriter, renderer.IncludeHeaderFooter(false))
require.Nil(t, err, "Error found while parsing the document")
require.NotNil(t, metadata)
t.Log("Done processing document")
Expand All @@ -202,7 +202,7 @@ func verifyCompleteDocument(t GinkgoTInterface, expectedContent, source string)
sourceReader := strings.NewReader(source)
resultWriter := bytes.NewBuffer(nil)
lastUpdated := time.Now()
_, err := ConvertToHTML(context.Background(), sourceReader, resultWriter, renderer.LastUpdated(lastUpdated))
_, err := ConvertToHTML(context.Background(), sourceReader, resultWriter, renderer.IncludeHeaderFooter(true), renderer.LastUpdated(lastUpdated))
require.Nil(t, err, "Error found while parsing the document")
t.Log("Done processing document")
result := resultWriter.String()
Expand Down
3 changes: 0 additions & 3 deletions renderer/html5/renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ func verify(t GinkgoTInterface, expectedResult, content string, rendererOpts ...
buff := bytes.NewBuffer(nil)
actualDocument := doc.(types.Document)
rendererCtx := renderer.Wrap(context.Background(), actualDocument, rendererOpts...)
// if entrypoint := rendererCtx.Entrypoint(); entrypoint != nil {

// }
_, err = html5.Render(rendererCtx, buff)
require.NoError(t, err)
if strings.Contains(expectedResult, "{{.LastUpdated}}") {
Expand Down