pax_global_header00006660000000000000000000000064131543044610014513gustar00rootroot0000000000000052 comment=5758a27b19771d9c210fb407cd53b8fe6b832a1c emd-1.0.1/000077500000000000000000000000001315430446100122575ustar00rootroot00000000000000emd-1.0.1/.gitignore000066400000000000000000000000171315430446100142450ustar00rootroot00000000000000build/ vendor/ emd-1.0.1/.travis.yml000066400000000000000000000077551315430446100144060ustar00rootroot00000000000000sudo: required services: - docker language: go go: - 1.9 env: matrix: - OKARCH=amd64 OSARCH=amd64 - OKARCH=386 OSARCH=i386 global: - VERSION=${TRAVIS_TAG} - GH_USER=${TRAVIS_REPO_SLUG%/*} - GH_APP=${TRAVIS_REPO_SLUG#*/} - JFROG_CLI_OFFER_CONFIG=false # bintray token - secure: uUsxcTceYD5fMyCm1YaDbOwdDuAUn4MjX861d/EcwpVcuQcWdawewYwg8mAoy+0ast1nJBWZWaJfn3Rj0pBWRaZDmL3A69zs5VJMVOIxlRT4qYvBPaM4nkFBIRaHpY52Ahyzh9Gkfbsl9jWavYvI4LQKKDssygDfsbEu/P9FwYUl3ojCeyvenVjUoXeLZ7bHDPKEizQDfSiHlTerXOHbnv7E0s43awRHsFxPiH81Vv30isyQmkDWwrOQ8CQmIE7wrjooqZQYwbUVejn4h0wywdadN/tvrAjMOynL7cekGtcynqp8tLxY94XPW0jAZaZovwCnu6T2O4JRc9rzEEYMIDBy79P/WYcCTdxo/r61mua8eMOcZxsLdgPnky6dZYFGM5yiDlicJPYJZEAmz6OA+7WnkXfK0CjuX92iDHj5s/5mJivg1n6k2++91MYAmpc+5yIJiDiSumWddZg5UoovCeHK58+DYTDtfaovB7bEUcIWmr4xv5XcXZ8fRZX6CJJPayFcKfEtvNYthOL91/tGGUwjillMtM3OvC0aJb8vZtrXYavD/3Li2TirMLMN0+RDjg3DjCEMvLClfJLtM2aG2+ISFCcn6awsUx8ThwQlrLIKmzXXq+tnUNlcUcb7HhHUQD96WqSKuk38wvM3NS1OGR3ckCo/kfgouQMd+h3BcKE= before_install: - sudo add-apt-repository 'deb https://dl.bintray.com/mh-cbon/deb unstable main' - sudo apt-get -qq update - sudo apt-get install --allow-unauthenticated changelog go-bin-deb fakeroot - mkdir -p ${GOPATH}/bin - cd ~ - curl https://glide.sh/get | sh install: - cd $GOPATH/src/github.com/$TRAVIS_REPO_SLUG - glide install - go install script: - go test emd/* - sh test.sh before_deploy: # create the deb package - cd $GOPATH/src/github.com/$TRAVIS_REPO_SLUG - mkdir -p build/$OSARCH - GOOS=linux go build --ldflags "-X main.VERSION=$VERSION" -o build/$OSARCH/$GH_APP main.go - go-bin-deb generate --file deb.json -a $OSARCH --version $VERSION -o $GH_APP-$OSARCH-$VERSION.deb # copy the deb for gh release (backward compatibility) - cp $GH_APP-$OSARCH-$VERSION.deb $GH_APP-$OKARCH.deb # upload to bintray - curl -fL https://getcli.jfrog.io | sh - ls -alh - ./jfrog bt pc --key=$BTKEY --user=$GH_USER --licenses=MIT --vcs-url=https://github.com/$GH_USER/deb $GH_USER/deb/$GH_APP || echo "package already exists" - ./jfrog bt upload --override=true --key $BTKEY --publish=true --deb=unstable/main/$OSARCH $GH_APP-$OSARCH-$VERSION.deb $GH_USER/deb/$GH_APP/$VERSION pool/g/$GH_APP/ # prepare rpm package creation - docker pull fedora # create the package in the docker - > docker run -v $PWD:/mnt/travis fedora /bin/sh -c "cd /mnt/travis && (curl -s -L https://bintray.com/mh-cbon/rpm/rpm > /etc/yum.repos.d/w.repo) && dnf install go-bin-rpm changelog rpm-build -y --quiet && go-bin-rpm generate --file rpm.json -a $OSARCH --version $VERSION -o $GH_APP-$OSARCH-$VERSION.rpm" # copy the rpm for gh release (backward compatibility) - cp $GH_APP-$OSARCH-$VERSION.rpm $GH_APP-$OKARCH.rpm # upload to bintray - ./jfrog bt pc --key=$BTKEY --user=$GH_USER --licenses=MIT --vcs-url=https://github.com/$GH_USER/rpm $GH_USER/rpm/$GH_APP || echo "package already exists" - ./jfrog bt upload --override=true --key $BTKEY --publish=true $GH_APP-$OSARCH-$VERSION.rpm $GH_USER/rpm/$GH_APP/$VERSION pool/$POOL/$GH_APP/ # generate the repo metadata - curl -X POST -u ${GH_USER}:${BTKEY} https://api.bintray.com/calc_metadata/${GH_USER}/rpm deploy: provider: releases api_key: secure: em4nCHJdPAXZ+jP/uDflyFfELb9Yn5B3C7rqjBYm1SdTi1KZVZyyOohckoPmljoHt2kva1ls5yszp8pFCj8mFXi1kY6UVV77VC6tYmcrGmP9FXz2iY+X3q2wulu8bU7f+mcG/whfOKPVU/hxLm6iNfcUw3oWNvH8vdZodtBse5UwFi4VkWZBa08Oj9JRR2P0JSMyHsDbvTNeC25xz8j9ytHcv2+j7pvOQf+Swam3z/FknRkG5hxpklMiFCBxKo4FkMKmSNWaH7F2AXGwTyqBgCj4uOEAJsp2Gi27Gw+dC8OOKxx/t9e4l38i5QqWVGVuSFW+wOLwr2StT5rVVG+QDxv61nkh5vLsXckRe7zxA4D2ldf8KtkyLP4vNaAtbUFTmyRJ+I8LhicAn6j4vjOtYpB+CwkGI21if1GEU7fygF7fyIqBss9TOHb4OJUNK16ZVA0do+ZGDcwTgPx11zcgd2Emxl4z2I/ue7OXXJ1hz95tHqMZz8z0hKffdxmVOgp3pQ9w8VoZfBxicGRrWKnr35vH2vkx3R2mmLj7MW3DpDrCRD3qSQ2A7hu4vEiTY0c1yzy6OEWwgfJsx7hnRSU29iaw9Ep0ScXxf/2DtWA6DxY6A/sWd1jGePPlPhOTpx5fdLEiITR0DyHKpe5tHDfXJl6Jn0fwl8nwCc4+bGSAMqk= file_glob: true file: - $GH_APP-$OKARCH.deb - $GH_APP-$OKARCH.rpm skip_cleanup: true on: tags: true emd-1.0.1/.version.sh000066400000000000000000000014541315430446100143620ustar00rootroot00000000000000PREBUMP= 666 git fetch --tags origin master 666 git pull origin master PREVERSION= philea -s "666 go vet %s" "666 go-fmt-fail %s" 666 go run main.go -version 666 go test emd/* -v 666 go test utils/* -v 666 go test provider/std/* -v 666 changelog finalize --version !newversion! 666 commit -q -m "changelog: !newversion!" -f change.log 666 changelog md -o CHANGELOG.md --guess 666 commit -q -m "changelog: !newversion!" -f CHANGELOG.md 666 go install --ldflags "-X main.VERSION=!newversion!" 666 emd gen -out README.md 666 commit -q -m "README: !newversion!" -f README.md POSTVERSION= 666 git push 666 git push --tags 666 gh-api-cli create-release -n release -o mh-cbon --guess \ --ver !newversion! -c "changelog ghrelease --version !newversion!" \ --draft !isprerelease! emd-1.0.1/CHANGELOG.md000066400000000000000000000333561315430446100141020ustar00rootroot00000000000000# Changelog - emd ### 1.0.1 __Changes__ - templates: - `choco_bintray/install` to show a snippet to install the app from bintray using chocolatey - `linux/bintray_repo` to show a snippet to install the app from bintray `apt/dnf` repository. __Contributors__ - mh-cbon Released by mh-cbon, Tue 29 Aug 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/1.0.0...1.0.1#diff) ______________ ### 1.0.0 __Changes__ - toc: fix link generator to remove colon - close #26: avoid fatal error when a path is not recognized - appveyor: close #28: fix badge urls __Contributors__ - mh-cbon - solvingJ Released by mh-cbon, Thu 24 Aug 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.12...1.0.0#diff) ______________ ### 0.0.12 __Changes__ - __cli__: - ensure data passed on the command line overwrites everthing else, fix #19. - __dep__: - fixed glide lock, needed an update. - __dev__: - Add provider tests __Contributors__ - mh-cbon Released by mh-cbon, Wed 10 May 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.11...0.0.12#diff) ______________ ### 0.0.11 __Changes__ - __CLI__: - Fix an issue in argument handling. - __Path detection__: #17 - The mechanism to detect and extract information from the path, is improved to work with anything that matches src/[provider]/[user]/[repo]/[path...] - __Temaplate func helpers__: - __pkg_doc__: won t panic anymore if the default `main.go` file is not yet created. - __Temaplates__: #16 - Fix templates output to avoid double `/`. - __dev__: - Largely improved tests. __Contributors__ - mh-cbon - suntong Released by mh-cbon, Sun 07 May 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.10...0.0.11#diff) ______________ ### 0.0.10 __Changes__ - __CLI__: - new `init` command: Writes a basic `README.e.md` frile to get started - `gen`: removed useless confirmation message on successful operation. - `stdin`: emd can now receives the input template from STDIN. - verbosity: Added support for verbosity with env variable `VERBOSE=y`. - __Predefined data__: - New api is introduced to better detect predefined data. - ProjectPath is better handled when its a symlink outside of `GOPATH` (#15 thanks suntong) - __Prelude data__: - It is now possible to override predefined data within the prelude. This should allow the end user to recover from a buggy implementation in the pre defined variables declaration. - __TOC__: - #16 Improve link generator to handle `[]|',` - Multiple fixes to properly render the TOC level of each header. - __Template__: added multiple new functions to help to work with templates - __set__(name string, x interface{}): Save given value `x` as `name` on dot `.`. - __link__(url string, text ...string) string: Prints markdown link. - __img__(url string, alt ...string) string: Prints markdown image. - __concat__(x ...string) string: Concat given arguments. - __pathjoin__(x ...string) string: Join given arguments with `/`. - __dev__: - added small test suites into `test.sh` __Contributors__ - mh-cbon - suntong Released by mh-cbon, Sat 06 May 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.10-beta...0.0.10#diff) ______________ ### 0.0.10-beta __Changes__ - CLI: - new `init` command: Writes a basic `README.e.md` frile to get started - `gen`: removed useless confirmation message on successful operation. - Predefined data: - New api is introduced to better detect predefined data. - Prelude data: - It is now possible to override predefined data within the prelude. This should allow the end user to recover from a buggy implementation in the pre defined variables declaration. - TOC: - #16 Improve link generator to handle `[]|',` - Multiple fixes to properly render the TOC level of each header. - Template: added multiple new functions to help to work with templates - __set__(name string, x interface{}): Save given value `x` as `name` on dot `.`. - __link__(url string, text ...string) string: Prints markdown link. - __img__(url string, alt ...string) string: Prints markdown image. - __concat__(x ...string) string: Concat given arguments. - __pathjoin__(x ...string) string: Join given arguments with `/`. __Contributors__ - mh-cbon Released by mh-cbon, Mon 24 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9...0.0.10-beta#diff) ______________ ### 0.0.9 __Changes__ - feature #10: Emd file can define a prelude block of `yaml` data to inject into the template processing. - cli fix: Before the -in argument was mandatory. It was not possible to use the default template. - feature installer: Fixed apt/rpm repositories. - feature #8: ensure an errored command line execution displays correctly. - feature: added new template functions - __yaml__(file string, keypaths ...string): parses and build new yaml content of given file. - __preline__(pre , content string): prepends pre for every lines of content. - __echo__(s ...string): echo every string s. - __read__(file string): returns file content. - __cat__(file string): to display the file content. - __exec__(bin string, args ...string): to exec a program. - __shell__(s string): to exec a command line on the underlying shell (it is not cross compatible). - __color__(color string, content string): to embed content in a block code with color. - __gotest__(rpkg string, run string, args ...string): exec `go test -v -run `. - __toc__(maximportance string, title string): display a TOC. - feature: added new badge templates - __license/shields__: show a license badge - __badge/codeship__: show a codeship badge - __deprecation__ #7: some template functions were deprecated to avoid pre defined formatting, old behavior can be reset via new options defined into the prelude data. See also the new __color__ function. - __file__ is dprecated for __cat__ - __cli__ is dprecated for __exec__ - badges fix #14: removed useless whitespace - dev: Added support for glide, it was required to handle yaml. - dev: updated tests - dev: godoc documentation improvements. __Contributors__ - suntong - mh-cbon Released by mh-cbon, Sat 22 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta9...0.0.9#diff) ______________ ### 0.0.9-beta9 __Changes__ - fix default reading of the md file __Contributors__ - mh-cbon Released by mh-cbon, Tue 18 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta8...0.0.9-beta9#diff) ______________ ### 0.0.9-beta8 __Changes__ - fix #15: properly handle symbolic links - fix cli: it was not possible to use the default template __Contributors__ - mh-cbon Released by mh-cbon, Tue 18 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta7...0.0.9-beta8#diff) ______________ ### 0.0.9-beta7 __Changes__ - fix wrong import path __Contributors__ - mh-cbon Released by mh-cbon, Mon 17 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta6...0.0.9-beta7#diff) ______________ ### 0.0.9-beta6 __Changes__ - ci: fix scripts to add glide support __Contributors__ - mh-cbon Released by mh-cbon, Mon 17 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta5...0.0.9-beta6#diff) ______________ ### 0.0.9-beta5 __Changes__ - new functions: - __yaml__(file string, keypaths ...string): parses and build new yaml content of given file. - __preline__(pre , content string): prepends pre for every lines of content. - __echo__(s ...string): echo every string s. - __read__(file string): returns file content. - toc: multiple fixes, - it properly handles duplicated title by appending an increment - fix handling of !; in links generator - fix line counting when extracting markdown titles - fix md title selection starting at line N - prelude: - fix read of quoted values - prelude data is now read on all templates added, not only file - fix last eol handling - codeship fix #2: proper project url - bump script: added new utils/ tests - glide: init versionned dependencies to handle yaml files. - godoc: refactoring to improve documentation __Contributors__ - mh-cbon Released by mh-cbon, Mon 17 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta4...0.0.9-beta5#diff) ______________ ### 0.0.9-beta4 __Changes__ - toc: improve toc parser, refactored, added tests __Contributors__ - mh-cbon Released by mh-cbon, Fri 14 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta3...0.0.9-beta4#diff) ______________ ### 0.0.9-beta3 __Changes__ - fix #13: add new template to show a license badge. - prelude: trim leading whitespaces of unquoted values. - fix #14: improved badge output, removed useless whitespace. - fix #2: codeship badge template, added a CsProjectID parameter. - exec/shell/cat/gotest: avoid pre defined formatting, old behavior can be reset via new options defined into the prelude data. - toc: fixed some corner cases while parsing/generating the TOC. __Contributors__ - mh-cbon Released by mh-cbon, Fri 14 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta2...0.0.9-beta3#diff) ______________ ### 0.0.9-beta2 __Changes__ - fix some bugs in TOC title evaluation and generation - fix apt repository! __Contributors__ - mh-cbon Released by mh-cbon, Thu 13 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta1...0.0.9-beta2#diff) ______________ ### 0.0.9-beta1 __Changes__ - deprecation: improve error messages __Contributors__ - mh-cbon Released by mh-cbon, Wed 12 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.9-beta...0.0.9-beta1#diff) ______________ ### 0.0.9-beta __Changes__ - close #10: added feature to read, decode and registers the prelude data It is now possible to define a prelude block of `yaml` data in your __README__ file to register new data. - added __cat/exec/shell/color/gotest/toc__ func - __cat__(file string): to display the file content. - __exec__(bin string, args ...string): to exec a program. - __shell__(s string): to exec a command line on the underlying shell (it is not cross compatible). - __color__(color string, content string): to embed content in a block code with color. - __gotest__(rpkg string, run string, args ...string): exec `go test -v -run `. - __toc__(maximportance string, title string): display a TOC. - close #7: deprecated __file/cli__ func Those two functions are deprecated in flavor of their new equivalents, __cat/exec__. The new functions does not returns a triple backquuotes block code. They returns the response body only. A new function helper __color__ is a added to create a block code. - close #8: improved cli error output Before the output error was not displaying the command line entirely when it was too long. Now the error is updated to always display the command line with full length. - close #9: add new gotest helper func - close #12: add toc func - close #10: ensure unquoted strings are read properly - close #11: add shell func helper. __Contributors__ - mh-cbon Released by mh-cbon, Wed 12 Apr 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.8...0.0.9-beta#diff) ______________ ### 0.0.8 __Changes__ - fix goreport badge template __Contributors__ - mh-cbon Released by mh-cbon, Sun 12 Mar 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.7...0.0.8#diff) ______________ ### 0.0.7 __Changes__ - improve template documentation - goreport: add template (fixes #4) __Contributors__ - mh-cbon Released by mh-cbon, Sun 12 Mar 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.6...0.0.7#diff) ______________ ### 0.0.6 __Changes__ - template functions (std): add a new render template function to define additional values (fixes #2) - template function (std): file takes a new argument to define the colorizer (fixes #1) - emd: add new methods to access template, out and data - release: fix missing version to the emd build - README: multiple improvements. __Contributors__ - mh-cbon Released by mh-cbon, Mon 06 Mar 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.5...0.0.6#diff) ______________ ### 0.0.5 __Changes__ - badges: add codeship - Funcs cli/file: changed the MD template to add support for html anchors (before they was using bold tag, now they use a title tag) - command gen: prints success message only if out is not stdout - README: added a section to show HTML generation, and a recipe to bump the package. - release: change bump script format __Contributors__ - mh-cbon Released by mh-cbon, Mon 06 Mar 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.4...0.0.5#diff) ______________ ### 0.0.4 __Changes__ - changelog: typos - README: add template helpers documentation __Contributors__ - mh-cbon Released by mh-cbon, Wed 22 Feb 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.3...0.0.4#diff) ______________ ### 0.0.3 __Changes__ - travis(token): update ghtoken __Contributors__ - mh-cbon Released by mh-cbon, Wed 22 Feb 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.2...0.0.3#diff) ______________ ### 0.0.2 __Changes__ - README: fix appveyor badge - badge(update): fix url - README: fix appveyor badge - badge(fix): fix appveyor badge - README: add appveyor badge - badge(update): update text displayed in ci badges - README(fix): use correct bin path - bump(fix): emd gen command was wrong __Contributors__ - mh-cbon Released by mh-cbon, Wed 22 Feb 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/0.0.1...0.0.2#diff) ______________ ### 0.0.1 __Changes__ - project initialization __Contributors__ - mh-cbon Released by mh-cbon, Wed 22 Feb 2017 - [see the diff](https://github.com/mh-cbon/emd/compare/9b73c280847b824e4e366bcf3276d4eefecde4de...0.0.1#diff) ______________ emd-1.0.1/LICENSE000066400000000000000000000020471315430446100132670ustar00rootroot00000000000000MIT License Copyright (c) 2016 `o-zef Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. emd-1.0.1/README.e.md000066400000000000000000000173501315430446100137670ustar00rootroot00000000000000--- License: MIT LicenseFile: LICENSE LicenseColor: yellow --- # {{.Name}} {{template "badge/travis" .}} {{template "badge/appveyor" .}} {{template "badge/goreport" .}} {{template "badge/godoc" .}} {{template "license/shields" .}} {{pkgdoc}} See [emd README file](https://raw.githubusercontent.com/mh-cbon/emd/master/README.e.md) # {{toc 5}} # Install {{template "gh/releases" .}} #### glide {{template "glide/install" .}} #### Bintray {{template "choco_bintray/install" .}} #### Chocolatey {{template "choco/install" .}} #### linux rpm/deb repository {{template "linux/bintray_repo" .}} #### linux rpm/deb standalone package {{template "linux/gh_pkg" .}} # Usage #### $ {{exec "emd" "-help" | color "sh"}} #### $ {{shell "emd gen -help" | color "sh"}} #### $ {{shell "emd init -help" | color "sh"}} # Cli examples ```sh # Init a basic emd file to get started. emd init # Reads content of README.e.md, outputs to README.md emd gen -out README.md # same with data injections, emd gen -out README.md --data='{"CsUUID":"xxxx"}' # use verbose mode VERBOSE=y emd gen ``` # Templates helper #### Define data Template data can be defined directly into the `README.e.md` file using a `prelude`, ```yml --- title: "Easygen - Easy to use universal code/text generator" date: "2016-01-01T22:13:12-05:00" categories: ["Tech"] tags: ["go","programming","easygen","CLI"] --- ``` This `prelude` must be inserted right before the regular `md` content. The keys are injected into the template `dot`, the value are `json` decoded. Template can access those data using name: `{{echo "{{.categories}}" "{{.tags}}" }}` #### Data | Key | Description | | --- | --- | | __ProviderURL__ | The vcs provider url (example: github.com). | | __ProviderName__ | The vcs provider name (example: github). | | __Name__ | Project name based on the cwd (example: emd). | | __User__ | User name based on the cwd (example: mh-cbon). | | __URL__ | Project url as determined by the cwd (example: github.com/mh-cbon/emd). | | __ProjectURL__ | Project url as determined by the cwd + relative path (example: github.com/mh-cbon/emd/cmd). | | __Branch__ | Current vcs branch name (defaults to master). | #### Functions Functions can be invoked like this `{{echo "{{func \"arg1\" \"arg2\"}}" }}` Options are keys to define into the `prelude`: ```yaml --- emd_cat_pre: "### > " emd_gotest_pre: "### $ " emd_exec_pre: "### $ " emd_shell_pre: "### $ " --- ``` #### Files functions | Name | Description | Options | | --- | --- | -- | | __cat__(f string) | Displays a file header.
Read and return the file body. | `emd_cat_pre: "### > "`: string to show right before the file path. | | __read__(f string) | Read and return the file body. | | | __yaml__(f string, keypaths ...string) | Parse given file as yaml, locate given path into the yaml content, yaml re encode it, return its string. | | #### Templates functions | Name | Description | Options | | --- | --- | -- | | __render__(name string, data interface{}, keyValues ...interface{}) | Render given `template` name, using `data`.
Additionnal data values can be declared using `keyValues ...interface{}` signature, such as
`render("x", data, "key1", "val1", "key2", "val2")`. | | | | __set__(name string, x interface{}) | Save given value `x` as `name` on dot `.`. | | #### Go utils functions | Name | Description | Options | | --- | --- | -- | | __pkgdoc__(files ...string) | Read the first of `files`, or `main.go`, lookup for its package comment and return it as plain text. | | | __gotest__(rpkg string, run string, args ...string) | Run `go test -v -run `, return its output.
`rpkg` can be a path to a relative folder like `./emd`. It will resolve to
`github.com/mh-cbon/emd/emd`| `emd_gotest_pre: "### $ "` defines a sring to show right before the `go test` command line. | #### Markdown functions | Name | Description | Options | | --- | --- | -- | | __color__(color string, content string]) string | Embed given content with triple backquote syntax colorizer support. | | | __toc__(maxImportance int, title ...string) string | Displays a `TOC` of the `README` file being processed.
`maxImportance` defines the titles to select by their numbers of `#`.
`titles` define the title to display, defaults to `TOC`.
Titles displayed before the call to `{{echo "{{toc x}}" }}` are automatically ignored.| | | __preline__(pre string, content string) string | Prepend every line of `content` with `pre`. | | | __echo__(f string) string | Prints `f`, usefull to print strings which contains the template tokens. | | | __link__(url string, text ...string) string | Prints markdown link. | | | __img__(url string, alt ...string) string | Prints markdown image. | | | __concat__(x ...string) string | Concat all `x`. | | | __pathjoin__(x ...string) string | Join all `x` with `/`. | | #### Cli functions | Name | Description | Options | | --- | --- | -- | | __exec__(bin string, args ...string) | Display a command line header.
Execute and return its response. | `emd_exec_pre: "### > "`: string to show right before the command line. | | __shell__(s string) | Display a command line header.
Execute the command on a shell, and return the its response. | `emd_shell_pre: "### > "`: string to show right before the command line. | #### Deprecated function | Name | Description | | --- | --- | | __file__(f string[, colorizer string]) | Read and display a file enclosed with triples backquotes. If `colorizer` is empty, it defaults to the file extension. | | __cli__(bin string, args ...string) | Execute and display a command line enclosed with triples backquotes. The highlight defaults to `sh`. | #### Templates ##### std | Name | Description | Params | | --- | --- | --- | | __gh/releases__ | Show a text to link the release page. | | | __badge/travis__ | Show a travis badge. | | | __badge/appveyor__ | Show an appveyor badge. | | | __badge/codeship__ | Show a codeship badge. | __CsProjectID__: The codeship project ID (*123465*).
__CsUUID__: the codeship project UUID (*654654-6465-54...*).
Within your `e.md` file use the `render` function, `{{echo "{{render \"badge/codeship\" . \"CsUUID\" \"xx\" \"CsProjectID\" \"yyy\"}}"}}`.
Via cli, add it with `--data '{"CsUUID": "xx", "CsProjectID":"yy"}'`. | | __choco_bintray/install__ | Show a snippet to install the package with chocolatey from bintray repos. | __BintrayRepo__: the name of the bintray repo (default: `choco`) | | __choco/install__ | Show a snippet to install the package with chocolatey. | | | __linux/gh_src_repo__ | Show an sh snippet to install the package via `rpm|deb|apt` repositories hosted on gh-pages. | | | __linux/bintray_repo__ | Show an sh snippet to install the package via `rpm|deb|apt` repositories hosted on bintray. | | | __linux/gh_pkg__ | Show an sh snippet to install the package via standalone packages (deb/rpm). | | | __license/shields__ | Show a license badge. | __License__: The license name like `MIT`, `BSD`.
__LicenseFile__: The path to the license file.
__LicenseColor__: The color of the badge (defaults t o blue). | ##### go | Name | Description | Params | | --- | --- | --- | | __go/install__ | Show an sh snippet to install the package via `go get`. | | | __badge/godoc__ | Show a godoc badge. | | | __badge/goreport__ | Show a goreport badge. | | ##### go-nonstd | Name | Description | Params | | --- | --- | --- | | __glide/install__ | Show an sh snippet to install the package via `glide`. | | # API example #### > {{cat "main_test.go" | color "go"}} # Recipes #### Generate HTML content To directly generate HTML content out of `emd` output, for example, with `gh-markdown-cli`, ```sh npm install gh-markdown-cli -g emd gen | mdown ``` #### Release the project ```sh gump patch -d # check gump patch # bump ``` # History [CHANGELOG](CHANGELOG.md) emd-1.0.1/README.md000066400000000000000000000254361315430446100135500ustar00rootroot00000000000000# emd [![travis Status](https://travis-ci.org/mh-cbon/emd.svg?branch=master)](https://travis-ci.org/mh-cbon/emd) [![Appveyor Status](https://ci.appveyor.com/api/projects/status/github/mh-cbon/emd?branch=master&svg=true)](https://ci.appveyor.com/project/mh-cbon/emd) [![Go Report Card](https://goreportcard.com/badge/github.com/mh-cbon/emd)](https://goreportcard.com/report/github.com/mh-cbon/emd) [![GoDoc](https://godoc.org/github.com/mh-cbon/emd?status.svg)](http://godoc.org/github.com/mh-cbon/emd) [![MIT License](http://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) Enhanced Markdown template processor. See [emd README file](https://raw.githubusercontent.com/mh-cbon/emd/master/README.e.md) # TOC - [Install](#install) - [glide](#glide) - [Bintray](#bintray) - [Chocolatey](#chocolatey) - [linux rpm/deb repository](#linux-rpmdeb-repository) - [linux rpm/deb standalone package](#linux-rpmdeb-standalone-package) - [Usage](#usage) - [$ emd -help](#-emd--help) - [$ emd gen -help](#-emd-gen--help) - [$ emd init -help](#-emd-init--help) - [Cli examples](#cli-examples) - [Templates helper](#templates-helper) - [Define data](#define-data) - [Data](#data) - [Functions](#functions) - [Files functions](#files-functions) - [Templates functions](#templates-functions) - [Go utils functions](#go-utils-functions) - [Markdown functions](#markdown-functions) - [Cli functions](#cli-functions) - [Deprecated function](#deprecated-function) - [Templates](#templates) - [API example](#api-example) - [> main_test.go](#-main_testgo) - [Recipes](#recipes) - [Generate HTML content](#generate-html-content) - [Release the project](#release-the-project) - [History](#history) # Install Check the [release page](https://github.com/mh-cbon/emd/releases)! #### glide ```sh mkdir -p $GOPATH/src/github.com/mh-cbon/emd cd $GOPATH/src/github.com/mh-cbon/emd git clone https://github.com/mh-cbon/emd.git . glide install go install ``` #### Bintray ```sh choco source add -n=mh-cbon -s="https://api.bintray.com/nuget/mh-cbon/choco" choco install emd ``` #### Chocolatey ```sh choco install emd ``` #### linux rpm/deb repository ```sh wget -O - https://raw.githubusercontent.com/mh-cbon/latest/master/bintray.sh \ | GH=mh-cbon/emd sh -xe # or curl -L https://raw.githubusercontent.com/mh-cbon/latest/master/bintray.sh \ | GH=mh-cbon/emd sh -xe ``` #### linux rpm/deb standalone package ```sh curl -L https://raw.githubusercontent.com/mh-cbon/latest/master/install.sh \ | GH=mh-cbon/emd sh -xe # or wget -q -O - --no-check-certificate \ https://raw.githubusercontent.com/mh-cbon/latest/master/install.sh \ | GH=mh-cbon/emd sh -xe ``` # Usage #### $ emd -help ```sh emd - 0.0.0 Usage -h Show help -help Show help -v Show version -version Show version Commands gen Process an emd file. init Init a basic emd file. ``` #### $ emd gen -help ```sh emd - 0.0.0 Command "gen": Process an emd file. -data string JSON map of data -h Show help -help Show help -in string Input src file -out string Output destination, defaults to stdout (default "-") ``` #### $ emd init -help ```sh emd - 0.0.0 Command "init": Init a basic emd file. -force Force write -h Show help -help Show help -out string Out file (default "README.e.md") ``` # Cli examples ```sh # Init a basic emd file to get started. emd init # Reads content of README.e.md, outputs to README.md emd gen -out README.md # same with data injections, emd gen -out README.md --data='{"CsUUID":"xxxx"}' # use verbose mode VERBOSE=y emd gen ``` # Templates helper #### Define data Template data can be defined directly into the `README.e.md` file using a `prelude`, ```yml --- title: "Easygen - Easy to use universal code/text generator" date: "2016-01-01T22:13:12-05:00" categories: ["Tech"] tags: ["go","programming","easygen","CLI"] --- ``` This `prelude` must be inserted right before the regular `md` content. The keys are injected into the template `dot`, the value are `json` decoded. Template can access those data using name: `{{.categories}} {{.tags}}` #### Data | Key | Description | | --- | --- | | __ProviderURL__ | The vcs provider url (example: github.com). | | __ProviderName__ | The vcs provider name (example: github). | | __Name__ | Project name based on the cwd (example: emd). | | __User__ | User name based on the cwd (example: mh-cbon). | | __URL__ | Project url as determined by the cwd (example: github.com/mh-cbon/emd). | | __ProjectURL__ | Project url as determined by the cwd + relative path (example: github.com/mh-cbon/emd/cmd). | | __Branch__ | Current vcs branch name (defaults to master). | #### Functions Functions can be invoked like this `{{func "arg1" "arg2"}}` Options are keys to define into the `prelude`: ```yaml --- emd_cat_pre: "### > " emd_gotest_pre: "### $ " emd_exec_pre: "### $ " emd_shell_pre: "### $ " --- ``` #### Files functions | Name | Description | Options | | --- | --- | -- | | __cat__(f string) | Displays a file header.
Read and return the file body. | `emd_cat_pre: "### > "`: string to show right before the file path. | | __read__(f string) | Read and return the file body. | | | __yaml__(f string, keypaths ...string) | Parse given file as yaml, locate given path into the yaml content, yaml re encode it, return its string. | | #### Templates functions | Name | Description | Options | | --- | --- | -- | | __render__(name string, data interface{}, keyValues ...interface{}) | Render given `template` name, using `data`.
Additionnal data values can be declared using `keyValues ...interface{}` signature, such as
`render("x", data, "key1", "val1", "key2", "val2")`. | | | | __set__(name string, x interface{}) | Save given value `x` as `name` on dot `.`. | | #### Go utils functions | Name | Description | Options | | --- | --- | -- | | __pkgdoc__(files ...string) | Read the first of `files`, or `main.go`, lookup for its package comment and return it as plain text. | | | __gotest__(rpkg string, run string, args ...string) | Run `go test -v -run `, return its output.
`rpkg` can be a path to a relative folder like `./emd`. It will resolve to
`github.com/mh-cbon/emd/emd`| `emd_gotest_pre: "### $ "` defines a sring to show right before the `go test` command line. | #### Markdown functions | Name | Description | Options | | --- | --- | -- | | __color__(color string, content string]) string | Embed given content with triple backquote syntax colorizer support. | | | __toc__(maxImportance int, title ...string) string | Displays a `TOC` of the `README` file being processed.
`maxImportance` defines the titles to select by their numbers of `#`.
`titles` define the title to display, defaults to `TOC`.
Titles displayed before the call to `{{toc x}}` are automatically ignored.| | | __preline__(pre string, content string) string | Prepend every line of `content` with `pre`. | | | __echo__(f string) string | Prints `f`, usefull to print strings which contains the template tokens. | | | __link__(url string, text ...string) string | Prints markdown link. | | | __img__(url string, alt ...string) string | Prints markdown image. | | | __concat__(x ...string) string | Concat all `x`. | | | __pathjoin__(x ...string) string | Join all `x` with `/`. | | #### Cli functions | Name | Description | Options | | --- | --- | -- | | __exec__(bin string, args ...string) | Display a command line header.
Execute and return its response. | `emd_exec_pre: "### > "`: string to show right before the command line. | | __shell__(s string) | Display a command line header.
Execute the command on a shell, and return the its response. | `emd_shell_pre: "### > "`: string to show right before the command line. | #### Deprecated function | Name | Description | | --- | --- | | __file__(f string[, colorizer string]) | Read and display a file enclosed with triples backquotes. If `colorizer` is empty, it defaults to the file extension. | | __cli__(bin string, args ...string) | Execute and display a command line enclosed with triples backquotes. The highlight defaults to `sh`. | #### Templates ##### std | Name | Description | Params | | --- | --- | --- | | __gh/releases__ | Show a text to link the release page. | | | __badge/travis__ | Show a travis badge. | | | __badge/appveyor__ | Show an appveyor badge. | | | __badge/codeship__ | Show a codeship badge. | __CsProjectID__: The codeship project ID (*123465*).
__CsUUID__: the codeship project UUID (*654654-6465-54...*).
Within your `e.md` file use the `render` function, `{{render "badge/codeship" . "CsUUID" "xx" "CsProjectID" "yyy"}}`.
Via cli, add it with `--data '{"CsUUID": "xx", "CsProjectID":"yy"}'`. | | __choco_bintray/install__ | Show a snippet to install the package with chocolatey from bintray repos. | __BintrayRepo__: the name of the bintray repo (default: `choco`) | | __choco/install__ | Show a snippet to install the package with chocolatey. | | | __linux/gh_src_repo__ | Show an sh snippet to install the package via `rpm|deb|apt` repositories hosted on gh-pages. | | | __linux/bintray_repo__ | Show an sh snippet to install the package via `rpm|deb|apt` repositories hosted on bintray. | | | __linux/gh_pkg__ | Show an sh snippet to install the package via standalone packages (deb/rpm). | | | __license/shields__ | Show a license badge. | __License__: The license name like `MIT`, `BSD`.
__LicenseFile__: The path to the license file.
__LicenseColor__: The color of the badge (defaults t o blue). | ##### go | Name | Description | Params | | --- | --- | --- | | __go/install__ | Show an sh snippet to install the package via `go get`. | | | __badge/godoc__ | Show a godoc badge. | | | __badge/goreport__ | Show a goreport badge. | | ##### go-nonstd | Name | Description | Params | | --- | --- | --- | | __glide/install__ | Show an sh snippet to install the package via `glide`. | | # API example #### > main_test.go ```go package main_test import ( "os" "github.com/mh-cbon/emd/emd" "github.com/mh-cbon/emd/std" ) var projectName = "dummy" // ExampleGenerate demonstrates the generation // of the given README.e.md source file // to os.Stdout. func Example() { // make a new instance of emd.Generator. gen := emd.NewGenerator() // set the main template. gen.AddTemplate("{{.Name}}") // set the data available in templates. gen.SetDataMap(map[string]interface{}{"Name": projectName}) // register a plugin if err := std.Register(gen); err != nil { panic(err) } // process the template. if err := gen.Execute(os.Stdout); err != nil { panic(err) } // Output: dummy } ``` # Recipes #### Generate HTML content To directly generate HTML content out of `emd` output, for example, with `gh-markdown-cli`, ```sh npm install gh-markdown-cli -g emd gen | mdown ``` #### Release the project ```sh gump patch -d # check gump patch # bump ``` # History [CHANGELOG](CHANGELOG.md) emd-1.0.1/_config.yml000066400000000000000000000000321315430446100144010ustar00rootroot00000000000000theme: jekyll-theme-caymanemd-1.0.1/appveyor.yml000066400000000000000000000123141315430446100146500ustar00rootroot00000000000000image: Visual Studio 2017 clone_folder: c:\gopath\src\github.com\%APPVEYOR_REPO_NAME% skip_non_tags: true environment: GOPATH: c:\gopath JFROG_CLI_OFFER_CONFIG: false VCS_URL: https://github.com/%APPVEYOR_REPO_NAME% BT_KEY: secure: P9xGXGG38T4AvO8XXXXcbaDG2sSN4t6KH92zssGp0nrbyQAZuxHD9F84s6PM9mOD # CHOCOKEY: # secure: HRc9tf57V3c3dVyn8hvMkKeiwK2oyWvOSjNXembIAQctNx+GTGBBaHI3bh+8cIgy GH_TOKEN: secure: WVMaMjrLzXN8YNcnFRfcucTYWtvoDeE/4b2TUGQBZDvv7u+ERBQ///z5Q8qYSt0L # environment: # GOPATH: c:\gopath # GO15VENDOREXPERIMENT: 1 # CHOCOKEY: # secure: HRc9tf57V3c3dVyn8hvMkKeiwK2oyWvOSjNXembIAQctNx+GTGBBaHI3bh+8cIgy # GHTOKEN: # secure: WVMaMjrLzXN8YNcnFRfcucTYWtvoDeE/4b2TUGQBZDvv7u+ERBQ///z5Q8qYSt0L install: - choco source add -n=mh-cbon -s="https://api.bintray.com/nuget/mh-cbon/choco" - choco install changelog gh-api-cli go-msi -y - refreshenv - set GH_APP=%APPVEYOR_PROJECT_NAME% - set GH_USER=%APPVEYOR_ACCOUNT_NAME% - set VERSION=%APPVEYOR_REPO_TAG_NAME% - if "%x%"=="%VERSION%" set VERSION=1.0.2 - set PATH=%WIX%\bin;%PATH% - set PATH=%GOPATH%\bin;%PATH% - curl -fsSk -o jfrog.exe -L "https://api.bintray.com/content/jfrog/jfrog-cli-go/$latest/jfrog-cli-windows-amd64/jfrog.exe?bt_package=jfrog-cli-windows-amd64" - go get -u github.com/mh-cbon/never-fail - go get -u github.com/Masterminds/glide - glide install # install: # - ps: if (-not (Test-Path env:APPVEYOR_REPO_TAG_NAME)) { $env:APPVEYOR_REPO_TAG_NAME = '0.0.2' } # - curl -fsSL -o C:\wix310-binaries.zip http://static.wixtoolset.org/releases/v3.10.3.3007/wix310-binaries.zip # - 7z x C:\wix310-binaries.zip -y -r -oC:\wix310 # - set PATH=C:\wix310;%PATH% # - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% # - go version # - go env # - curl -fsSL -o C:\latest.bat https://raw.githubusercontent.com/mh-cbon/latest/master/latest.bat?a=1 # - cmd /C C:\latest.bat mh-cbon go-msi amd64 # - set PATH=C:\Program Files\go-msi\;%PATH% # - go get -u github.com/Masterminds/glide # - glide install # - go test github.com/mh-cbon/emd -v # build msi artifacts build_script: - go test github.com/mh-cbon/emd -v # x386 - set GOARCH=386 - go build -o %GH_APP%.exe --ldflags "-X main.VERSION=%VERSION%" main.go - go-msi make --msi %GH_APP%-%GOARCH%-%VERSION%.msi --version %VERSION% --arch %GOARCH% - cp %GH_APP%-%GOARCH%-%VERSION%.msi %GH_APP%-%GOARCH%.msi # nuget package is built only for the x86 arch. - go-msi choco --path wix.json --version %VERSION% --input %GH_APP%-%GOARCH%-%VERSION%.msi --changelog-cmd "changelog ghrelease --version %VERSION%" # amd64 - set GOARCH=amd64 - go build -o %GH_APP%.exe --ldflags "-X main.VERSION=%VERSION%" main.go - go-msi make --msi %GH_APP%-%GOARCH%-%VERSION%.msi --version %VERSION% --arch %GOARCH% - cp %GH_APP%-%GOARCH%-%VERSION%.msi %GH_APP%-%GOARCH%.msi # build_script: # - set GOARCH=386 # - go build -o %APPVEYOR_PROJECT_NAME%.exe --ldflags "-X main.VERSION=%APPVEYOR_REPO_TAG_NAME%" main.go # - go-msi.exe make --msi %APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%-%GOARCH%.msi --version %APPVEYOR_REPO_TAG_NAME% --arch %GOARCH% # - set GOARCH=amd64 # - go build -o %APPVEYOR_PROJECT_NAME%.exe --ldflags "-X main.VERSION=%APPVEYOR_REPO_TAG_NAME%" main.go # - go-msi.exe make --msi %APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%-%GOARCH%.msi --version %APPVEYOR_REPO_TAG_NAME% --arch %GOARCH% # after_deploy: # - go-msi.exe choco --input %APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%-%GOARCH%.msi --version %APPVEYOR_REPO_TAG_NAME% # - choco push -k="'%CHOCOKEY%'" %APPVEYOR_PROJECT_NAME%.%APPVEYOR_REPO_TAG_NAME%.nupkg deploy_script: - never-fail jfrog bt pc --user %GH_USER% --key %BT_KEY% --licenses=MIT --vcs-url=https://github.com/%APPVEYOR_REPO_NAME% %GH_USER%/msi/%GH_APP% - never-fail jfrog bt pc --user %GH_USER% --key %BT_KEY% --licenses=MIT --vcs-url=https://github.com/%APPVEYOR_REPO_NAME% %GH_USER%/choco/%GH_APP% - never-fail curl -X "DELETE" -u%GH_USER%:%BT_KEY% https://api.bintray.com/content/%GH_USER%/choco/%GH_APP%.%VERSION%.nupkg # workaround until --override=true is honored in next upload - jfrog bt upload --user %GH_USER% --key %BT_KEY% --override=true --publish=true %GH_APP%.%VERSION%.nupkg %GH_USER%/choco/%GH_APP%/%VERSION% - set GOARCH=386 - jfrog bt upload --user %GH_USER% --key %BT_KEY% --override=true --publish=true %GH_APP%-%GOARCH%-%VERSION%.msi %GH_USER%/msi/%GH_APP%/%VERSION% - set GOARCH=amd64 - jfrog bt upload --user %GH_USER% --key %BT_KEY% --override=true --publish=true %GH_APP%-%GOARCH%-%VERSION%.msi %GH_USER%/msi/%GH_APP%/%VERSION% # next section is a workaround for https://github.com/appveyor/ci/issues/1752 - gh-api-cli upload-release-asset -t %GH_TOKEN% -g "*-386.msi" -o %GH_USER% -r %GH_APP% --ver %VERSION% - gh-api-cli upload-release-asset -t %GH_TOKEN% -g "*-amd64.msi" -o %GH_USER% -r %GH_APP% --ver %VERSION% test: off artifacts: - path: '*-386.msi' name: msi-x86 - path: '*-amd64.msi' name: msi-x64 deploy: - provider: GitHub artifact: msi-x86, msi-x64 draft: false prerelease: false description: "Release %APPVEYOR_REPO_TAG_NAME%" auth_token: secure: WVMaMjrLzXN8YNcnFRfcucTYWtvoDeE/4b2TUGQBZDvv7u+ERBQ///z5Q8qYSt0L on: appveyor_repo_tag: true emd-1.0.1/change.log000066400000000000000000000316421315430446100142150ustar00rootroot00000000000000 1.0.1 * templates: - `choco_bintray/install` to show a snippet to install the app from bintray using chocolatey - `linux/bintray_repo` to show a snippet to install the app from bintray `apt/dnf` repository. - mh-cbon -- mh-cbon ; Tue, 29 Aug 2017 19:51:46 +0200 1.0.0 * toc: fix link generator to remove colon * close #26: avoid fatal error when a path is not recognized * appveyor: close #28: fix badge urls - mh-cbon - solvingJ -- mh-cbon ; Thu, 24 Aug 2017 18:46:21 +0200 0.0.12 * __cli__: - ensure data passed on the command line overwrites everthing else, fix #19. * __dep__: - fixed glide lock, needed an update. * __dev__: - Add provider tests - mh-cbon -- mh-cbon ; Wed, 10 May 2017 11:30:14 +0200 0.0.11 * __CLI__: - Fix an issue in argument handling. * __Path detection__: #17 - The mechanism to detect and extract information from the path, is improved to work with anything that matches src/[provider]/[user]/[repo]/[path...] * __Temaplate func helpers__: - __pkg_doc__: won t panic anymore if the default `main.go` file is not yet created. * __Temaplates__: #16 - Fix templates output to avoid double `/`. * __dev__: - Largely improved tests. - mh-cbon - suntong -- mh-cbon ; Sun, 07 May 2017 16:05:48 +0200 0.0.10 * __CLI__: - new `init` command: Writes a basic `README.e.md` frile to get started - `gen`: removed useless confirmation message on successful operation. - `stdin`: emd can now receives the input template from STDIN. - verbosity: Added support for verbosity with env variable `VERBOSE=y`. * __Predefined data__: - New api is introduced to better detect predefined data. - ProjectPath is better handled when its a symlink outside of `GOPATH` (#15 thanks suntong) * __Prelude data__: - It is now possible to override predefined data within the prelude. This should allow the end user to recover from a buggy implementation in the pre defined variables declaration. * __TOC__: - #16 Improve link generator to handle `[]|',` - Multiple fixes to properly render the TOC level of each header. * __Template__: added multiple new functions to help to work with templates - __set__(name string, x interface{}): Save given value `x` as `name` on dot `.`. - __link__(url string, text ...string) string: Prints markdown link. - __img__(url string, alt ...string) string: Prints markdown image. - __concat__(x ...string) string: Concat given arguments. - __pathjoin__(x ...string) string: Join given arguments with `/`. * __dev__: - added small test suites into `test.sh` - mh-cbon - suntong -- mh-cbon ; Sat, 06 May 2017 09:09:10 +0200 0.0.10-beta * CLI: - new `init` command: Writes a basic `README.e.md` frile to get started - `gen`: removed useless confirmation message on successful operation. * Predefined data: - New api is introduced to better detect predefined data. * Prelude data: - It is now possible to override predefined data within the prelude. This should allow the end user to recover from a buggy implementation in the pre defined variables declaration. * TOC: - #16 Improve link generator to handle `[]|',` - Multiple fixes to properly render the TOC level of each header. * Template: added multiple new functions to help to work with templates - __set__(name string, x interface{}): Save given value `x` as `name` on dot `.`. - __link__(url string, text ...string) string: Prints markdown link. - __img__(url string, alt ...string) string: Prints markdown image. - __concat__(x ...string) string: Concat given arguments. - __pathjoin__(x ...string) string: Join given arguments with `/`. - mh-cbon -- mh-cbon ; Mon, 24 Apr 2017 14:54:07 +0200 0.0.9 * feature #10: Emd file can define a prelude block of `yaml` data to inject into the template processing. * cli fix: Before the -in argument was mandatory. It was not possible to use the default template. * feature installer: Fixed apt/rpm repositories. * feature #8: ensure an errored command line execution displays correctly. * feature: added new template functions - __yaml__(file string, keypaths ...string): parses and build new yaml content of given file. - __preline__(pre , content string): prepends pre for every lines of content. - __echo__(s ...string): echo every string s. - __read__(file string): returns file content. - __cat__(file string): to display the file content. - __exec__(bin string, args ...string): to exec a program. - __shell__(s string): to exec a command line on the underlying shell (it is not cross compatible). - __color__(color string, content string): to embed content in a block code with color. - __gotest__(rpkg string, run string, args ...string): exec `go test -v -run `. - __toc__(maximportance string, title string): display a TOC. * feature: added new badge templates - __license/shields__: show a license badge - __badge/codeship__: show a codeship badge * __deprecation__ #7: some template functions were deprecated to avoid pre defined formatting, old behavior can be reset via new options defined into the prelude data. See also the new __color__ function. - __file__ is dprecated for __cat__ - __cli__ is dprecated for __exec__ * badges fix #14: removed useless whitespace * dev: Added support for glide, it was required to handle yaml. * dev: updated tests * dev: godoc documentation improvements. - suntong - mh-cbon -- mh-cbon ; Sat, 22 Apr 2017 10:51:03 +0200 0.0.9-beta9 * fix default reading of the md file - mh-cbon -- mh-cbon ; Tue, 18 Apr 2017 10:51:03 +0200 0.0.9-beta8 * fix #15: properly handle symbolic links * fix cli: it was not possible to use the default template - mh-cbon -- mh-cbon ; Tue, 18 Apr 2017 10:46:56 +0200 0.0.9-beta7 * fix wrong import path - mh-cbon -- mh-cbon ; Mon, 17 Apr 2017 16:35:09 +0200 0.0.9-beta6 * ci: fix scripts to add glide support - mh-cbon -- mh-cbon ; Mon, 17 Apr 2017 16:26:18 +0200 0.0.9-beta5 * new functions: - __yaml__(file string, keypaths ...string): parses and build new yaml content of given file. - __preline__(pre , content string): prepends pre for every lines of content. - __echo__(s ...string): echo every string s. - __read__(file string): returns file content. * toc: multiple fixes, - it properly handles duplicated title by appending an increment - fix handling of !; in links generator - fix line counting when extracting markdown titles - fix md title selection starting at line N * prelude: - fix read of quoted values - prelude data is now read on all templates added, not only file - fix last eol handling * codeship fix #2: proper project url * bump script: added new utils/ tests * glide: init versionned dependencies to handle yaml files. * godoc: refactoring to improve documentation - mh-cbon -- mh-cbon ; Mon, 17 Apr 2017 16:09:41 +0200 0.0.9-beta4 * toc: improve toc parser, refactored, added tests - mh-cbon -- mh-cbon ; Fri, 14 Apr 2017 15:15:52 +0200 0.0.9-beta3 * fix #13: add new template to show a license badge. * prelude: trim leading whitespaces of unquoted values. * fix #14: improved badge output, removed useless whitespace. * fix #2: codeship badge template, added a CsProjectID parameter. * exec/shell/cat/gotest: avoid pre defined formatting, old behavior can be reset via new options defined into the prelude data. * toc: fixed some corner cases while parsing/generating the TOC. - mh-cbon -- mh-cbon ; Fri, 14 Apr 2017 11:58:55 +0200 0.0.9-beta2 * fix some bugs in TOC title evaluation and generation * fix apt repository! - mh-cbon -- mh-cbon ; Thu, 13 Apr 2017 15:09:44 +0200 0.0.9-beta1 * deprecation: improve error messages - mh-cbon -- mh-cbon ; Wed, 12 Apr 2017 17:15:39 +0200 0.0.9-beta * close #10: added feature to read, decode and registers the prelude data It is now possible to define a prelude block of `yaml` data in your __README__ file to register new data. * added __cat/exec/shell/color/gotest/toc__ func - __cat__(file string): to display the file content. - __exec__(bin string, args ...string): to exec a program. - __shell__(s string): to exec a command line on the underlying shell (it is not cross compatible). - __color__(color string, content string): to embed content in a block code with color. - __gotest__(rpkg string, run string, args ...string): exec `go test -v -run `. - __toc__(maximportance string, title string): display a TOC. * close #7: deprecated __file/cli__ func Those two functions are deprecated in flavor of their new equivalents, __cat/exec__. The new functions does not returns a triple backquuotes block code. They returns the response body only. A new function helper __color__ is a added to create a block code. * close #8: improved cli error output Before the output error was not displaying the command line entirely when it was too long. Now the error is updated to always display the command line with full length. * close #9: add new gotest helper func * close #12: add toc func * close #10: ensure unquoted strings are read properly * close #11: add shell func helper. - mh-cbon -- mh-cbon ; Wed, 12 Apr 2017 14:36:51 +0200 0.0.8 * fix goreport badge template - mh-cbon -- mh-cbon ; Sun, 12 Mar 2017 01:28:04 +0100 0.0.7 * improve template documentation * goreport: add template (fixes #4) - mh-cbon -- mh-cbon ; Sun, 12 Mar 2017 01:23:58 +0100 0.0.6 * template functions (std): add a new render template function to define additional values (fixes #2) * template function (std): file takes a new argument to define the colorizer (fixes #1) * emd: add new methods to access template, out and data * release: fix missing version to the emd build * README: multiple improvements. - mh-cbon -- mh-cbon ; Mon, 06 Mar 2017 19:18:04 +0100 0.0.5 * badges: add codeship * Funcs cli/file: changed the MD template to add support for html anchors (before they was using bold tag, now they use a title tag) * command gen: prints success message only if out is not stdout * README: added a section to show HTML generation, and a recipe to bump the package. * release: change bump script format - mh-cbon -- mh-cbon ; Mon, 06 Mar 2017 15:20:40 +0100 0.0.4 * changelog: typos * README: add template helpers documentation - mh-cbon -- mh-cbon ; Wed, 22 Feb 2017 22:18:19 +0100 0.0.3 * travis(token): update ghtoken - mh-cbon -- mh-cbon ; Wed, 22 Feb 2017 22:05:07 +0100 0.0.2 * README: fix appveyor badge * badge(update): fix url * README: fix appveyor badge * badge(fix): fix appveyor badge * README: add appveyor badge * badge(update): update text displayed in ci badges * README(fix): use correct bin path * bump(fix): emd gen command was wrong - mh-cbon -- mh-cbon ; Wed, 22 Feb 2017 21:26:29 +0100 0.0.1 * project initialization - mh-cbon -- mh-cbon ; Wed, 22 Feb 2017 21:07:17 +0100 emd-1.0.1/cli/000077500000000000000000000000001315430446100130265ustar00rootroot00000000000000emd-1.0.1/cli/cli.go000066400000000000000000000064221315430446100141300ustar00rootroot00000000000000// Package cli handles command line arguments. package cli import ( "flag" "fmt" "os" ) // NewProgram makes a new Program instance. func NewProgram(name string, version string) *Program { return &Program{map[string]Commander{}, name, version, false, false, false, false} } // NewCommand makes a new Program instance. func NewCommand(name string, desc string, fn func(s Commander) error) *Command { set := flag.NewFlagSet(name, flag.ExitOnError) set.SetOutput(os.Stdout) return &Command{name, desc, set, fn} } // Program is a struct to define a program and its command. type Program struct { commands map[string]Commander ProgramName string ProgramVersion string Help bool ShortHelp bool Version bool ShortVersion bool } // Bind help and version flag. func (p *Program) Bind() { flag.CommandLine.Init(p.ProgramName, flag.ExitOnError) flag.CommandLine.SetOutput(os.Stdout) flag.BoolVar(&p.ShortHelp, "h", false, "Show help") flag.BoolVar(&p.Help, "help", false, "Show help") flag.BoolVar(&p.Version, "version", false, "Show version") flag.BoolVar(&p.ShortVersion, "v", false, "Show version") } // Add a new sub command. func (p *Program) Add(c Commander) bool { p.commands[c.getName()] = c return true } // ShowVersion prints program name and version on stderr. func (p *Program) ShowVersion() error { fmt.Fprintf(os.Stdout, "%s - %v\n", p.ProgramName, p.ProgramVersion) return nil } // ShowUsage prints program usage of given subCmd on stderr. If subCmd is empty, prints general usage. func (p *Program) ShowUsage(subCmd string) error { if subCmd == "" { p.ShowVersion() fmt.Fprintln(os.Stdout, "\nUsage") flag.PrintDefaults() fmt.Fprintln(os.Stdout, "\nCommands") for name, c := range p.commands { fmt.Fprintf(os.Stderr, "\t%v\t%v\n", name, c.getDesc()) } return nil } if cmd := p.commands[subCmd]; cmd != nil { return p.ShowCmdUsage(cmd) } return fmt.Errorf("No such command %q", subCmd) } // ShowCmdUsage prints command usage of given subCmd on stderr. func (p *Program) ShowCmdUsage(cmd Commander) error { p.ShowVersion() fmt.Fprintf(os.Stdout, "\nCommand %q: %v\n", cmd.getName(), cmd.getDesc()) cmd.getSet().PrintDefaults() return nil } // Run the program against given set of arguments. func (p *Program) Run(args []string) error { if len(args) > 1 { if cmd, ok := p.commands[args[1]]; ok { if err := cmd.getSet().Parse(args[2:]); err != nil { return nil } } else { flag.Parse() } for name, cmd := range p.commands { if cmd.getSet().Parsed() { err := cmd.getFn()(cmd) if err != nil { err = fmt.Errorf("command %q failed: %v", name, err) } return err } } } if p.Version || p.ShortVersion { return p.ShowVersion() } return p.ShowUsage("") } // Commander is an generalizer of Command. type Commander interface { getDesc() string getName() string getSet() *flag.FlagSet getFn() func(s Commander) error } // Command describe a program sub command. type Command struct { name string desc string Set *flag.FlagSet fn func(s Commander) error } func (c *Command) getDesc() string { return c.desc } func (c *Command) getName() string { return c.name } func (c *Command) getSet() *flag.FlagSet { return c.Set } func (c *Command) getFn() func(s Commander) error { return c.fn } emd-1.0.1/deb.json000066400000000000000000000011011315430446100136750ustar00rootroot00000000000000{ "name": "emd", "maintainer": "mh-cbon ", "description": "Enhanced Markdown template processor", "changelog-cmd": "changelog debian --vars='{\"name\":\"!name!\"}'", "homepage": "http://github.com/mh-cbon/!name!", "files": [ { "from": "build/!arch!/!name!", "to": "/usr/bin", "base" : "build/!arch!/", "fperm": "0755" } ], "copyrights": [ { "files": "*", "copyright": "2016 mh-cbon ", "license": "MIT", "file": "LICENSE" } ] } emd-1.0.1/deprecated/000077500000000000000000000000001315430446100143575ustar00rootroot00000000000000emd-1.0.1/deprecated/emd.go000066400000000000000000000032221315430446100154520ustar00rootroot00000000000000// Package deprecated contains deprecated helpers. package deprecated import ( "fmt" "io/ioutil" "log" "os/exec" "path/filepath" "strings" "github.com/mh-cbon/emd/emd" ) // CliError is an error of cli command type CliError struct { Err error Cmd string } func (c *CliError) Error() string { return fmt.Sprintf("%v\n\nThe command was:\n%v", c.Err, c.Cmd) } // Register standard helpers to the generator. func Register(g *emd.Generator) error { // deprecated for cat g.AddFunc("file", func(f string, exts ...string) (string, error) { s, err := ioutil.ReadFile(f) if err != nil { return "", err } ext := filepath.Ext(f) ext = strings.TrimPrefix(ext, ".") if len(exts) > 0 { ext = exts[0] } log.Printf("file function is deprecated , please update to: {{cat %q | color %q}}", f, ext) res := ` ###### > ` + f + ` ` + "```" + ext + ` ` + strings.TrimSpace(string(s)) + ` ` + "```" return res, err }) // deprecated for exec g.AddFunc("cli", func(bin string, args ...string) (string, error) { d := "\"" + strings.Join(args, "\" \"") + "\"" log.Printf("cli function is deprecated , please update to: {{exec %q %v | color \"sh\"}}", bin, d) cmd := exec.Command(bin, args...) out, err := cmd.CombinedOutput() if err != nil { s := bin for _, a := range args { if strings.Index(a, "\"") > -1 { a = strings.Replace(a, "\"", "\\\"", -1) } s += fmt.Sprintf(" %v", a) } return "", &CliError{Err: err, Cmd: s} } fbin := filepath.Base(bin) res := ` ###### $ ` + fbin + ` ` + strings.Join(args, " ") + ` ` + "```sh" + ` ` + strings.TrimSpace(string(out)) + ` ` + "```" return res, err }) return nil } emd-1.0.1/emd/000077500000000000000000000000001315430446100130245ustar00rootroot00000000000000emd-1.0.1/emd/emd.go000066400000000000000000000063521315430446100141260ustar00rootroot00000000000000// Package emd provides support to process .md files. package emd import ( "bytes" "fmt" "io" "io/ioutil" "text/template" "github.com/mh-cbon/emd/utils" ) //Generator generates an emd content. type Generator struct { t *template.Template o io.Writer tpls []string funcs map[string]interface{} data map[string]interface{} post []func(string) string } // NewGenerator creates Generator Pointers. func NewGenerator() *Generator { return &Generator{ tpls: []string{}, funcs: map[string]interface{}{}, data: map[string]interface{}{}, } } //AddPostProcess registers a post process function. // Post process are registered by template func call and are removed after next template generation. func (g *Generator) AddPostProcess(f func(string) string) { g.post = append(g.post, f) } //AddFunc registers a template function. func (g *Generator) AddFunc(name string, f interface{}) { g.funcs[name] = f } //AddFuncs registers a map of template functions. func (g *Generator) AddFuncs(fm map[string]interface{}) { for name, f := range fm { g.funcs[name] = f } } //SetData registers a template data. func (g *Generator) SetData(name string, d interface{}) { g.data[name] = d } //SetDataMap registers a map of template data. func (g *Generator) SetDataMap(dm map[string]interface{}) { for name, d := range dm { g.data[name] = d } } //AddTemplate registers a template string. func (g *Generator) AddTemplate(t string) { // read the prelude newT, newData, err := utils.GetPrelude(t) if err != nil { panic(err) } g.SetDataMap(newData) g.tpls = append(g.tpls, newT) } //AddFileTemplate registers a template file. func (g *Generator) AddFileTemplate(t string) error { s, err := ioutil.ReadFile(t) if err != nil { return err } // add the template string. g.AddTemplate(string(s)) return nil } //GetTemplate returns the compiled templates. //It is available only during Execute. func (g *Generator) GetTemplate() *template.Template { return g.t } //GetOut returns the out writer. //It is available only during Execute. func (g *Generator) GetOut() io.Writer { return g.o } //WriteString writes a string on out. //It is available only during Execute. func (g *Generator) WriteString(s string) (int, error) { return g.o.Write([]byte(s)) } //GetData returns a copy of the template's data. //It is available only during Execute. func (g *Generator) GetData() map[string]interface{} { ret := map[string]interface{}{} for k, v := range g.data { ret[k] = v } return ret } //GetKey returns value of K. func (g *Generator) GetKey(K string) interface{} { return g.data[K] } //GetSKey returns a string value of K. func (g *Generator) GetSKey(K string) string { v := g.GetKey(K) if v == nil { return "" } return fmt.Sprintf("%v", g.GetKey(K)) } //Execute the template to out. func (g *Generator) Execute(out io.Writer) error { var b bytes.Buffer g.o = &b // becasue of post process, we need to buffer out. var err error g.t = template.New("").Funcs(g.funcs) for _, tpl := range g.tpls { g.t, err = g.t.Parse(tpl) if err != nil { return err } } err = g.t.Execute(g.o, g.data) g.t = nil g.o = nil s := b.String() b.Truncate(0) for _, p := range g.post { s = p(s) } g.post = g.post[:0] out.Write([]byte(s)) return err } emd-1.0.1/emd/emd_test.go000066400000000000000000000014051315430446100151570ustar00rootroot00000000000000package emd import ( "bytes" "strings" "testing" ) func TestVVV(t *testing.T) { gen := NewGenerator() gen.AddTemplate(`The result of the func: {{f "s"}} The result of the template: {{template "s" .}} The data: {{.}} `) gen.AddTemplate(`{{define "s"}}s template{{end}}`) gen.AddFunc("f", func(s string) string { return strings.ToUpper(s) }) gen.SetData("the", "data") gen.AddPostProcess(func(s string) string { return s + "\npostprocess" }) var buf bytes.Buffer gen.Execute(&buf) expectedOut := `The result of the func: S The result of the template: s template The data: map[the:data] postprocess` gotOut := buf.String() if expectedOut != gotOut { t.Errorf( "Unexpected result\n==== expected\n%q\n==== got\n%v", expectedOut, gotOut, ) } } emd-1.0.1/glide.lock000066400000000000000000000003321315430446100142130ustar00rootroot00000000000000hash: d8b138bdb5a5e0c112e455dbaadb27b60defda234fa7cb2da858c734a15b0118 updated: 2017-05-08T14:18:10.415313664+02:00 imports: - name: gopkg.in/yaml.v2 version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b testImports: [] emd-1.0.1/glide.yaml000066400000000000000000000001041315430446100142220ustar00rootroot00000000000000package: github.com/mh-cbon/emd import: - package: gopkg.in/yaml.v2 emd-1.0.1/go-nonstd/000077500000000000000000000000001315430446100141675ustar00rootroot00000000000000emd-1.0.1/go-nonstd/emd.go000066400000000000000000000010701315430446100152610ustar00rootroot00000000000000// Package gononstd contains go non-standard helpers. package gononstd import "github.com/mh-cbon/emd/emd" // InstructionGlideInstall is a template to show instructions to install the package with glide. var InstructionGlideInstall = `{{define "glide/install" -}} ` + "```sh" + ` mkdir -p $GOPATH/src/{{.URL}} cd $GOPATH/src/{{.URL}} git clone https://{{.URL}}.git . glide install go install ` + "```" + ` {{- end}}` // Register go non-standard helpers to the generator. func Register(g *emd.Generator) error { g.AddTemplate(InstructionGlideInstall) return nil } emd-1.0.1/go/000077500000000000000000000000001315430446100126645ustar00rootroot00000000000000emd-1.0.1/go/emd.go000066400000000000000000000056051315430446100137660ustar00rootroot00000000000000// Package gostd contains go standard helpers. package gostd import ( "fmt" "go/parser" "go/token" "os" "path/filepath" "strings" "github.com/mh-cbon/emd/emd" "github.com/mh-cbon/emd/utils" ) // PkgDoc Reads the first of the files, or `main.go`, lookup for its package comment and returns it as plain text. func PkgDoc(files ...string) (string, error) { file := "main.go" if len(files) > 0 { file = files[0] } if _, err := os.Stat(file); len(files) == 0 && os.IsNotExist(err) { return "", nil } fset := token.NewFileSet() f, err := parser.ParseFile(fset, file, nil, parser.ParseComments) if err != nil { return "", fmt.Errorf("Failed to parse input file: %v", err) } if f.Comments == nil || len(f.Comments) == 0 { return "Go package documentation not found!", nil } return f.Comments[0].Text(), nil } // GoTest Reads the first of the files, or `main.go`, lookup for its package comment and returns it as plain text. func GoTest(g *emd.Generator) func(string, string, ...string) (string, error) { return func(rpkg, run string, args ...string) (string, error) { if rpkg != "" { if _, err := os.Stat(rpkg); !os.IsNotExist(err) { rpkg, err = filepath.Abs(rpkg) if err != nil { return "", err } GOPATH := filepath.Join(os.Getenv("GOPATH"), "src") rpkg = strings.Replace(rpkg, GOPATH, "", -1) rpkg = strings.Replace(rpkg, "\\", "/", -1) // windows.. } } nargs := []string{"test", "-v"} if rpkg != "" { nargs = append(nargs, rpkg[1:]) // rm front / } if run != "" { nargs = append(nargs, []string{"-run", run}...) } nargs = append(nargs, args...) out, err := utils.Exec("go", nargs) if err != nil { return "", err } s := utils.GetCmdStr("go", nargs) pre := g.GetSKey("emd_gotest_pre") _, err = g.WriteString(pre + s + "\n") return strings.TrimSpace(string(out)), err } } // InstructionGoGetInstall is a template to show instructions to install the package with go get. var InstructionGoGetInstall = `{{define "go/install" -}} ` + "```sh" + ` go get {{.ProviderURL}}/{{.User}}/{{.Name}} ` + "```" + ` {{- end}}` // BadgeGoDoc is a template to show a godoc badge. var BadgeGoDoc = `{{define "badge/godoc" -}} [!` + `[GoDoc]` + `(https://godoc.org/{{.ProviderURL}}/{{.User}}/{{.Name}}?status.svg)` + `]` + `(http://godoc.org/{{.ProviderURL}}/{{.User}}/{{.Name}}) {{- end}}` // BadgeGoReport is a template to show a goreport badge. var BadgeGoReport = `{{define "badge/goreport" -}} [!` + `[Go Report Card]` + `(https://goreportcard.com/badge/{{.ProviderURL}}/{{.User}}/{{.Name}})` + `]` + `(https://goreportcard.com/report/{{.ProviderURL}}/{{.User}}/{{.Name}}) {{- end}}` // Register go standard helpers to the generator. func Register(g *emd.Generator) error { g.AddFunc("pkgdoc", PkgDoc) g.AddFunc("gotest", GoTest(g)) g.AddTemplate(InstructionGoGetInstall) g.AddTemplate(BadgeGoDoc) g.AddTemplate(BadgeGoReport) return nil } emd-1.0.1/main.go000066400000000000000000000140071315430446100135340ustar00rootroot00000000000000// Enhanced Markdown template processor. package main import ( "bytes" "encoding/json" "fmt" "io" "io/ioutil" "log" "os" "path/filepath" "regexp" "time" "github.com/mh-cbon/emd/cli" "github.com/mh-cbon/emd/deprecated" "github.com/mh-cbon/emd/emd" gostd "github.com/mh-cbon/emd/go" gononstd "github.com/mh-cbon/emd/go-nonstd" "github.com/mh-cbon/emd/provider" "github.com/mh-cbon/emd/std" ) // VERSION defines the running build id. var VERSION = "0.0.0" var program = cli.NewProgram("emd", VERSION) var verbose bool func logMsg(f string, args ...interface{}) { if verbose { log.Printf(f+"\n", args...) } } func main() { program.Bind() if err := program.Run(os.Args); err != nil { log.Println(err) os.Exit(1) } } // gen sub command type gencommand struct { *cli.Command in string out string data string help bool shortHelp bool } // init sub command type initcommand struct { *cli.Command help bool shortHelp bool out string force bool } func init() { gen := &gencommand{Command: cli.NewCommand("gen", "Process an emd file.", Generate)} gen.Set.StringVar(&gen.in, "in", "", "Input src file") gen.Set.StringVar(&gen.out, "out", "-", "Output destination, defaults to stdout") gen.Set.StringVar(&gen.data, "data", "", "JSON map of data") gen.Set.BoolVar(&gen.help, "help", false, "Show help") gen.Set.BoolVar(&gen.shortHelp, "h", false, "Show help") program.Add(gen) ini := &initcommand{Command: cli.NewCommand("init", "Init a basic emd file.", InitFile)} ini.Set.BoolVar(&ini.help, "help", false, "Show help") ini.Set.BoolVar(&ini.shortHelp, "h", false, "Show help") ini.Set.BoolVar(&ini.force, "force", false, "Force write") ini.Set.StringVar(&ini.out, "out", "README.e.md", "Out file") program.Add(ini) verbose = os.Getenv("VERBOSE") != "" } // Generate is the cli command implementation of gen. func Generate(s cli.Commander) error { cmd, ok := s.(*gencommand) if ok == false { return fmt.Errorf("Invalid command type %T", s) } if cmd.help || cmd.shortHelp { return program.ShowCmdUsage(cmd) } out, err := getStdout(cmd.out) if err != nil { return err } if x, ok := out.(io.Closer); ok { defer x.Close() } projectPath, err := getProjectPath() if err != nil { return err } logMsg("projectPath %q", projectPath) plugins := getPlugins() data, err := getData(projectPath) if err != nil { return err } gen := emd.NewGenerator() gen.SetDataMap(data) if cmd.in != "" { if err := gen.AddFileTemplate(cmd.in); err != nil { return err } } else { b := tryReadOsStdin() if b != nil && b.Len() > 0 { gen.AddTemplate(b.String()) } else { if s, err := os.Stat("README.e.md"); !os.IsNotExist(err) && s.IsDir() == false { err := gen.AddFileTemplate("README.e.md") if err != nil { return err } } else { gen.AddTemplate(defTemplate) } } } for name, plugin := range plugins { if err := plugin(gen); err != nil { return fmt.Errorf("Failed to register %v package: %v", name, err) } } if cmd.data != "" { jData := map[string]interface{}{} if err := json.Unmarshal([]byte(cmd.data), &jData); err != nil { return fmt.Errorf("Cannot decode JSON data string: %v", err) } gen.SetDataMap(jData) } if err := gen.Execute(out); err != nil { return fmt.Errorf("Generator failed: %v", err) } return nil } func tryReadOsStdin() *bytes.Buffer { copied := make(chan bool) timedout := make(chan bool) var ret bytes.Buffer go func() { io.Copy(&ret, os.Stdin) copied <- true }() go func() { <-time.After(time.Millisecond * 10) timedout <- ret.Len() == 0 }() select { case empty := <-timedout: if empty { return nil } <-copied case <-copied: } return &ret } func getProjectPath() (string, error) { originalCwd, err := os.Getwd() if err != nil { return "", err } logMsg("cwd %q", originalCwd) // regular go package { projectPath, err := matchProjectPath(originalCwd) if err == nil { return projectPath, nil } } // symlinked go package { cwd, err := filepath.EvalSymlinks(originalCwd) if err == nil { projectPath, err := matchProjectPath(cwd) if err == nil { return projectPath, nil } } } // all other cases return originalCwd, nil } var re = regexp.MustCompile("(src/[^/]+[.](com|org|net)/.+)") func matchProjectPath(p string) (string, error) { res := re.FindAllString(p, -1) if len(res) > 0 { return res[0][3:], nil } return "", fmt.Errorf("Invalid working directory %q", p) } func getData(cwd string) (map[string]interface{}, error) { p := provider.Default(cwd) return map[string]interface{}{ "Name": p.GetProjectName(), "User": p.GetUserName(), "ProviderURL": p.GetProviderURL(), "ProviderName": p.GetProviderID(), "URL": p.GetURL(), "ProjectURL": p.GetProjectURL(), "Branch": "master", }, nil } func getPlugins() map[string]func(*emd.Generator) error { return map[string]func(*emd.Generator) error{ "std": std.Register, "gostd": gostd.Register, "gononstd": gononstd.Register, "deprecated": deprecated.Register, } } func getStdout(out string) (io.Writer, error) { ret := os.Stdout if out != "-" { f, err := os.Create(out) if err != nil { f, err = os.Open(out) if err != nil { return nil, fmt.Errorf("Cannot open out destination: %v", err) } } ret = f } return ret, nil } // InitFile creates a basic emd file if none exists. func InitFile(s cli.Commander) error { cmd, ok := s.(*initcommand) if ok == false { return fmt.Errorf("Invalid command type %T", s) } if cmd.help || cmd.shortHelp { return program.ShowCmdUsage(cmd) } out := cmd.out if cmd.out == "" { out = "README.e.md" } if _, err := os.Stat(out); !cmd.force && !os.IsNotExist(err) { return fmt.Errorf("File exists at %q", out) } return ioutil.WriteFile(out, []byte(defTemplate), os.ModePerm) } var defTemplate = `# {{.Name}} {{template "badge/goreport" .}} {{template "badge/godoc" .}} {{pkgdoc}} # {{toc 5}} # Install {{template "gh/releases" .}} #### go {{template "go/install" .}} ` emd-1.0.1/main_test.go000066400000000000000000000012361315430446100145730ustar00rootroot00000000000000package main_test import ( "os" "github.com/mh-cbon/emd/emd" "github.com/mh-cbon/emd/std" ) var projectName = "dummy" // ExampleGenerate demonstrates the generation // of the given README.e.md source file // to os.Stdout. func Example() { // make a new instance of emd.Generator. gen := emd.NewGenerator() // set the main template. gen.AddTemplate("{{.Name}}") // set the data available in templates. gen.SetDataMap(map[string]interface{}{"Name": projectName}) // register a plugin if err := std.Register(gen); err != nil { panic(err) } // process the template. if err := gen.Execute(os.Stdout); err != nil { panic(err) } // Output: dummy } emd-1.0.1/provider/000077500000000000000000000000001315430446100141115ustar00rootroot00000000000000emd-1.0.1/provider/provider.go000066400000000000000000000060431315430446100162750ustar00rootroot00000000000000package provider import ( "github.com/mh-cbon/emd/provider/std" ) //Provider identify an url. type Provider interface { Is(string) bool SetURL(string) GetUserName() string GetProjectName() string GetProjectPath() string GetProviderURL() string GetProviderID() string GetURL() string GetProjectURL() string } // Providers if a facade of many Provider. type Providers struct { URL string Providers []Provider } // New providers for url. func New(url string) Providers { return Providers{URL: url} } // Default makes a new Providers facade with pre loaded gh provider. func Default(url string) Providers { return New(url).Add(std.New()) } // Add a concrete provider. func (p Providers) Add(provider ...Provider) Providers { p.Providers = append(p.Providers, provider...) return p } // Match tells if an url matches a provider. func (p Providers) Match() bool { for _, pp := range p.Providers { if pp.Is(p.URL) { return true } } return false } func (p Providers) selectProvider() Provider { ret := &NotFoundProvider{} for _, pp := range p.Providers { if pp.Is(p.URL) { pp.SetURL(p.URL) return pp } } return ret } // GetUserName of the the current url. func (p Providers) GetUserName() string { return p.selectProvider().GetUserName() } // GetProjectName of the the current url. func (p Providers) GetProjectName() string { return p.selectProvider().GetProjectName() } // GetProviderURL of the the current url. func (p Providers) GetProviderURL() string { return p.selectProvider().GetProviderURL() } // GetProviderID of the the current url. func (p Providers) GetProviderID() string { return p.selectProvider().GetProviderID() } // GetProjectPath of the the current url. func (p Providers) GetProjectPath() string { return p.selectProvider().GetProjectPath() } // GetURL of the the current url. func (p Providers) GetURL() string { return p.selectProvider().GetURL() } // GetProjectURL of the the current url. func (p Providers) GetProjectURL() string { return p.selectProvider().GetProjectURL() } // NotFoundProvider for an url not identified type NotFoundProvider struct{} var notFound = "not found" // Is always return false. func (p *NotFoundProvider) Is(u string) bool { return false } // SetURL si no op. func (p *NotFoundProvider) SetURL(u string) { } // GetUserName of the the current url. func (p *NotFoundProvider) GetUserName() string { return notFound } // GetProjectName of the the current url. func (p *NotFoundProvider) GetProjectName() string { return notFound } // GetProviderURL of the the current url. func (p *NotFoundProvider) GetProviderURL() string { return notFound } // GetProviderID of the the current url. func (p *NotFoundProvider) GetProviderID() string { return notFound } // GetProjectPath of the the current url. func (p *NotFoundProvider) GetProjectPath() string { return notFound } // GetProjectURL of the the current url. func (p *NotFoundProvider) GetProjectURL() string { return notFound } // GetURL of the the current url. func (p *NotFoundProvider) GetURL() string { return notFound } emd-1.0.1/provider/std/000077500000000000000000000000001315430446100147035ustar00rootroot00000000000000emd-1.0.1/provider/std/provider.go000066400000000000000000000043301315430446100170640ustar00rootroot00000000000000package std import ( "regexp" "strings" ) var re = regexp.MustCompile("^([^/]+)[.](com|org|net)/.*") // Provider detects GH url type Provider struct { URL string providerURL string providerID string } // New provider to work with url func New() *Provider { return &Provider{} } // Is the current url about gh? func (p *Provider) Is(url string) bool { x := cleanURL(url) return re.MatchString(x) } // SetURL of the provider func (p *Provider) SetURL(url string) { p.URL = cleanURL(url) parts := strings.Split(p.URL, "/") p.providerURL = parts[0] parts2 := re.FindAllStringSubmatch(p.URL, -1) if len(parts2) > 0 { p.providerID = parts2[0][1] } } func cleanURL(url string) string { if url[:4] == "http" { url = url[4:] } else if url[:5] == "https" { url = url[5:] } if url[:3] == "://" { url = url[3:] } if url[:1] == "/" { url = url[1:] } return url } // GetUserName of the the current url. func (p *Provider) GetUserName() string { ss := strings.Split(p.URL, "/") if len(ss) > 1 { return ss[1] } return "" } // GetProjectName of the the current url. func (p *Provider) GetProjectName() string { ss := strings.Split(p.URL, "/") if len(ss) > 2 { return ss[2] } return "" } // GetProjectPath of the the current url. func (p *Provider) GetProjectPath() string { ss := strings.Split(p.URL, "/") if len(ss) > 3 { return "/" + strings.Join(ss[3:], "/") } return "" } // GetProjectURL of the the current url. func (p *Provider) GetProjectURL() string { ret := []string{} if x := p.GetProviderURL(); x != "" { if y := p.GetUserName(); y != "" { if z := p.GetProjectName(); z != "" { ret = append(ret, x) ret = append(ret, y) ret = append(ret, z) } } } return strings.Join(ret, "/") } // GetURL of the the current url. func (p *Provider) GetURL() string { ret := []string{} if x := p.GetProjectURL(); x != "" { ret = append(ret, x) if y := p.GetProjectPath(); y != "" { ret = append(ret, y[1:]) //rm front / } } return strings.Join(ret, "/") } // GetProviderURL of the the current url. func (p *Provider) GetProviderURL() string { return p.providerURL } // GetProviderID of the the current url. func (p *Provider) GetProviderID() string { return p.providerID } emd-1.0.1/provider/std/provider_test.go000066400000000000000000000115031315430446100201230ustar00rootroot00000000000000package std import ( "testing" ) func TestIs(t *testing.T) { data := []string{ "http://github.com/", } p := New() want := true for i, url := range data { got := p.Is(url) if got != want { t.Errorf("At %v want: %v got %v in %q", i, want, got, url) } } } func TestIsNot(t *testing.T) { data := []string{ "qsdsqdsqdqs", } p := New() want := false for i, url := range data { got := p.Is(url) if got != want { t.Errorf("At %v want: %v got %v in %q", i, want, got, url) } } } func TestGetUserName(t *testing.T) { data := map[string]string{ "http://github.com/": "", "http://github.com/mh-cbon": "mh-cbon", "http://github.com/mh-cbon/emd": "mh-cbon", "http://github.com/mh-cbon/emd/cmd": "mh-cbon", "github.com/mh-cbon": "mh-cbon", "github.com/mh-cbon/emd": "mh-cbon", "github.com/mh-cbon/emd/cmd": "mh-cbon", "/github.com/mh-cbon": "mh-cbon", "/github.com/mh-cbon/emd": "mh-cbon", "/github.com/mh-cbon/emd/cmd": "mh-cbon", } p := New() for url, want := range data { p.SetURL(url) got := p.GetUserName() if got != want { t.Errorf("Want: %q got %q in %q", want, got, url) } } } func TestGetProjectName(t *testing.T) { data := map[string]string{ "http://github.com/": "", "http://github.com/mh-cbon": "", "http://github.com/mh-cbon/emd": "emd", "http://github.com/mh-cbon/emd/cmd": "emd", "github.com/mh-cbon": "", "github.com/mh-cbon/emd": "emd", "github.com/mh-cbon/emd/cmd": "emd", "/github.com/mh-cbon": "", "/github.com/mh-cbon/emd": "emd", "/github.com/mh-cbon/emd/cmd": "emd", } p := New() for url, want := range data { p.SetURL(url) got := p.GetProjectName() if got != want { t.Errorf("Want: %q got %q in %q", want, got, url) } } } func TestGetProjectPath(t *testing.T) { data := map[string]string{ "http://github.com/": "", "http://github.com/mh-cbon": "", "http://github.com/mh-cbon/emd": "", "http://github.com/mh-cbon/emd/cmd": "/cmd", "github.com/mh-cbon": "", "github.com/mh-cbon/emd": "", "github.com/mh-cbon/emd/cmd": "/cmd", "/github.com/mh-cbon": "", "/github.com/mh-cbon/emd": "", "/github.com/mh-cbon/emd/cmd": "/cmd", } p := New() for url, want := range data { p.SetURL(url) got := p.GetProjectPath() if got != want { t.Errorf("Want: %q got %q in %q", want, got, url) } } } func TestGetProjectURL(t *testing.T) { data := map[string]string{ "http://github.com/": "", "http://github.com/mh-cbon": "", "http://github.com/mh-cbon/emd": "github.com/mh-cbon/emd", "http://github.com/mh-cbon/emd/cmd": "github.com/mh-cbon/emd", "github.com/mh-cbon": "", "github.com/mh-cbon/emd": "github.com/mh-cbon/emd", "github.com/mh-cbon/emd/cmd": "github.com/mh-cbon/emd", "/github.com/mh-cbon": "", "/github.com/mh-cbon/emd": "github.com/mh-cbon/emd", "/github.com/mh-cbon/emd/cmd": "github.com/mh-cbon/emd", } p := New() for url, want := range data { p.SetURL(url) got := p.GetProjectURL() if got != want { t.Errorf("Want: %q got %q in %q", want, got, url) } } } func TestGetProviderID(t *testing.T) { data := map[string]string{ "http://github.com/": "github", "http://github.com/mh-cbon": "github", "http://github.com/mh-cbon/emd": "github", "http://github.com/mh-cbon/emd/cmd": "github", "github.com/mh-cbon": "github", "github.com/mh-cbon/emd": "github", "github.com/mh-cbon/emd/cmd": "github", "/github.com/mh-cbon": "github", "/github.com/mh-cbon/emd": "github", "/github.com/mh-cbon/emd/cmd": "github", } p := New() for url, want := range data { p.SetURL(url) got := p.GetProviderID() if got != want { t.Errorf("Want: %q got %q in %q", want, got, url) } } } func TestGetURL(t *testing.T) { data := map[string]string{ "http://github.com/": "", "http://github.com/mh-cbon": "", "http://github.com/mh-cbon/emd": "github.com/mh-cbon/emd", "http://github.com/mh-cbon/emd/cmd": "github.com/mh-cbon/emd/cmd", "github.com/mh-cbon": "", "github.com/mh-cbon/emd": "github.com/mh-cbon/emd", "github.com/mh-cbon/emd/cmd": "github.com/mh-cbon/emd/cmd", "/github.com/mh-cbon": "", "/github.com/mh-cbon/emd": "github.com/mh-cbon/emd", "/github.com/mh-cbon/emd/cmd": "github.com/mh-cbon/emd/cmd", } p := New() for url, want := range data { p.SetURL(url) got := p.GetURL() if got != want { t.Errorf("Want: %q got %q in %q", want, got, url) } } } emd-1.0.1/rpm.json000066400000000000000000000005721315430446100137540ustar00rootroot00000000000000{ "name": "emd", "summary": "Enhanced Markdown template processor", "description": "Enhanced Markdown template processor", "changelog-cmd": "changelog rpm", "license": "LICENSE", "url": "https://github.com/mh-cbon/!name!", "files": [ { "from": "build/!arch!/!name!", "to": "%{_bindir}/", "base": "build/!arch!/", "type": "" } ] } emd-1.0.1/std/000077500000000000000000000000001315430446100130515ustar00rootroot00000000000000emd-1.0.1/std/emd.go000066400000000000000000000270131315430446100141500ustar00rootroot00000000000000// Package std contains standard helpers. package std import ( "fmt" "io/ioutil" "log" "strings" yaml "gopkg.in/yaml.v2" "github.com/mh-cbon/emd/emd" "github.com/mh-cbon/emd/utils" ) // Concat multiple strings. func Concat(s ...interface{}) string { ss := []string{} for _, v := range s { ss = append(ss, fmt.Sprintf("%v", v)) } return strings.Join(ss, "") } // PathJoin multiple path parts. func PathJoin(s ...interface{}) string { ss := []string{} for _, v := range s { ss = append(ss, fmt.Sprintf("%v", v)) } return strings.Join(ss, "/") } // Link creates a link according to markdown syntax. func Link(url interface{}, texts ...interface{}) string { var text interface{} text = "" if len(texts) > 0 { text = texts[0] } if text == "" { return fmt.Sprintf("%v", url) } return fmt.Sprintf("[%v](%v)", text, url) } // Img creates a img according to markdown syntax. func Img(url interface{}, alts ...interface{}) string { var alt interface{} alt = "" if len(alts) > 0 { alt = alts[0] } return fmt.Sprintf("![%v](%v)", alt, url) } // SetValue saves a value. func SetValue(g *emd.Generator) func(string, interface{}) string { return func(name string, v interface{}) string { g.SetData(name, v) return "" } } // GetValue returns a value. func GetValue(g *emd.Generator) func(string) interface{} { return func(name string) interface{} { return g.GetKey(name) } } // Cat displays a file header, returns file body. func Cat(g *emd.Generator) func(string) (string, error) { return func(f string) (string, error) { s, err := Read(f) if err != nil { return "", err } pre := g.GetSKey("emd_cat_pre") _, err = g.WriteString(pre + f + "\n") return strings.TrimSpace(string(s)), err } } // Read returns file body. func Read(f string) (string, error) { s, err := ioutil.ReadFile(f) if err != nil { return "", err } return strings.TrimSpace(string(s)), err } // makeMapOf given arguments. func makeMapOf(keyValuesMap ...interface{}) (map[string]interface{}, error) { ret := map[string]interface{}{} if len(keyValuesMap) > 0 { if len(keyValuesMap)%2 != 0 { return ret, fmt.Errorf("Incorrect arguments number in call to render template function, args are: %#v", keyValuesMap) } for i := 0; i < len(keyValuesMap); i += 2 { key, ok := keyValuesMap[i].(string) if ok == false { return ret, fmt.Errorf("Incorrect key type %T of arg %#v in call to render template function, expected a string, args are: %#v", keyValuesMap[i], keyValuesMap[i], keyValuesMap) } ret[key] = keyValuesMap[i+1] } } return ret, nil } // Render renders template wih given name, and map arguments to its data argument. func Render(g *emd.Generator) func(string, map[string]interface{}, ...interface{}) (string, error) { return func(name string, data map[string]interface{}, keyValuesMap ...interface{}) (string, error) { extraData := map[string]interface{}{} for k, v := range data { extraData[k] = v } y, err := makeMapOf(keyValuesMap...) if err != nil { return "", err } for k, v := range y { extraData[k] = v } return "", g.GetTemplate().ExecuteTemplate(g.GetOut(), name, extraData) } } // Exec display a program invokation header, returns its output. func Exec(g *emd.Generator) func(string, ...string) (string, error) { return func(bin string, args ...string) (string, error) { out, err := utils.Exec(bin, args) if err != nil { return "", err } f := utils.GetCmdStr(bin, args) pre := g.GetSKey("emd_exec_pre") _, err = g.WriteString(pre + f + "\n") return strings.TrimSpace(out), err } } // Shell display a cli invokation header, returns the cli output. func Shell(g *emd.Generator) func(string) (string, error) { return func(s string) (string, error) { out, err := utils.Shell("", s) if err != nil { return "", err } pre := g.GetSKey("emd_shell_pre") _, err = g.WriteString(pre + s + "\n") return strings.TrimSpace(string(out)), err } } // Color embeds a text block with markdown triple backquotes syntax makrup. func Color(syntax, content string) string { if content == "" && syntax != "" { content = syntax syntax = "sh" // set the default color } return fmt.Sprintf("```%v\n%v\n```", syntax, content) } // Yaml parses given file as yaml, locate given path, build a new map, yaml encode it, returns its string. func Yaml(file string, paths ...string) (string, error) { s, err := ioutil.ReadFile(file) if err != nil { return "", err } m := yaml.MapSlice{} err = yaml.Unmarshal(s, &m) if err != nil { return "", err } res := yaml.MapSlice{} if len(paths) > 0 { // make it more complex later for _, p := range paths { for _, k := range m { if k.Key.(string) == p { res = append(res, k) } } } } else { res = m } var d []byte d, err = yaml.Marshal(&res) if err != nil { return "", err } return strings.TrimSpace(string(d)), nil } // Preline prepends every line of content with pre. func Preline(pre, content string) string { res := "" for _, c := range content { res += string(c) if c == '\n' { res += pre } } if res != "" { res = pre + res } return res } // Echo prints given strings. func Echo(content ...string) string { return strings.Join(content, " ") } var replaceIndex = 0 // Toc generates and prints a TOC. func Toc(g *emd.Generator) func(int, ...string) string { return func(depth int, toctitles ...string) string { toctitle := "TOC" if len(toctitles) > 0 { toctitle = toctitles[0] } replaceToken := fmt.Sprintf("%v%v", "REPLACETOKENGOESHERE", replaceIndex) replaceIndex++ g.AddPostProcess(func(s string) string { // a quick and dirty md parser of titles (###) and block (```) lineIndex := utils.LineIndex(s, replaceToken) if lineIndex > -1 { lines := strings.Split(s, "\n") titles := utils.GetAllMdTitles(s) x := titles[:0] for _, t := range titles { if t.Line > lineIndex { x = append(x, t) } } root := utils.MakeTitleTree(x) toc := "" e := -1 lastPower := -1 root.Traverse(utils.PowerLess(5, func(n *utils.MdTitleTree) { if n.Power < 2 { e = 0 } else if lastPower < n.Power { e++ } else if lastPower > n.Power { e-- } if e < 0 { e = 0 } lastPower = n.Power link := utils.GetMdLinkHash(n.Title) if n.Duplicate > -1 { link += fmt.Sprintf("-%v", n.Duplicate) } x := strings.Repeat(" ", e) toc += fmt.Sprintf("%v- [%v](#%v)\n", x, n.Title, link) })) lines[lineIndex] = strings.Replace(lines[lineIndex], replaceToken, toctitle, -1) lines = append(lines[:lineIndex+1], lines[lineIndex:]...) lines[lineIndex+1] = strings.TrimRight(toc, "\n") return strings.Join(lines, "\n") } log.Println("weird, a toc was generated, but it was not added to the final content.") return s }) return replaceToken } } // GHReleasePages is a template to show a notice about the gh releases page. var GHReleasePages = `{{define "gh/releases" -}} Check the {{link (concat "https://" .URL "/releases") "release page"}}! {{- end}}` // BadgeTravis is a template to show a travis badge. var BadgeTravis = `{{define "badge/travis" -}} {{- set "travisUrl" (pathjoin "https://travis-ci.org" .User .Name) }} {{- set "travisImg" (img (concat .travisUrl ".svg?branch=" .Branch) "travis Status") }} {{- link .travisUrl .travisImg}} {{- end}}` // BadgeAppveyor is a template to show an appveyor badge. var BadgeAppveyor = `{{define "badge/appveyor" -}} {{- set "appveyorStatusUrl" (pathjoin "https://ci.appveyor.com/api/projects/status" .ProviderName .User .Name) }} {{- set "appveyorProjectUrl" (pathjoin "https://ci.appveyor.com/project" .User .Name) }} {{- set "appveyorImg" (img (concat .appveyorStatusUrl "?branch=" .Branch "&svg=true") "Appveyor Status") }} {{- link .appveyorProjectUrl .appveyorImg }} {{- end}}` // BadgeCodeship is a template to show a codehsip badge. var BadgeCodeship = `{{define "badge/codeship" -}} {{- set "csTitle" (or .CsTitle "Codeship Status") }} {{- set "csStatusUrl" (pathjoin "https://codeship.com/projects" .CsUUID "status") }} {{- set "csProjectUrl" (pathjoin "https://codeship.com/projects" .CsProjectID) }} {{- set "csImg" (img (concat (get "csStatusUrl") "?branch=" .Branch) (get "csTitle") ) }} {{- link (get "csProjectUrl") (get "csImg") }} {{- end}}` // InstructionChocoInstall is a template to show instructions to install the package with chocolatey. var InstructionChocoInstall = `{{define "choco/install" -}} ` + "```sh" + ` choco install {{.Name}} ` + "```" + ` {{- end}}` // InstructionChocoBintrayInstall is a template to show instructions to install the package with chocolatey from bintray repo. var InstructionChocoBintrayInstall = `{{define "choco_bintray/install" -}} ` + "```sh" + ` choco source add -n={{.User}} -s="https://api.bintray.com/nuget/{{.User}}/{{or .BintrayRepo "choco"}}" choco install {{.Name}} ` + "```" + ` {{- end}}` // InstructionGhRepo is a template to show instructions to install the rpm/deb repositories with gh-pages. var InstructionGhRepo = `{{define "linux/gh_src_repo" -}} ` + "```sh" + ` wget -O - https://raw.githubusercontent.com/mh-cbon/latest/master/source.sh \ | GH={{.User}}/{{.Name}} sh -xe # or curl -L https://raw.githubusercontent.com/mh-cbon/latest/master/source.sh \ | GH={{.User}}/{{.Name}} sh -xe ` + "```" + ` {{- end}}` // InstructionBintrayRepo is a template to show instructions to install the rpm/deb repositories via bintray. var InstructionBintrayRepo = `{{define "linux/bintray_repo" -}} ` + "```sh" + ` wget -O - https://raw.githubusercontent.com/mh-cbon/latest/master/bintray.sh \ | GH={{.User}}/{{.Name}} sh -xe # or curl -L https://raw.githubusercontent.com/mh-cbon/latest/master/bintray.sh \ | GH={{.User}}/{{.Name}} sh -xe ` + "```" + ` {{- end}}` // InstructionGhPkg is a template to show instructions to install the rpm/deb package with gh-pages. var InstructionGhPkg = `{{define "linux/gh_pkg" -}} ` + "```sh" + ` curl -L https://raw.githubusercontent.com/mh-cbon/latest/master/install.sh \ | GH={{.User}}/{{.Name}} sh -xe # or wget -q -O - --no-check-certificate \ https://raw.githubusercontent.com/mh-cbon/latest/master/install.sh \ | GH={{.User}}/{{.Name}} sh -xe ` + "```" + ` {{- end}}` // BadgeLicense shows a badge for a license. var BadgeLicense = `{{define "license/shields" -}} {{- set "licenseFile" (or .LicenseFile "LICENSE") }} {{- set "licenseTitle" (concat .License " License") }} {{- set "licenseImg" (or .LicenseColor "blue") }} {{- set "licenseImg" (concat "License-" .License "-" (get "licenseImg") ".svg") }} {{- set "licenseImg" (concat "http://img.shields.io/badge/" (get "licenseImg")) }} {{- set "licenseImg" (img (get "licenseImg") (get "licenseTitle")) }} {{- link (get "licenseFile") (get "licenseImg") }} {{- end}}` // Register standard helpers to the generator. func Register(g *emd.Generator) error { g.AddFunc("cat", Cat(g)) g.AddFunc("read", Read) g.AddFunc("render", Render(g)) g.AddFunc("exec", Exec(g)) g.AddFunc("shell", Shell(g)) g.AddFunc("color", Color) g.AddFunc("toc", Toc(g)) g.AddFunc("yaml", Yaml) g.AddFunc("preline", Preline) g.AddFunc("echo", Echo) g.AddFunc("link", Link) g.AddFunc("img", Img) g.AddFunc("concat", Concat) g.AddFunc("pathjoin", PathJoin) g.AddFunc("set", SetValue(g)) g.AddFunc("get", GetValue(g)) g.AddTemplate(GHReleasePages) g.AddTemplate(BadgeTravis) g.AddTemplate(BadgeAppveyor) g.AddTemplate(BadgeCodeship) g.AddTemplate(InstructionChocoBintrayInstall) g.AddTemplate(InstructionChocoInstall) g.AddTemplate(InstructionGhRepo) g.AddTemplate(InstructionGhPkg) g.AddTemplate(InstructionBintrayRepo) g.AddTemplate(BadgeLicense) return nil } emd-1.0.1/test.sh000066400000000000000000000133711315430446100135770ustar00rootroot00000000000000#!/bin/sh set -ex rm $GOPATH/bin/emd go install rm -fr $GOPATH/src/github.com/mh-cbon/emd-test rm -fr ~/fake # test 1: a project contained in GOPATH, aliased out of it mkdir -p ~/fake/src/github.com/mh-cbon/test-emd ln -s ~/fake/src/github.com/mh-cbon/test-emd $GOPATH/src/github.com/mh-cbon/emd-test cd ~/fake/src/github.com/mh-cbon/test-emd export VERBOSE=y cat <> README.e.md templated EOT emd gen | grep "templated" || exit 1; cd ~ rm -fr $GOPATH/src/github.com/mh-cbon/emd-test rm -fr ~/fake # test4: ensure emd gen defaults to defTemplate if not any README.e.md . mkdir -p $GOPATH/src/github.com/mh-cbon/emd-test cd $GOPATH/src/github.com/mh-cbon/emd-test emd gen | grep "# emd-test" || exit 1; # test prelude data. cat < -1 { a = strings.Replace(a, "\"", "\\\"", -1) } s += fmt.Sprintf(" %v", a) } return s } // Exec a command func Exec(bin string, args []string) (string, error) { cmd := exec.Command(bin, args...) out, err := cmd.CombinedOutput() if err != nil { return "", &CliError{Err: err, Cmd: GetCmdStr(bin, args)} } return string(out), nil } emd-1.0.1/utils/md.go000066400000000000000000000076711315430446100143610ustar00rootroot00000000000000package utils import ( "fmt" "regexp" "strings" ) // LineIndex returns line index of search in content. func LineIndex(content string, search string) int { ret := -1 line := "" for _, c := range content { if c == '\n' { line += "" ret++ } else { line += string(c) } if strings.Index(line, search) > -1 { ret++ break } } return ret } // PowerLess select titles of Power

-1 { c++ // starts at 1 } return c } // GetAllMdTitles extracts all MD titles markup. func GetAllMdTitles(content string) []MdTitle { ret := []MdTitle{} allTitles := []string{} line := "" isInBlock := false isInTitle := false i := 0 for _, c := range content { if !isInBlock && c == '\n' { if isInTitle { if mdTitle.MatchString(line) { got := mdTitle.FindAllStringSubmatch(line, -1) if len(got) > 0 { t := got[0][2] ret = append(ret, MdTitle{ Line: i, Title: t, Power: len(got[0][1]), Duplicate: cntStr(allTitles, t), }) allTitles = append(allTitles, t) } } } i++ isInTitle = false line = "" } else if c == '`' { isInBlock = !isInBlock line += string(c) } else if c == '#' && !isInBlock { isInTitle = true line += string(c) } else { if c == '\n' { i++ } line += string(c) } } return ret } // MakeTitleTree transform a raw list of titles into a tree. func MakeTitleTree(titles []MdTitle) *MdTitleTree { root := &MdTitleTree{} cur := root for _, t := range titles { if t.Power == 1 { nnew := &MdTitleTree{MdTitle: t, Parent: root} root.Items = append(root.Items, nnew) cur = nnew } else if t.Power > cur.Power { nnew := &MdTitleTree{MdTitle: t, Parent: cur} cur.Items = append(cur.Items, nnew) cur = nnew } else if t.Power == cur.Power { nnew := &MdTitleTree{MdTitle: t, Parent: cur.Parent} cur.Parent.Items = append(cur.Parent.Items, nnew) cur = nnew } else if t.Power < cur.Power { for { if cur.Parent.Power <= t.Power { break } cur = cur.Parent } cur = cur.Parent nnew := &MdTitleTree{MdTitle: t, Parent: cur.Parent} cur.Parent.Items = append(cur.Parent.Items, nnew) cur = nnew } } return root } // GetMdLinkHash encodes s to insert into an MD link. func GetMdLinkHash(link string) string { link = strings.ToLower(link) link = strings.Replace(link, "/", "", -1) link = strings.Replace(link, "$", "", -1) link = strings.Replace(link, ">", "", -1) link = strings.Replace(link, ".", "", -1) link = strings.Replace(link, ";", "", -1) link = strings.Replace(link, ":", "", -1) link = strings.Replace(link, "!", "", -1) link = strings.Replace(link, "'", "", -1) link = strings.Replace(link, "|", "", -1) link = strings.Replace(link, "[", "", -1) link = strings.Replace(link, "]", "", -1) link = strings.Replace(link, ",", "", -1) link = strings.Replace(link, " ", "-", -1) // should it be a regexp like /[a-z0-9-_]/i ? return link } // MdTitleTree is an MdTitle with tree capabilities type MdTitleTree struct { MdTitle Parent *MdTitleTree Items []*MdTitleTree } // Traverse a tree func (m *MdTitleTree) Traverse(f func(*MdTitleTree)) { f(m) for _, i := range m.Items { i.Traverse(f) } } func (m *MdTitleTree) String() string { x := strings.Repeat("#", m.Power) return fmt.Sprintf("%-5v %-15q Items:%v Line:%v", x, m.Title, len(m.Items), m.Line) } // MdTitle is a markdwon title. type MdTitle struct { Line int Power int Duplicate int Title string } emd-1.0.1/utils/md_test.go000066400000000000000000000134231315430446100154100ustar00rootroot00000000000000package utils import ( "fmt" "strings" "testing" ) func TestLineIndex(t *testing.T) { content := `xx yyy search zzz ` want := 2 got := LineIndex(content, "search") if want != got { t.Errorf("LineIndex fail, want=%v, got=%v", want, got) } } func TestGetAllMdTitles(t *testing.T) { content := `# one yyy ## two # three zzz ` got := GetAllMdTitles(content) iwant := 3 igot := len(got) if iwant != igot { t.Errorf("GetAllMdTitles fail, len() want=%v, got=%v", iwant, igot) } sgot := got[0].Title swant := "one" if swant != sgot { t.Errorf("GetAllMdTitles fail, [0].Title want=%v, got=%v", swant, sgot) } iwant = 1 igot = got[0].Power if iwant != igot { t.Errorf("GetAllMdTitles fail, [0].Power want=%v, got=%v", iwant, igot) } sgot = got[1].Title swant = "two" if swant != sgot { t.Errorf("GetAllMdTitles fail, [1].Title want=%v, got=%v", swant, sgot) } iwant = 2 igot = got[1].Power if iwant != igot { t.Errorf("GetAllMdTitles fail, [0].Power want=%v, got=%v", iwant, igot) } sgot = got[2].Title swant = "three" if swant != sgot { t.Errorf("GetAllMdTitles fail, [1].Title want=%v, got=%v", swant, sgot) } iwant = 1 igot = got[2].Power if iwant != igot { t.Errorf("GetAllMdTitles fail, [0].Power want=%v, got=%v", iwant, igot) } } func TestMakeTitleTree(t *testing.T) { content := `# one ## two # three # four ## four 1 ### four 1-1 ### four 1-2 ## four 2 ### four 2-1 ### four 2-2 # five ###### five 1-1 ` titles := GetAllMdTitles(content) root := MakeTitleTree(titles) got := root.Items // fmt.Println(got[0]) // fmt.Println(got[1]) // fmt.Println(got[2]) // fmt.Println(got[2].Items[0]) // fmt.Println(got[2].Items[0].Items[0]) // fmt.Println(got[2].Items[0].Items[1]) // fmt.Println(got[2].Items[1]) // fmt.Println(got[3]) iwant := 4 igot := len(got) if iwant != igot { t.Errorf("MakeTitleTree fail, len() want=%v, got=%v", iwant, igot) } swant := "one" sgot := got[0].Title if swant != sgot { t.Errorf("MakeTitleTree fail, [0].Title want=%v, got=%v", swant, sgot) } iwant = 1 igot = got[0].Power if iwant != igot { t.Errorf("MakeTitleTree fail, [0].Power want=%v, got=%v", iwant, igot) } iwant = 1 igot = len(got[0].Items) if iwant != igot { t.Errorf("MakeTitleTree fail, len([0].Items) want=%v, got=%v", iwant, igot) } swant = "two" sgot = got[0].Items[0].Title if swant != sgot { t.Errorf("MakeTitleTree fail, [0]Items[0].Title want=%v, got=%v", swant, sgot) } iwant = 2 igot = got[0].Items[0].Power if iwant != igot { t.Errorf("MakeTitleTree fail, [0]Items[0].Power want=%v, got=%v", iwant, igot) } iwant = 1 igot = got[1].Power if iwant != igot { t.Errorf("MakeTitleTree fail, [1].Power want=%v, got=%v", iwant, igot) } swant = "three" sgot = got[1].Title if swant != sgot { t.Errorf("MakeTitleTree fail, [0].Title want=%v, got=%v", swant, sgot) } iwant = 0 igot = len(got[1].Items) if iwant != igot { t.Errorf("MakeTitleTree fail, len([1].Items) want=%v, got=%v", iwant, igot) } } func TestTraverse(t *testing.T) { content := `# one ## two # three # four ## four 1 ### four 1-1 ### four 1-2 ## four 2 ### four 2-1 #### four 2-2 # five ###### five 1-1 ` titles := GetAllMdTitles(content) root := MakeTitleTree(titles) got := "" root.Traverse(PowerLess(5, func(n *MdTitleTree) { // got += MakeTOCItem(" ", n) + "\n" link := GetMdLinkHash(n.Title) x := strings.Repeat(" ", n.Power) got += fmt.Sprintf("%v- [%v](#%v)\n", x, n.Title, link) })) want := ` - [one](#one) - [two](#two) - [three](#three) - [four](#four) - [four 1](#four-1) - [four 1-1](#four-1-1) - [four 1-2](#four-1-2) - [four 2](#four-2) - [four 2-1](#four-2-1) - [four 2-2](#four-2-2) - [five](#five) ` if want != got { t.Errorf("TestTraverse failed, want=\n%v\ngot\n%v", want, got) } } func TestTraverse2(t *testing.T) { content := ` # Install ## go ` + "```" + `sh go get github.com/semver/cmd ` + "```" + ` # Cli ## Help #### $ go run main.go -help ` + "```" + `sh semver - 0.0.0 Usage -filter|-c string Filter versions matching given semver constraint -invalid bool Show only invalid versions -sort|-s bool Sort input versions -desc|-d bool Sort versions descending -first|-f bool Only first version -last|-l bool Only last version -json|-j bool JSON output -version bool Show version Example semver -c 1.x 0.0.4 1.2.3 exho "0.0.4 1.2.3" | semver -j exho "0.0.4 1.2.3" | semver -s exho "0.0.4 1.2.3" | semver -s -d -j -f exho "0.0.4 1.2.3 tomate" | semver -invalid ` + "```" + ` # Example ## Filter versions #### $ go run main.go -c 1.x 1.0.4 1.1.1 1.2.2 2.3.4 ` + "```" + `sh - 1.0.4 - 1.1.1 - 1.2.2 ` + "```" + ` ## Use stdin #### $ echo '1.0.4 1.1.1 1.2.2 2.3.4' | go run main.go -c 2.x ` + "```" + `sh - 2.3.4 ` + "```" + ` ` titles := GetAllMdTitles(content) root := MakeTitleTree(titles) got := "" root.Traverse(PowerLess(5, func(n *MdTitleTree) { // got += MakeTOCItem(" ", n) + "\n" link := GetMdLinkHash(n.Title) x := strings.Repeat(" ", n.Power) got += fmt.Sprintf("%v- [%v](#%v)\n", x, n.Title, link) })) want := ` - [Install](#install) - [go](#go) - [Cli](#cli) - [Help](#help) - [$ go run main.go -help](#-go-run-maingo--help) - [Example](#example) - [Filter versions](#filter-versions) - [$ go run main.go -c 1.x 1.0.4 1.1.1 1.2.2 2.3.4](#-go-run-maingo--c-1x-104-111-122-234) - [Use stdin](#use-stdin) - [$ echo '1.0.4 1.1.1 1.2.2 2.3.4' | go run main.go -c 2.x](#-echo-104-111-122-234--go-run-maingo--c-2x) ` if want != got { t.Errorf("TestTraverse failed, want=\n%q\ngot\n%q", want, got) } } func TestGetMdLinkHash(t *testing.T) { sgot := GetMdLinkHash("/$ .>;:") swant := "-" if swant != sgot { t.Errorf("GetMdLinkHash fail, want=%v, got=%v", swant, sgot) } } emd-1.0.1/utils/prelude.go000066400000000000000000000020111315430446100154000ustar00rootroot00000000000000package utils import ( "encoding/json" "fmt" "strings" ) // GetPrelude decodes and remove the prelude from the input string. func GetPrelude(s string) (string, map[string]interface{}, error) { var v map[string]interface{} k := strings.Split(string(s), "\n") i := 0 prelude := "" if len(k) > 1 && k[0] == "---" { i++ for _, l := range k[1:] { i++ if l == "---" { break } z := strings.Index(l, ":") name := l[0:z] val := l[z+1:] val = strings.TrimLeft(val, " ") // quote raw values, it allows easier writing of strings containing strings. if val[0] != '[' && val[0] != '"' && val[0] != '\'' { val = fmt.Sprintf("%q", val) } prelude += fmt.Sprintf("%q:%v,\n", name, val) } prelude = "{" + prelude[:len(prelude)-2] + "}" if err := json.Unmarshal([]byte(prelude), &v); err != nil { return "", v, err } } // rebuild the template without prelude c := "" for _, l := range k[i:] { c += fmt.Sprintf("%v\n", l) } return strings.TrimRight(c, "\n") + "\n", v, nil } emd-1.0.1/utils/shellexec.go000066400000000000000000000027071315430446100157300ustar00rootroot00000000000000package utils import ( "io/ioutil" "os" "os/exec" "path/filepath" "runtime" ) // Command Return a new exec.Cmd object for the given command string func Command(cwd string, cmd string) (*TempCmd, error) { return NewTempCmd(cwd, cmd) } // TempCmd ... type TempCmd struct { *exec.Cmd f string } var isWindows = runtime.GOOS == "windows" // NewTempCmd is a cmd wrapped into a tmp file func NewTempCmd(cwd string, cmd string) (*TempCmd, error) { f, err := ioutil.TempDir("", "stringexec") if err != nil { return nil, err } fp := filepath.Join(f, "s") if isWindows { fp += ".bat" } err = ioutil.WriteFile(fp, []byte(cmd), 0766) if err != nil { return nil, err } ret := &TempCmd{Cmd: exec.Command("sh", "-c", fp), f: fp} if isWindows { ret.Cmd = exec.Command("cmd", "/C", fp) } ret.Cmd.Dir = cwd return ret, nil } // Run the cmd func (t *TempCmd) Run() error { if err := t.Cmd.Start(); err != nil { return err } return t.Wait() } // Wait wait for command then delete the tmp file. func (t *TempCmd) Wait() error { err := t.Cmd.Wait() os.Remove(t.f) return err } // Shell exec a string. func Shell(wd, s string) (string, error) { if wd == "" { var err error wd, err = os.Getwd() if err != nil { return "", err } } cmd, err := NewTempCmd(wd, s) if err != nil { return "", &CliError{Err: err, Cmd: s} } out, err := cmd.CombinedOutput() if err != nil { return "", &CliError{Err: err, Cmd: s} } return string(out), nil } emd-1.0.1/wix.json000066400000000000000000000013371315430446100137650ustar00rootroot00000000000000{ "product": "emd", "company": "mh-cbon", "license": "LICENSE", "upgrade-code": "14F6E9E0-470C-46D0-80BF-2408266E37CB", "files": { "guid": "C15B46B7-FD6E-4DB9-9194-EFA544DEBB4B", "items": [ "emd.exe" ] }, "env": { "guid": "658A7B52-AC3D-466F-8B27-5E35FFC4FD4A", "vars": [ { "name": "PATH", "value": "[INSTALLDIR]", "permanent": "no", "system": "no", "action": "set", "part": "last" } ] }, "shortcuts": {}, "choco": { "description": "Enhanced Markdown template processor", "project-url": "https://github.com/mh-cbon/emd", "tags": "emd", "license-url": "https://github.com/mh-cbon/emd/blob/master/LICENSE" } }