From b1dd2bce666fe8217c35b9fab443035f25bfad26 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Tue, 6 Aug 2019 00:13:54 +0700 Subject: cmd/ciigo: a CLI to convert, generate, and serve markup files Here are the usage of CLI, ciigo [-template ] convert Scan the "dir" recursively to find markup files (.adoc or .md) and convert them into HTML files. The template "file" is optional, default to "templates/html.tmpl" in the current directory. ciigo [-template ] [-out ] generate Convert all markup files inside directory "dir" recursively and then embed them into ".go" source file. The output file is optional, default to "ciigo_static.go" in current directory. ciigo [-template ] [-address ] serve Serve all files inside directory "dir" using HTTP server, watch changes on markup files and convert them to HTML files automatically. If the address is not set, its default to ":8080". --- Makefile | 1 + ciigo.go | 9 ++-- cmd/ciigo-example/main.go | 2 +- cmd/ciigo/main.go | 118 ++++++++++++++++++++++++++++++++++++++++++++++ content/index.adoc | 56 ++++++++++++++++++---- generate.go | 20 +++++++- generate_main.go | 2 +- htmlgenerator.go | 8 +++- server.go | 12 +++-- 9 files changed, 204 insertions(+), 24 deletions(-) create mode 100644 cmd/ciigo/main.go diff --git a/Makefile b/Makefile index 8344d18..b45ebaf 100644 --- a/Makefile +++ b/Makefile @@ -6,4 +6,5 @@ generate: go generate build: + go install ./cmd/ciigo-example go install ./cmd/ciigo diff --git a/ciigo.go b/ciigo.go index 01763e3..1491b07 100644 --- a/ciigo.go +++ b/ciigo.go @@ -12,10 +12,11 @@ package ciigo const ( - dirAssets = "assets" - dirRoot = "./content" - extAsciidoc = ".adoc" - extMarkdown = ".md" + dirAssets = "assets" + dirRoot = "./content" + extAsciidoc = ".adoc" + extMarkdown = ".md" + defHTMLTemplate = "./templates/html.tmpl" ) const ( diff --git a/cmd/ciigo-example/main.go b/cmd/ciigo-example/main.go index 2b98c13..a636b0e 100644 --- a/cmd/ciigo-example/main.go +++ b/cmd/ciigo-example/main.go @@ -13,7 +13,7 @@ import ( ) func main() { - srv := ciigo.NewServer("./content", ":8080") + srv := ciigo.NewServer("./content", ":8080", "./templates/html.tmpl") srv.Start() } diff --git a/cmd/ciigo/main.go b/cmd/ciigo/main.go new file mode 100644 index 0000000..9427be2 --- /dev/null +++ b/cmd/ciigo/main.go @@ -0,0 +1,118 @@ +// Copyright 2019, Shulhan . All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// +// ciigo is a CLI to convert, generate, and/or serve a directory that contains +// markup files, as HTML files. +// +// Usage +// +// The following section describe how to use ciigo CLI. +// +// ciigo [-template ] convert +// +// Scan the "dir" recursively to find markup files (.adoc or .md) and convert +// them into HTML files. +// The template "file" is optional, default to "templates/html.tmpl" in the +// current directory. +// +// ciigo [-template ] [-out ] generate +// +// Convert all the markup files inside directory "dir" recursively and then +// embed them into ".go" source file. +// The output file is optional, default to "ciigo_static.go" in current +// directory. +// +// ciigo [-template ] [-address ] serve +// +// Serve all files inside directory "dir" using HTTP server, watch changes on +// markup files and convert them to HTML files. +// If the address is not set, its default to ":8080". +// +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/shuLhan/ciigo" + "github.com/shuLhan/share/lib/debug" +) + +func main() { + isHelp := flag.Bool("h", false, "print help") + isHelp = flag.Bool("help", false, "print help") + htmlTemplate := flag.String("template", "templates/html.tmpl", + "path to HTML template") + outputFile := flag.String("out", "ciigo_static.go", + "path to output of .go generated file") + address := flag.String("address", ":8080", + "the binding address for HTTP server") + + flag.Parse() + + if *isHelp { + usage() + os.Exit(0) + } + + command := flag.Arg(0) + if len(command) == 0 { + usage() + os.Exit(1) + } + + dir := flag.Arg(1) + if len(dir) == 0 { + dir = "." + } + + command = strings.ToLower(command) + switch command { + case "convert": + ciigo.Convert(dir, *htmlTemplate) + case "generate": + ciigo.Generate(dir, *outputFile, *htmlTemplate) + case "serve": + debug.Value = 2 + srv := ciigo.NewServer(dir, *address, *htmlTemplate) + srv.Start() + default: + usage() + os.Exit(1) + } +} + +func usage() { + fmt.Println(` += ciigo + +A CLI to convert, generate, and/or serve a directory that contains markup +files, as HTML files. + +== Usage + +ciigo [-template ] convert + + Scan the "dir" recursively to find markup files (.adoc or .md) + and convert them into HTML files. + The template "file" is optional, default to "templates/html.tmpl" in + the current directory. + +ciigo [-template ] [-out ] generate + + Convert all markup files inside directory "dir" recursively and then + embed them into ".go" source file. + The output file is optional, default to "ciigo_static.go" in current + directory. + +ciigo [-template ] [-address ] serve + + Serve all files inside directory "dir" using HTTP server, watch + changes on markup files and convert them to HTML files automatically. + If the address is not set, its default to ":8080". +`) +} diff --git a/content/index.adoc b/content/index.adoc index 5be9b37..acd8372 100644 --- a/content/index.adoc +++ b/content/index.adoc @@ -1,8 +1,8 @@ = Welcome to ciigo :stylesheet: /assets/style.css -`ciigo` is a program to write static web server with embedded files using -generated markup format. +`ciigo` is a library and a program to write static web server with embedded +files using generated markup format. Currently, ciigo support https://asciidoctor.org/docs/what-is-asciidoc/[asciidoc] @@ -11,7 +11,13 @@ https://commonmark.org/[markdown] as markup format. -== Document Structure +== ciigo as library + +This README explain how to use the ciigo as library. +For ciigo as command line interface see + + +=== Document Structure This software use the following directory structure and file name conventions, @@ -30,10 +36,10 @@ conventions, * `templates`: contains dynamic templates. Currently. there is only single template: `html.tmpl`, that wrap the generated HTML. -* All markup files inside content must have an ".adoc" extension. +* All markup files inside content must have an ".adoc" or ".md" extension. -== Getting Started +=== Getting Started This section describe step by step instructions on how to build and create pages to be viewed for local development using `ciigo`. @@ -122,7 +128,9 @@ Hello, world! . Run `go generate` to convert all files with extension `.adoc` (or `.md`) into HTML and embed it into `./cmd/mysite/static.go` + - $ go generate +---- +$ go generate +---- . Now run the `./cmd/mysite` with `DEBUG` environment variable is set, + @@ -140,12 +148,12 @@ You should see "Hello, world!" as the main page. Thats it! -Create or update any ".adoc" files in "content" directory, the program will -automatically generated the HTML file, but you still need to refresh the web -browser to load the new generated file. +Create or update any ".adoc" or ",md" files inside "content" directory, the +program will automatically generated the HTML file, but you still need to +refresh the web browser to load the new generated file. -== Deployment +=== Deployment First, we need to convert all markup files inside "content" into HTML and dump the content of all static files inside "content", @@ -175,6 +183,34 @@ Finally, deploy the program to your server. If you need to use another port, you can change it at `cmd/mysite/main.go`. +== ciigo as CLI + +ciigo as CLI can convert, generate, and/or serve a directory that contains +markup files, as HTML files. + +=== Usage + + ciigo convert [-template ] + +Scan the "dir" recursively to find markup files (.adoc or .md) and +convert them into HTML files. +The template "file" is optional, default to "templates/html.tmpl" in +the current directory. + + ciigo generate [-template ] [-out ] + +Convert all markup files inside directory "dir" recursively and then +embed them into ".go" source file. +The output file is optional, default to "ciigo_static.go" in current +directory. + + ciigo serve [-template ] [-address ] + +Serve all files inside directory "dir" using HTTP server, watch +changes on markup files and convert them to HTML files automatically. +If the address is not set, its default to ":8080". + + == Limitations and Known Bugs `ciigo` will not handle automatic certificate (e.g. using LetsEncrypt), its diff --git a/generate.go b/generate.go index 3391f60..d6f06b3 100644 --- a/generate.go +++ b/generate.go @@ -15,6 +15,22 @@ import ( "github.com/shuLhan/share/lib/memfs" ) +// +// Convert all markup files inside directory, recursively, into HTML files +// using "htmlTemplate" file as template. +// +func Convert(dir, htmlTemplate string) { + if len(dir) == 0 { + dir = "." + } + + htmlg := newHTMLGenerator(htmlTemplate) + + markupFiles := listMarkupFiles(dir) + + htmlg.convertMarkupFiles(markupFiles, true) +} + // // Generate a static Go file to be used for building binary. // @@ -22,8 +38,8 @@ import ( // recursively; and read all the HTML files and files in "content/assets" and // convert them into Go file in "out". // -func Generate(root, out string) { - htmlg := newHTMLGenerator() +func Generate(root, out, htmlTemplate string) { + htmlg := newHTMLGenerator(htmlTemplate) markupFiles := listMarkupFiles(root) htmlg.convertMarkupFiles(markupFiles, false) diff --git a/generate_main.go b/generate_main.go index 0e5e391..ca7f37c 100644 --- a/generate_main.go +++ b/generate_main.go @@ -12,5 +12,5 @@ import ( ) func main() { - ciigo.Generate("./content", "cmd/ciigo-example/static.go") + ciigo.Generate("./content", "cmd/ciigo-example/static.go", "") } diff --git a/htmlgenerator.go b/htmlgenerator.go index c6b4621..022fdbb 100644 --- a/htmlgenerator.go +++ b/htmlgenerator.go @@ -28,9 +28,13 @@ type htmlGenerator struct { tmpl *template.Template } -func newHTMLGenerator() (htmlg *htmlGenerator) { +func newHTMLGenerator(htmlTemplate string) (htmlg *htmlGenerator) { + if len(htmlTemplate) == 0 { + htmlTemplate = defHTMLTemplate + } + htmlg = &htmlGenerator{ - path: "./templates/html.tmpl", + path: htmlTemplate, mdg: goldmark.New( goldmark.WithExtensions( meta.Meta, diff --git a/server.go b/server.go index 03fd581..78e6572 100644 --- a/server.go +++ b/server.go @@ -28,10 +28,13 @@ type Server struct { } // -// NewServer create an HTTP server to serve HTML files in directory "content". +// NewServer create an HTTP server to serve HTML files in directory "root". +// // The address parameter is optional, if not set its default to ":8080". +// The htmlTemplate parameter is optional, if not set its default to +// "templates/html.tmpl" in current directory. // -func NewServer(root, address string) (srv *Server) { +func NewServer(root, address, htmlTemplate string) (srv *Server) { var err error if len(root) == 0 { @@ -56,8 +59,9 @@ func NewServer(root, address string) (srv *Server) { } if srv.opts.Development { - srv.htmlg = newHTMLGenerator() + srv.htmlg = newHTMLGenerator(htmlTemplate) srv.markupFiles = listMarkupFiles(root) + srv.htmlg.convertMarkupFiles(srv.markupFiles, false) } return srv @@ -71,7 +75,7 @@ func (srv *Server) Start() { srv.autoGenerate() } - fmt.Printf("ciigo: starting HTTP server at %s for %s\n", + fmt.Printf("ciigo: starting HTTP server at %q for %q\n", srv.opts.Address, srv.opts.Root) err := srv.http.Start() -- cgit v1.3