2016-02-21 13:21:41 +03:00
|
|
|
#!/usr/bin/env stack
|
2016-04-06 01:23:20 +03:00
|
|
|
{- stack runghc --verbosity info
|
2016-04-05 16:59:52 +03:00
|
|
|
--package base-prelude
|
|
|
|
--package directory
|
|
|
|
--package extra
|
|
|
|
--package here
|
|
|
|
--package safe
|
|
|
|
--package shake
|
|
|
|
--package time
|
2016-04-06 01:23:20 +03:00
|
|
|
--package pandoc
|
2016-04-05 16:59:52 +03:00
|
|
|
-}
|
|
|
|
{-
|
|
|
|
Usage: see below.
|
|
|
|
Shake.hs is a more powerful Makefile, providing a number of commands
|
|
|
|
for performing useful tasks. Compiling this script is suggested, so that
|
|
|
|
it runs quicker and will not be affected eg when exploring old code versions.
|
|
|
|
More about Shake: http://shakebuild.com/manual
|
|
|
|
Requires: https://www.haskell.org/downloads#stack
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-05 16:59:52 +03:00
|
|
|
Shake notes:
|
|
|
|
wishlist:
|
2016-04-07 18:52:41 +03:00
|
|
|
just one shake import
|
2016-04-05 16:59:52 +03:00
|
|
|
wildcards in phony rules
|
|
|
|
multiple individually accessible wildcards
|
2016-04-07 18:52:41 +03:00
|
|
|
not having to write :: Action ExitCode after a non-final cmd
|
2016-04-05 16:59:52 +03:00
|
|
|
-}
|
|
|
|
|
|
|
|
{-# LANGUAGE PackageImports, QuasiQuotes #-}
|
|
|
|
|
|
|
|
import Prelude ()
|
|
|
|
import "base-prelude" BasePrelude
|
|
|
|
-- import "base" System.Console.GetOpt
|
|
|
|
import "extra" Data.List.Extra
|
|
|
|
import "here" Data.String.Here
|
|
|
|
import "safe" Safe
|
|
|
|
import "shake" Development.Shake
|
|
|
|
import "shake" Development.Shake.FilePath
|
|
|
|
import "time" Data.Time
|
|
|
|
import "directory" System.Directory as S (getDirectoryContents)
|
|
|
|
|
|
|
|
usage = [i|Usage:
|
2016-04-06 01:56:14 +03:00
|
|
|
./Shake.hs compile # compile this script (optional)
|
|
|
|
./Shake --help # show options, eg --color
|
2016-04-06 02:07:37 +03:00
|
|
|
./Shake # show commands
|
2016-04-16 13:47:00 +03:00
|
|
|
./Shake all # generate everything
|
|
|
|
./Shake docs # generate general docs
|
2016-05-28 22:10:51 +03:00
|
|
|
./Shake website # generate the web site
|
2016-04-06 01:56:14 +03:00
|
|
|
./Shake manpages # generate nroff files for man
|
2016-04-14 08:29:16 +03:00
|
|
|
./Shake txtmanpages # generate text man pages for embedding
|
2016-04-19 03:54:55 +03:00
|
|
|
./Shake infomanpages # generate info files for info
|
2016-04-06 01:56:14 +03:00
|
|
|
./Shake webmanpages # generate web man pages for hakyll
|
2016-04-07 18:52:41 +03:00
|
|
|
./Shake webmanual # generate combined web man page for hakyll
|
2016-04-05 16:59:52 +03:00
|
|
|
|]
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-19 03:54:55 +03:00
|
|
|
pandoc = "pandoc" -- pandoc from PATH (faster)
|
|
|
|
-- "stack exec -- pandoc" -- pandoc from project's stackage snapshot
|
2016-04-10 00:24:33 +03:00
|
|
|
hakyllstd = "site/hakyll-std/hakyll-std"
|
2016-04-19 03:54:55 +03:00
|
|
|
makeinfo = "makeinfo"
|
2016-06-12 07:34:20 +03:00
|
|
|
-- nroff = "nroff"
|
|
|
|
groff = "groff"
|
2016-02-21 13:21:41 +03:00
|
|
|
|
|
|
|
main = do
|
|
|
|
|
|
|
|
pandocFilters <-
|
2016-04-06 01:46:44 +03:00
|
|
|
map ("doc" </>). nub . sort . map (-<.> "") . filter ("pandoc-" `isPrefixOf`)
|
|
|
|
<$> S.getDirectoryContents "doc"
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-05 16:59:52 +03:00
|
|
|
shakeArgs
|
|
|
|
shakeOptions{
|
2016-04-13 06:32:01 +03:00
|
|
|
shakeVerbosity=Loud
|
2016-04-05 16:59:52 +03:00
|
|
|
-- ,shakeReport=[".shake.html"]
|
|
|
|
} $ do
|
|
|
|
|
|
|
|
want ["help"]
|
|
|
|
|
|
|
|
phony "help" $ liftIO $ putStrLn usage
|
|
|
|
|
|
|
|
phony "compile" $ need ["Shake"]
|
2016-04-16 13:47:00 +03:00
|
|
|
|
2016-04-05 16:59:52 +03:00
|
|
|
"Shake" %> \out -> do
|
2016-04-16 13:47:00 +03:00
|
|
|
need [out <.> "hs"]
|
2016-04-05 16:59:52 +03:00
|
|
|
cmd "stack ghc Shake.hs" :: Action ExitCode
|
|
|
|
putLoud "Compiled ./Shake, you can now use this instead of ./Shake.hs"
|
|
|
|
|
2016-05-28 22:10:51 +03:00
|
|
|
phony "all" $ need ["docs", "website"]
|
2016-04-06 02:16:38 +03:00
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
-- docs
|
2016-04-08 17:01:11 +03:00
|
|
|
|
|
|
|
let
|
|
|
|
manpageNames = [ -- in suggested reading order
|
|
|
|
"hledger.1"
|
|
|
|
,"hledger-ui.1"
|
|
|
|
,"hledger-web.1"
|
|
|
|
,"hledger-api.1"
|
|
|
|
,"hledger_journal.5"
|
|
|
|
,"hledger_csv.5"
|
2016-04-13 07:10:02 +03:00
|
|
|
,"hledger_timeclock.5"
|
2016-04-08 17:01:11 +03:00
|
|
|
,"hledger_timedot.5"
|
|
|
|
]
|
2016-04-16 13:47:00 +03:00
|
|
|
-- manuals m4 source, may include other files (hledger/doc/hledger.1.m4.md)
|
|
|
|
m4manpages = [manpageDir m </> m <.> "m4.md" | m <- manpageNames]
|
|
|
|
-- manuals rendered to nroff, ready for man (hledger/doc/hledger.1)
|
|
|
|
nroffmanpages = [manpageDir m </> m | m <- manpageNames]
|
|
|
|
-- manuals rendered to text, ready for embedding (hledger/doc/hledger.1.txt)
|
|
|
|
txtmanpages = [manpageDir m </> m <.> "txt" | m <- manpageNames]
|
2016-04-19 03:54:55 +03:00
|
|
|
-- manuals rendered to info, ready for info (hledger/doc/hledger.info)
|
|
|
|
infomanpages = [manpageDir m </> m <.> "info" | m <- manpageNames]
|
2016-04-16 13:47:00 +03:00
|
|
|
-- manuals rendered to markdown, ready for web output by hakyll (site/hledger.md)
|
|
|
|
webmanpages = ["site" </> manpageNameToUri m <.>"md" | m <- manpageNames]
|
|
|
|
-- manuals rendered to markdown and combined, ready for web output by hakyll
|
|
|
|
webmanual = "site/manual.md"
|
|
|
|
|
|
|
|
-- hledger.1 -> hledger/doc, hledger_journal.5 -> hledger-lib/doc
|
|
|
|
manpageDir m
|
|
|
|
| '_' `elem` m = "hledger-lib" </> "doc"
|
|
|
|
| otherwise = dropExtension m </> "doc"
|
2016-04-08 17:01:11 +03:00
|
|
|
|
|
|
|
-- hledger.1 -> hledger, hledger_journal.5 -> journal
|
|
|
|
manpageNameToUri m | "hledger_" `isPrefixOf` m = dropExtension $ drop 8 m
|
|
|
|
| otherwise = dropExtension m
|
|
|
|
|
|
|
|
-- hledger -> hledger.1, journal -> hledger_journal.5
|
|
|
|
manpageUriToName u | "hledger" `isPrefixOf` u = u <.> "1"
|
|
|
|
| otherwise = "hledger_" ++ u <.> "5"
|
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
phony "docs" $ do
|
|
|
|
need $
|
|
|
|
nroffmanpages
|
2016-04-19 03:54:55 +03:00
|
|
|
++ infomanpages
|
2016-04-16 13:47:00 +03:00
|
|
|
++ txtmanpages
|
2016-04-08 17:01:11 +03:00
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
-- compile pandoc helpers
|
doc: experimental m4-based man page build process
The new m4manpages, m4webmanpages targets generate nroff and markdown
man pages via an alternate, excitingly complicated process, involving
shake, hakyll, pandoc *and* m4. Currently just the hledger man page is
processed this way, and the output (hledger/doc/m4-hledger.1,
site/m4-hledger.1.md) is equivalent to that of the non-m4 process.
Pro: selecting and massaging web/man content may be smoother with m4
than with pandoc filters. File inclusion allows documentation to be
broken up into chunks, which may be easier to edit, reorganize and
reuse. Macros could reduce boilerplate and enable more featureful and
attractive docs.
Con: the non-m4 process was simpler, easier to for contributors to
understand and working well enough. YAGNI.
2016-04-06 18:23:12 +03:00
|
|
|
phony "pandocfilters" $ need pandocFilters
|
2016-04-16 13:47:00 +03:00
|
|
|
|
doc: experimental m4-based man page build process
The new m4manpages, m4webmanpages targets generate nroff and markdown
man pages via an alternate, excitingly complicated process, involving
shake, hakyll, pandoc *and* m4. Currently just the hledger man page is
processed this way, and the output (hledger/doc/m4-hledger.1,
site/m4-hledger.1.md) is equivalent to that of the non-m4 process.
Pro: selecting and massaging web/man content may be smoother with m4
than with pandoc filters. File inclusion allows documentation to be
broken up into chunks, which may be easier to edit, reorganize and
reuse. Macros could reduce boilerplate and enable more featureful and
attractive docs.
Con: the non-m4 process was simpler, easier to for contributors to
understand and working well enough. YAGNI.
2016-04-06 18:23:12 +03:00
|
|
|
pandocFilters |%> \out -> do
|
|
|
|
need [out <.> "hs"]
|
|
|
|
cmd ("stack ghc") out
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
-- man pages
|
|
|
|
|
2016-04-16 20:09:51 +03:00
|
|
|
-- use m4 and pandoc to process macros, filter content, and convert to nroff suitable for man output
|
2016-04-16 13:47:00 +03:00
|
|
|
phony "manpages" $ need nroffmanpages
|
|
|
|
|
|
|
|
nroffmanpages |%> \out -> do -- hledger/doc/hledger.1
|
2016-04-16 20:09:51 +03:00
|
|
|
let src = out <.> "m4.md"
|
|
|
|
lib = "doc/lib.m4"
|
|
|
|
dir = takeDirectory out
|
doc: experimental m4-based man page build process
The new m4manpages, m4webmanpages targets generate nroff and markdown
man pages via an alternate, excitingly complicated process, involving
shake, hakyll, pandoc *and* m4. Currently just the hledger man page is
processed this way, and the output (hledger/doc/m4-hledger.1,
site/m4-hledger.1.md) is equivalent to that of the non-m4 process.
Pro: selecting and massaging web/man content may be smoother with m4
than with pandoc filters. File inclusion allows documentation to be
broken up into chunks, which may be easier to edit, reorganize and
reuse. Macros could reduce boilerplate and enable more featureful and
attractive docs.
Con: the non-m4 process was simpler, easier to for contributors to
understand and working well enough. YAGNI.
2016-04-06 18:23:12 +03:00
|
|
|
tmpl = "doc/manpage.nroff"
|
2016-04-16 20:09:51 +03:00
|
|
|
-- assume all other m4 files in dir are included by this one XXX not true in hledger-lib
|
|
|
|
deps <- liftIO $ filter (/= src) . filter (".m4.md" `isSuffixOf`) . map (dir </>) <$> S.getDirectoryContents dir
|
|
|
|
need $ src : lib : tmpl : deps ++ pandocFilters
|
|
|
|
cmd Shell
|
|
|
|
"m4 -P -DMAN -I" dir lib src "|"
|
|
|
|
pandoc "-f markdown -s --template" tmpl
|
|
|
|
-- "--filter doc/pandoc-drop-web-blocks"
|
2016-04-06 01:46:44 +03:00
|
|
|
"--filter doc/pandoc-drop-html-blocks"
|
|
|
|
"--filter doc/pandoc-drop-html-inlines"
|
|
|
|
"--filter doc/pandoc-drop-links"
|
|
|
|
"--filter doc/pandoc-drop-notes"
|
2016-04-08 07:58:42 +03:00
|
|
|
"-o" out
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
-- render man page nroffs to fixed-width text for embedding in executables, with nroff
|
2016-04-14 08:29:16 +03:00
|
|
|
phony "txtmanpages" $ need txtmanpages
|
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
txtmanpages |%> \out -> do -- hledger/doc/hledger.1.txt
|
|
|
|
let src = dropExtension out
|
|
|
|
need [src]
|
2016-06-12 07:34:20 +03:00
|
|
|
cmd Shell groff "-t -e -mandoc -Tascii" src "| col -bx >" out -- http://www.tldp.org/HOWTO/Man-Page/q10.html
|
2016-04-16 13:47:00 +03:00
|
|
|
|
2016-04-19 03:54:55 +03:00
|
|
|
-- use m4 and pandoc to process macros, filter content, and convert to info, suitable for info viewing
|
|
|
|
phony "infomanpages" $ need infomanpages
|
|
|
|
|
|
|
|
infomanpages |%> \out -> do -- hledger/doc/hledger.info
|
|
|
|
let src = out -<.> "m4.md"
|
|
|
|
lib = "doc/lib.m4"
|
|
|
|
dir = takeDirectory out
|
|
|
|
-- assume all other m4 files in dir are included by this one XXX not true in hledger-lib
|
|
|
|
deps <- liftIO $ filter (/= src) . filter (".m4.md" `isSuffixOf`) . map (dir </>) <$> S.getDirectoryContents dir
|
|
|
|
need $ src : lib : deps ++ pandocFilters
|
|
|
|
cmd Shell
|
|
|
|
"m4 -P -I" dir lib src "|"
|
|
|
|
pandoc "-f markdown"
|
|
|
|
-- "--filter doc/pandoc-drop-web-blocks"
|
|
|
|
"--filter doc/pandoc-drop-html-blocks"
|
|
|
|
"--filter doc/pandoc-drop-html-inlines"
|
|
|
|
"--filter doc/pandoc-drop-links"
|
|
|
|
"--filter doc/pandoc-drop-notes"
|
|
|
|
"-t texinfo |"
|
|
|
|
makeinfo "--force --no-split -o" out
|
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
-- web site
|
|
|
|
|
2016-05-28 22:10:51 +03:00
|
|
|
phony "website" $ do
|
2016-04-16 13:47:00 +03:00
|
|
|
need $
|
|
|
|
webmanpages ++
|
|
|
|
[webmanual
|
2016-04-16 15:55:16 +03:00
|
|
|
,"releasemanual"
|
2016-04-16 13:47:00 +03:00
|
|
|
,hakyllstd
|
|
|
|
]
|
|
|
|
cmd Shell (Cwd "site") "hakyll-std/hakyll-std" "build"
|
|
|
|
|
2016-04-16 20:09:51 +03:00
|
|
|
-- use m4 and pandoc to process macros and filter content, leaving markdown suitable for web output
|
2016-04-08 17:01:11 +03:00
|
|
|
phony "webmanpages" $ need webmanpages
|
2016-04-16 13:47:00 +03:00
|
|
|
|
|
|
|
webmanpages |%> \out -> do -- site/hledger.md
|
|
|
|
let m = manpageUriToName $ dropExtension $ takeFileName out -- hledger.1
|
2016-04-16 20:09:51 +03:00
|
|
|
dir = manpageDir m
|
|
|
|
src = dir </> m <.> "m4.md"
|
|
|
|
lib = "doc/lib.m4"
|
2016-04-09 23:36:48 +03:00
|
|
|
heading = let h = dropExtension m
|
|
|
|
in if "hledger_" `isPrefixOf` h
|
|
|
|
then drop 8 h ++ " format"
|
|
|
|
else h
|
2016-04-16 20:09:51 +03:00
|
|
|
-- assume all other m4 files in dir are included by this one XXX not true in hledger-lib
|
|
|
|
deps <- liftIO $ filter (/= src) . filter (".m4.md" `isSuffixOf`) . map (dir </>) <$> S.getDirectoryContents dir
|
|
|
|
need $ src : lib : deps ++ pandocFilters
|
2016-04-09 23:36:48 +03:00
|
|
|
liftIO $ writeFile out $ "# " ++ heading ++ "\n\n"
|
2016-04-16 20:09:51 +03:00
|
|
|
cmd Shell
|
|
|
|
"m4 -P -DMAN -DWEB -I" dir lib src "|"
|
|
|
|
pandoc "-f markdown -t markdown --atx-headers"
|
2016-04-07 18:52:41 +03:00
|
|
|
"--filter doc/pandoc-demote-headers"
|
|
|
|
-- "--filter doc/pandoc-add-toc"
|
|
|
|
-- "--filter doc/pandoc-drop-man-blocks"
|
2016-04-09 23:36:48 +03:00
|
|
|
">>" out
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-09 23:19:31 +03:00
|
|
|
-- adjust and combine man page mds for single-page web output, using pandoc
|
2016-04-07 18:52:41 +03:00
|
|
|
phony "webmanual" $ need [ webmanual ]
|
2016-04-16 13:47:00 +03:00
|
|
|
|
|
|
|
webmanual %> \out -> do
|
2016-04-08 17:01:11 +03:00
|
|
|
need webmanpages
|
2016-04-16 15:52:20 +03:00
|
|
|
liftIO $ writeFile webmanual "* toc\n\n"
|
2016-04-08 17:01:11 +03:00
|
|
|
forM_ webmanpages $ \f -> do -- site/hledger.md, site/journal.md
|
2016-04-09 23:36:48 +03:00
|
|
|
cmd Shell ("printf '\\n\\n' >>") webmanual :: Action ExitCode
|
2016-04-09 04:14:49 +03:00
|
|
|
cmd Shell "pandoc" f "-t markdown --atx-headers"
|
2016-04-09 23:36:48 +03:00
|
|
|
-- "--filter doc/pandoc-drop-man-blocks"
|
2016-04-07 18:52:41 +03:00
|
|
|
"--filter doc/pandoc-drop-toc"
|
2016-04-08 07:58:42 +03:00
|
|
|
-- "--filter doc/pandoc-capitalize-headers"
|
2016-04-07 18:52:41 +03:00
|
|
|
"--filter doc/pandoc-demote-headers"
|
|
|
|
">>" webmanual :: Action ExitCode
|
2016-02-21 13:21:41 +03:00
|
|
|
|
2016-04-16 15:55:16 +03:00
|
|
|
-- check out and render manual pages for the current release also
|
|
|
|
phony "releasemanual" $ need [ "releasemanual0.27" ]
|
|
|
|
|
|
|
|
phony "releasemanual0.27" $ do
|
|
|
|
-- XXX under doc so hakyll-std will render it
|
|
|
|
cmd "mkdir -p site/doc/0.27" :: Action ExitCode
|
|
|
|
cmd Shell "git show 0.27:doc/manual.md >site/doc/0.27/manual.md"
|
|
|
|
|
2016-04-16 13:47:00 +03:00
|
|
|
-- build standard hakyll script used for site rendering
|
|
|
|
hakyllstd %> \out -> do
|
|
|
|
let dir = takeDirectory out
|
|
|
|
need [out <.> "hs", dir </> "TableOfContents.hs"] -- XXX hard-coded dep
|
|
|
|
cmd (Cwd dir) "stack ghc hakyll-std"
|
|
|
|
|
2016-04-06 01:40:59 +03:00
|
|
|
-- cleanup
|
|
|
|
|
2016-02-21 13:21:41 +03:00
|
|
|
phony "clean" $ do
|
|
|
|
putNormal "Cleaning generated files"
|
2016-04-08 17:01:11 +03:00
|
|
|
removeFilesAfter "." webmanpages
|
2016-04-07 18:52:41 +03:00
|
|
|
removeFilesAfter "." [webmanual]
|
doc: experimental m4-based man page build process
The new m4manpages, m4webmanpages targets generate nroff and markdown
man pages via an alternate, excitingly complicated process, involving
shake, hakyll, pandoc *and* m4. Currently just the hledger man page is
processed this way, and the output (hledger/doc/m4-hledger.1,
site/m4-hledger.1.md) is equivalent to that of the non-m4 process.
Pro: selecting and massaging web/man content may be smoother with m4
than with pandoc filters. File inclusion allows documentation to be
broken up into chunks, which may be easier to edit, reorganize and
reuse. Macros could reduce boilerplate and enable more featureful and
attractive docs.
Con: the non-m4 process was simpler, easier to for contributors to
understand and working well enough. YAGNI.
2016-04-06 18:23:12 +03:00
|
|
|
|
|
|
|
phony "Clean" $ do
|
|
|
|
need ["clean"]
|
2016-04-08 17:01:11 +03:00
|
|
|
putNormal "Cleaning generated man page nroffs"
|
2016-04-16 13:47:00 +03:00
|
|
|
removeFilesAfter "." nroffmanpages
|
2016-04-10 00:24:33 +03:00
|
|
|
putNormal "Cleaning all hakyll generated files"
|
|
|
|
removeFilesAfter "site" ["_*"]
|
|
|
|
putNormal "Cleaning executables"
|
|
|
|
removeFilesAfter "." $ hakyllstd : pandocFilters
|
2016-02-21 13:21:41 +03:00
|
|
|
putNormal "Cleaning object files"
|
2016-04-10 00:24:33 +03:00
|
|
|
removeFilesAfter "doc" ["*.o","*.p_o","*.hi"] -- forces rebuild of exes ?
|
|
|
|
removeFilesAfter "site" ["*.o","*.p_o","*.hi"]
|
2016-02-21 13:21:41 +03:00
|
|
|
putNormal "Cleaning shake build files"
|
2016-04-13 06:32:01 +03:00
|
|
|
removeFilesAfter ".shake" ["//*"]
|