readme-lhs 0.2.0 → 0.2.1
raw patch · 10 files changed
+256/−1216 lines, 10 filesdep −tasty
Dependencies removed: tasty
Files
- example.lhs +37/−25
- index.html +0/−81
- other/batteries.hsfiles +0/−476
- other/readme-hs.hsfiles +0/−335
- other/readme-lhs.hsfiles +144/−243
- readme-lhs.cabal +2/−6
- readme.md +32/−36
- src/Readme/Lhs.hs +27/−10
- stack.yaml +0/−3
- test/test.hs +14/−1
example.lhs view
@@ -6,18 +6,9 @@ === <blockquote cite>-The language in which we express our ideas has a strong influence on our thought processes. ~ Knuth+The language in which we express our ideas has a strong influence on our thought processes. Knuth </blockquote> -This is an example of mixing literate haskell with markdown, and in using Readme.Lhs. The file is composed of several elements:--- literate haskell. Bird-tracks are used, as the alternative method is latex rather than markdown, which doesn't survive a pandoc round trip.-- markdown. All non bird-tracked lines are considered to be markdown. It's probably incompatible with haddock, but this may well resolve with adoption of the [literate markdown ghc proposal](https://gitlab.haskell.org/ghc/ghc/wikis/literate-markdown).-- fenced code blocks with an output class, which are used to insert computation results. The fenced code blocks look like:-- \`\`\`{.output .example}- \`\`\`- [ghc options](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html#flag-reference) --- @@ -26,7 +17,6 @@ [pragmas](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/lang.html) ------------------------------------------------------------------------------------ -> -- doctest doesn't look at the cabal file, so you need pragmas here > {-# LANGUAGE NoImplicitPrelude #-} > {-# LANGUAGE OverloadedStrings #-} > {-# LANGUAGE DataKinds #-}@@ -52,14 +42,14 @@ > main = do > let n = 10 > let answer = product [1..n::Integer]-> _ <- runOutput ("example.lhs", LHS) ("readme.md", GitHubMarkdown) $ do-> output "example1" "Simple example of an output"+> void $ runOutput ("example.lhs", LHS) ("readme.md", GitHubMarkdown) $ do+> output "example1" (Fence "Simple example of an output") ```{.output .example1} ``` -> output "example2" (show answer)+> output "example2" (Fence (show answer)) 10! is equal to: @@ -67,9 +57,21 @@ ``` -> pure ()->+As well as fenced output, output can be Text that replaces the {.output} code block +> output "example3" (Replace "Fenced code block was overwritten")++```{.output .example3}+This will be replaced.+```++or be native pandoc.++> output "example4" (Native [BulletList [[plain "a"], [plain "bullet"], [plain "list"]]])++```{.output .example4}+```+ Output that doesn't exist is simply cleared. ``` {.output .example3}@@ -77,21 +79,31 @@ cleared on execution. ``` -hsfiles writeup+Technicals === -A literate-programming friendly; tight work-flow stack template.+This is an example of mixing literate haskell with markdown, and in using readme-lhs. The file is composed of several elements: -other/readme-lhs.hsfiles+- literate haskell. Bird-tracks are used, as the alternative lhs method is latex. Pandoc can read this, but defaults to bird tracks when rendering `markdown+lhs`.+- markdown. All non bird-tracked lines are considered to be markdown. It's probably incompatible with haddock. This might be easily fixable.+- fenced code blocks with an output class, which are used to insert computation results. The fenced code blocks look like: -other/batteries.hsfiles----+ \`\`\`{.output .example}+ \`\`\` -This is my latest working template, overly influenced by [lexi-lambda's opinionated guide](https://lexi-lambda.github.io/blog/2018/02/10/an-opinionated-guide-to-haskell-in-2018/). The template includes:+As it currently stands, ghc cannot read a file with fenced code-blocks that look like: -- some minor tweaks to protolude-- lens, foldl, formatting & text as must have libraries-- generic-lens-labels+```+\```haskell+\```+```++Given this, a file cannot be both a valid haskell file, and a markdown file that is rendered nicely by github. This would resolve with adoption of the [literate markdown ghc proposal](https://gitlab.haskell.org/ghc/ghc/wikis/literate-markdown).++template+===++A bare bones stack template is located in [other/readme-lhs.hsfiles](other/readme-lhs.hsfiles). It contains what you need to quickly get started with literate programming. workflow ---
− index.html
@@ -1,81 +0,0 @@-<meta charset="utf-8"> <link rel="stylesheet" href="other/lhs.css">-<script type="text/javascript" async- src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML">-</script>-<h1 id="readme-lhs-build-status"><a href="https://tonyday567.github.io/readme-lhs/index.html">readme-lhs</a> <a href="https://travis-ci.org/tonyday567/readme-lhs"><img src="https://travis-ci.org/tonyday567/readme-lhs.svg" alt="Build Status" /></a></h1>-<blockquote cite>-The language in which we express our ideas has a strong influence on our thought processes. ~ Knuth-</blockquote>-<p>A literate-programming friendly; tight work-flow stack template.</p>-<h2 id="otherreadme-lhs.hsfiles">other/readme-lhs.hsfiles</h2>-<pre><code>stack new project-name readme-lhs-cd project-name-stack build-$(stack path --local-install-root)/bin/readme-lhs-example-$(stack path --local-bin)/pandoc -f markdown -i other/header.md readme.md example/example.lhs other/footer.md -t html -o index.html --filter pandoc-include --mathjax</code></pre>-<p>Which:</p>-<ul class="incremental">-<li>runs an executable, which places some output in a markdown file</li>-<li>gathers together the readme.md and the example.lhs into an index.html</li>-</ul>-<h1 id="alternative-templates">alternative templates</h1>-<p>Or grab some of the other templates from this repo:</p>-<h2 id="otherreadme-hs.hsfiles">other/readme-hs.hsfiles</h2>-<p>like the lhs version, but hs based</p>-<h2 id="otherbatteries.hsfiles">other/batteries.hsfiles</h2>-<p>This is my latest working template, overly influenced by <a href="https://lexi-lambda.github.io/blog/2018/02/10/an-opinionated-guide-to-haskell-in-2018/">lexi-lambda's opinionated guide</a>. The template includes:</p>-<ul class="incremental">-<li>some minor tweaks to protolude</li>-<li>lens, foldl, formatting & text as must have libraries</li>-<li>generic-lens-labels</li>-</ul>-<h1 id="code">code</h1>-<h2 id="ghc-options"><a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html#flag-reference">ghc options</a></h2>-<div class="sourceCode"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="ot">{-# OPTIONS_GHC -Wall #-}</span></code></pre></div>-<h2 id="pragmas"><a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/lang.html">pragmas</a></h2>-<div class="sourceCode"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="co">-- doctest doesn't look at the cabal file, so you need pragmas here</span>-<span class="ot">{-# LANGUAGE NoImplicitPrelude #-}</span>-<span class="ot">{-# LANGUAGE OverloadedStrings #-}</span>-<span class="ot">{-# LANGUAGE DataKinds #-}</span>-<span class="ot">{-# LANGUAGE DeriveGeneric #-}</span>-<span class="ot">{-# LANGUAGE ScopedTypeVariables #-}</span>-<span class="ot">{-# LANGUAGE TypeOperators #-}</span>-<span class="ot">{-# LANGUAGE FlexibleInstances #-}</span></code></pre></div>-<h2 id="libraries"><a href="https://www.stackage.org/">libraries</a></h2>-<ul class="incremental">-<li><a href="https://www.stackage.org/package/protolude">protolude</a></li>-<li><a href="https://www.stackage.org/package/optparse-generic">optparse-generic</a></li>-</ul>-<div class="sourceCode"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">import </span><span class="dt">Protolude</span>-<span class="kw">import </span><span class="dt">Options.Generic</span></code></pre></div>-<h2 id="code-1">code</h2>-<ul class="incremental">-<li><a href="https://www.stackage.org/package/hoogle">hoogle</a></li>-</ul>-<div class="sourceCode"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Opts</span> w <span class="fu">=</span> <span class="dt">Opts</span>- {<span class="ot"> number ::</span> w <span class="ot">::</span><span class="fu">:</span> <span class="dt">Maybe</span> <span class="dt">Integer</span> <span class="fu"><?></span> <span class="st">"The number you want to product to"</span>- } <span class="kw">deriving</span> (<span class="dt">Generic</span>)--<span class="kw">instance</span> <span class="dt">ParseRecord</span> (<span class="dt">Opts</span> <span class="dt">Wrapped</span>)--<span class="ot">main ::</span> <span class="dt">IO</span> ()-main <span class="fu">=</span> <span class="kw">do</span>-<span class="ot"> o ::</span> <span class="dt">Opts</span> <span class="dt">Unwrapped</span> <span class="ot"><-</span> unwrapRecord <span class="st">"an example app for readme-lhs"</span>- <span class="kw">let</span> n <span class="fu">=</span> fromMaybe <span class="dv">10</span> (number o)- <span class="kw">let</span> answer <span class="fu">=</span> product [<span class="dv">1</span><span class="fu">..</span>n]- putStrLn (show answer <span class="fu"><></span> <span class="st">" 👍"</span><span class="ot"> ::</span> <span class="dt">Text</span>)- writeFile <span class="st">"other/answer.md"</span>- (<span class="st">"$\\prod_{i=1}^{"</span> <span class="fu"><></span> show n <span class="fu"><></span> <span class="st">"} i = "</span> <span class="fu"><></span>- show answer <span class="fu"><></span> <span class="st">"$"</span>)</code></pre></div>-<h2 id="output">output</h2>-<p><span class="math inline">\(\prod_{i=1}^{10} i = 3628800\)</span></p>-<h2 id="tests">tests</h2>-<p><a href="https://www.stackage.org/package/doctest">doctest</a></p>-<div class="sourceCode"><pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="co">-- | doctests</span>-<span class="co">-- >>> let n = 10</span>-<span class="co">-- >>> product [1..n]</span>-<span class="co">-- 3628800</span></code></pre></div>-<hr />-<div class="footer">-<p>Made with love 'n' care; and <a href="https://haskell-lang.org/">haskell</a>, <a href="https://pandoc.org">pandoc</a>, and <a href="https://docs.haskellstack.org/en/stable/README/">stack</a>.</p>-</div>
− other/batteries.hsfiles
@@ -1,476 +0,0 @@-{-# START_FILE .gitattributes #-}-other/* linguist-documentation-index.html linguist-documentation-{-# START_FILE .gitignore #-}-/.stack-work/-TAGS-*.DS_Store-{-# START_FILE .hlint.yaml #-}-- ignore: {name: Eta reduce}-- ignore: {name: Use if}-- ignore: {name: Use first}--# To generate a suitable file for HLint do:-# $ hlint --default > .hlint.yaml-{-# START_FILE .travis.yaml #-}-# This is the simple Travis configuration, which is intended for use-# on applications which do not require cross-platform and-# multiple-GHC-version support. For more information and other-# options, see:-#-# https://docs.haskellstack.org/en/stable/travis_ci/-#-# Copy these contents into the root directory of your Github project in a file-# named .travis.yml--# Use new container infrastructure to enable caching-sudo: false--# Do not choose a language; we provide our own build tools.-language: generic--# Caching so the next build will be fast too.-cache:- directories:- - $HOME/.stack--# Ensure necessary system libraries are present-addons:- apt:- packages:- - libgmp-dev--before_install:-# Download and unpack the stack executable-- mkdir -p ~/.local/bin-- export PATH=$HOME/.local/bin:$PATH-- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'--install:-# Build dependencies-- stack --no-terminal --install-ghc test --only-dependencies--script:-# Build the package, its tests, and its docs and run the tests-- stack --no-terminal test --haddock --no-haddock-deps-{-# START_FILE .weeder.yaml #-}-- package:- - name: {{name}}- - section:- - name: test:test- - message:- - name: Redundant build-depends entry- - depends: base-{-# START_FILE LICENSE #-}-Copyright {{author-name}}{{^author-name}}Author name here{{/author-name}} (c) {{year}}{{^year}}2017{{/year}}--All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:-- * Redistributions of source code must retain the above copyright- notice, this list of conditions and the following disclaimer.-- * Redistributions in binary form must reproduce the above- copyright notice, this list of conditions and the following- disclaimer in the documentation and/or other materials provided- with the distribution.-- * Neither the name of {{author-name}}{{^author-name}}Author name here{{/author-name}} nor the names of other- contributors may be used to endorse or promote products derived- from this software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-{-# START_FILE Setup.hs #-}-import Distribution.Simple-main = defaultMain-{-# START_FILE package.yaml #-}-name: {{name}}-version: '0.0.0.1'-synopsis: See readme.md-description: See readme.md for description.-category: project-author: {{author-name}}{{^author-name}}Author name here{{/author-name}}-maintainer: {{author-email}}{{^author-email}}example@example.com{{/author-email}}-copyright: {{copyright}}{{^copyright}}{{year}}{{^year}}2018{{/year}} {{authorName}}{{^authorName}}Author name here{{/authorName}}{{/copyright}}-license: BSD3-github: {{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}-extra-source-files:- - readme.md- - stack.yaml-dependencies:- - base >=4.7 && <5-ghc-options:- - -Wall- - -Wcompat- - -Wincomplete-record-updates- - -Wincomplete-uni-patterns- - -Wredundant-constraints-library:- source-dirs: src- dependencies:- - data-default- - flow- - foldl- - formatting- - generic-lens-labels- - lens- - protolude- - text- ghc-options:- - -funbox-strict-fields- exposed-modules:- - Batterylude-executables:- {{name}}:- main: {{name}}.hs- source-dirs: app- ghc-options:- - -funbox-strict-fields- - -threaded- - -rtsopts- - -with-rtsopts=-N- dependencies:- - {{name}}- - optparse-generic- - protolude-tests:- test:- main: test.hs- source-dirs: test- dependencies:- - doctest- - protolude-{-# START_FILE readme.md #-}-{{name}}-===--[](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) [](https://hackage.haskell.org/package/{{name}}) [](http://stackage.org/lts/package/{{name}}) [](http://stackage.org/nightly/package/{{name}}) --recipe------```-stack build --test --fast --haddock --exec "$(stack path --local-install-root)/bin/{{name}}" --ghc-options=-Werror --file-watch-```--To generate an index.html--```-stack build --exec "$(stack path --local-bin)/pandoc -f markdown -i other/header.md readme.md other/footer.md -t html -o index.html --filter pandoc-include --mathjax"-```--To generate a per-project hoogle--```-stack hoogle -- generate --local--```--To serve hoogle search--```-stack hoogle -- server --local --port=8080-```--- [hoogle](http://localhost:8080/)--reference------- [lexi-lambda's opinionated guide](https://lexi-lambda.github.io/blog/2018/02/10/an-opinionated-guide-to-haskell-in-2018/)--- [ghc options](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html#flag-reference)-- [pragmas](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/lang.html)-- [hoogle](https://www.stackage.org/package/hoogle)-- [doctest](https://www.stackage.org/package/doctest)--Included [libraries](https://www.stackage.org/)------- [data-default](https://www.stackage.org/package/data-default)-- [foldl](https://www.stackage.org/package/foldl)-- [formatting](https://www.stackage.org/package/formatting)-- [lens](https://www.stackage.org/package/protolude)-- [optparse-generic](https://www.stackage.org/package/optparse-generic)-- [protolude](https://www.stackage.org/package/protolude)-- [text](https://www.stackage.org/package/text)-{-# START_FILE stack.yaml #-}-resolver: nightly-2018-02-17--packages:- - .--extra-deps:- # for hoogle- - http-conduit-2.3.0- - generic-lens-labels-0.1.0.2-{-# START_FILE app/{{name}}.hs #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE OverloadedLabels #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# OPTIONS_GHC -Wall #-}--import Options.Generic-import Batterylude--newtype Opts w = Opts- { numBatteries :: w ::: Maybe Int <?> "number of {{name}} desired"- } deriving (Generic)--instance ParseRecord (Opts Wrapped)--main :: IO ()-main = do- o :: Opts Unwrapped <- unwrapRecord "{{name}}"- let n = fromMaybe (view #countBatteries (def::ConfigBatteries)) (numBatteries o)- putStrLn ("👍" :: Text)- putStrLn (statement1 (def |> #countBatteries .~ n))- statement2---- | doctests--- >>> :main--- 👍--- There are 99 batteries.--- This is not a battery.--- This is an effect of a battery.----{-# START_FILE other/footer.md #-}-***--<div class="footer">-Made with love 'n' care; and-[haskell](https://haskell-lang.org/),-[pandoc](https://pandoc.org), and-[stack](https://docs.haskellstack.org/en/stable/README/).-</div>-{-# START_FILE other/header.md #-}-<meta charset="utf-8">-<link rel="stylesheet" href="other/lhs.css">-<script type="text/javascript" async- src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML">-</script>-{-# START_FILE other/lhs.css #-}-* {- background: transparent;- border: 0;- font-size: 100%;- margin: 0;- padding: 0;- text-decoration: none;- vertical-align: baseline; }--body {- background-color: #fafafa;- color: #3c3c3c;- font-family: "Lora", "Seravek", sans-serif;- line-height: 1.5;- word-wrap: break-word;- min-width: 200px;- max-width: 900px;- margin: 0 auto;- padding: 3em; }- body a {- background-color: transparent;- color: #3c3c3c;- border-bottom-style: solid;- border-bottom-width: 1px;- border-bottom-color: #969696;- text-decoration: none; }- body a:visited {- border-bottom-style: solid;- border-bottom-width: 1px;- border-bottom-color: #bd67c9;- text-decoration: none; }- body a:visited:hover {- opacity: 0.7; }- body a:hover {- opacity: 0.7; }- body h1 {- font-size: 2em;- padding-top: 1em;- padding-bottom: 0.5em; }- body h2 {- font-size: 1.5em;- padding-top: 1em;- padding-bottom: 0.5em; }- body h1, body h2 {- font-family: "Raleway", serif;- color: #222222; }- body h1 a, body h2 a {- background-color: transparent;- color: #222222;- text-decoration: none;- border-bottom-style: solid;- border-bottom-width: 2px;- border-bottom-color: #969696; }- body h1 a:visited, body h2 a:visited {- opacity: 0.7;- color: #222222;- text-decoration: none;- border-bottom-style: solid;- border-bottom-width: 2px;- border-bottom-color: #bd67c9; }- body h1 a:hover, body h2 a:hover {- opacity: 0.7;- text-decoration: none; }- body blockquote {- border-left: 0.25rem solid #c8c8c8;- font-style: italic;- margin: 0.5rem 0 1rem 0;- padding: 0 0 0 1rem;- color: #646464; }- body .footer {- color: #888888;- font-size: 0.75em;- text-align: right; }- body hr {- height: 0;- margin: 1em 0;- overflow: hidden;- background: transparent;- border: 0;- border-bottom: 1px solid #c8c8c8; }- body pre {- color: #ab1f27;- background-color: #f5f0f0;- padding: 0.75em;- overflow: auto; }- body ul {- margin: 0.5rem 0;- padding-left: 0; }- body ul li {- counter-increment: this;- line-height: 1.313em;- list-style: none;- position: relative; }- body ul li:after {- color: #646464;- content: "-";- left: -1em;- position: absolute;- top: 0; }--.sourceCode {- background-color: whitesmoke;- color: #284628;- font-family: "Inconsolata", mono;- font-size: 1em; }- .sourceCode .ot, .sourceCode .kw {- color: #284628; }- .sourceCode .dt {- color: #ab1f27; }- .sourceCode .dv, .sourceCode .st {- color: #2536d6; }- .sourceCode .co {- color: #646464;- font-style: italic; }- .sourceCode .fu {- color: #e347e4; }-{-# START_FILE src/Batterylude.hs #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE OverloadedLabels #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# OPTIONS_GHC -Wall #-}-{-# OPTIONS_GHC -Wno-unused-top-binds #-}--module Batterylude- ( module Protolude- , (<>)- , (.)- , id- , String- , module Control.Lens- , module Flow- , module Data.Default- , module Formatting- , statement1- , statement2- , ConfigBatteries(ConfigBatteries)- ) where--import Control.Category ((.), id)-import qualified Control.Foldl as L-import Control.Lens- hiding (Fold, Strict, Unwrapped, Wrapped, (.>), (<&>), (<.), (<.>),- (<|), (|>), from, to, uncons, unsnoc)-import Data.Default-import Data.Generics.Labels ()-import Data.Semigroup ((<>))-import qualified Data.Text as Text-import qualified Data.Text.IO as Text-import Flow-import Formatting-import GHC.Base (String)-import Protolude hiding ((%), (.), (<>))---- | there is invariably a Config for a project-data ConfigBatteries = ConfigBatteries- { countBatteries :: Int- , hasBatteries :: Bool- } deriving (Show, Eq, Generic)--instance Default ConfigBatteries where- def = ConfigBatteries 99 True---- | formatting example-statement1 :: ConfigBatteries -> Text-statement1 cfg =- sformat- ("There " %text % " " %text % " " %text%".")- (bool "are" "is" (view #countBatteries cfg == 1))- (bool "no" (show <| view #countBatteries cfg) (view #hasBatteries cfg))- (bool "batteries" "battery" (view #countBatteries cfg == 1))---- | foldl example-statement2 :: IO ()-statement2 = do- Text.putStrLn <|- L.fold- (L.Fold (\x a -> x <> " " <> a) ("This" :: Text) id)- ["is", "not", "a", "battery."]- Text.putStrLn <|- Text.intercalate " " ["This", "is", "an", "effect", "of", "a", "battery."]-{-# START_FILE test/test.hs #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# OPTIONS_GHC -Wall #-}--module Main where--import Protolude-import Test.DocTest--main :: IO ()-main =- doctest ["app/{{name}}.hs"]
− other/readme-hs.hsfiles
@@ -1,335 +0,0 @@-{-# START_FILE app/example.md #-}-{{name}}-===--[](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) [](https://hackage.haskell.org/package/{{name}}) [](http://stackage.org/lts/package/{{name}}) [](http://stackage.org/nightly/package/{{name}}) --results------```include-other/results.md-```--recipe------```-stack build --test --exec "$(stack path --local-install-root)/bin/{{name}}" --exec "$(stack path --local-bin)/pandoc -f markdown -i other/header.md app/example.md other/footer.md -t html -o index.html --filter pandoc-include --mathjax" --exec "$(stack path --local-bin)/pandoc -f markdown -i app/example.md -t markdown -o readme.md --filter pandoc-include --mathjax" --file-watch-```--reference------- [ghc options](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html#flag-reference)-- [pragmas](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/lang.html)-- [libraries](https://www.stackage.org/)-- [protolude](https://www.stackage.org/package/protolude)-- [optparse-generic](https://www.stackage.org/package/optparse-generic)-- [hoogle](https://www.stackage.org/package/hoogle)-- [doctest](https://www.stackage.org/package/doctest)--{-# START_FILE app/example.hs #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE FlexibleInstances #-}-{-# OPTIONS_GHC -Wall #-}--import Options.Generic-import Protolude--data Opts w = Opts- { number :: w ::: Maybe Integer <?> "The number you want to product to"- } deriving (Generic)--instance ParseRecord (Opts Wrapped)--main :: IO ()-main = do- o :: Opts Unwrapped <- unwrapRecord "{{name}}"- let n = fromMaybe 10 (number o)- let answer = product [1 .. n]- putStrLn (show answer <> " 👍" :: Text)- writeFile- "other/answer.md"- ("$\\prod_{i=1}^{" <> show n <> "} i = " <> show answer <> "$")---- | doctests--- >>> let n = 10--- >>> product [1..n]--- 3628800--{-# START_FILE package.yaml #-}-name: {{name}}-version: '0.0.1'-synopsis: See readme.md-description: See readme.md for description.-category: project-author: {{author-name}}{{^author-name}}Author name here{{/author-name}}-maintainer: tonyday567@gmail.com-copyright: {{copyright}}{{^copyright}}{{year}}{{^year}}2017{{/year}} {{authorName}}{{^authorName}}Author name here{{/authorName}}{{/copyright}}-license: BSD3-github: {{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}-extra-source-files:- - stack.yaml-default-extensions:- - NegativeLiterals- - NoImplicitPrelude- - OverloadedStrings- - UnicodeSyntax-dependencies:-- base >=4.7 && <5-executables:- {{name}}:- main: example.hs- source-dirs: app- ghc-options:- - -funbox-strict-fields- - -fforce-recomp- - -threaded- - -rtsopts- - -with-rtsopts=-N- dependencies:- - protolude- - optparse-generic-tests:- test:- main: test.hs- source-dirs: test- dependencies:- - doctest- - protolude--{-# START_FILE .gitignore #-}-/.stack-work/-TAGS--{-# START_FILE .gitattributes #-}-other/* linguist-documentation-index.html linguist-documentation--{-# START_FILE Setup.hs #-}-import Distribution.Simple-main = defaultMain--{-# START_FILE LICENSE #-}-Copyright {{author-name}}{{^author-name}}Author name here{{/author-name}} (c) {{year}}{{^year}}2017{{/year}}--All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are met:-- * Redistributions of source code must retain the above copyright- notice, this list of conditions and the following disclaimer.-- * Redistributions in binary form must reproduce the above- copyright notice, this list of conditions and the following- disclaimer in the documentation and/or other materials provided- with the distribution.-- * Neither the name of {{author-name}}{{^author-name}}Author name here{{/author-name}} nor the names of other- contributors may be used to endorse or promote products derived- from this software without specific prior written permission.--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.--{-# START_FILE .travis.yml #-}-# This is the simple Travis configuration, which is intended for use-# on applications which do not require cross-platform and-# multiple-GHC-version support. For more information and other-# options, see:-#-# https://docs.haskellstack.org/en/stable/travis_ci/-#-# Copy these contents into the root directory of your Github project in a file-# named .travis.yml--# Use new container infrastructure to enable caching-sudo: false--# Do not choose a language; we provide our own build tools.-language: generic--# Caching so the next build will be fast too.-cache:- directories:- - $HOME/.stack--# Ensure necessary system libraries are present-addons:- apt:- packages:- - libgmp-dev--before_install:-# Download and unpack the stack executable-- mkdir -p ~/.local/bin-- export PATH=$HOME/.local/bin:$PATH-- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'--install:-# Build dependencies-- stack --no-terminal --install-ghc test --only-dependencies--script:-# Build the package, its tests, and its docs and run the tests-- stack --no-terminal test --haddock --no-haddock-deps--{-# START_FILE other/lhs.css #-}-* {- background: transparent;- border: 0;- font-size: 100%;- margin: 0;- padding: 0;- text-decoration: none;- vertical-align: baseline; }--body {- background-color: #fafafa;- color: #3c3c3c;- font-family: "Lora", "Seravek", sans-serif;- line-height: 1.5;- word-wrap: break-word;- min-width: 200px;- max-width: 900px;- margin: 0 auto;- padding: 3em; }- body a {- background-color: transparent;- color: #3c3c3c;- border-bottom-style: solid;- border-bottom-width: 1px;- border-bottom-color: #969696;- text-decoration: none; }- body a:visited {- border-bottom-style: solid;- border-bottom-width: 1px;- border-bottom-color: #bd67c9;- text-decoration: none; }- body a:visited:hover {- opacity: 0.7; }- body a:hover {- opacity: 0.7; }- body h1 {- font-size: 2em;- padding-top: 1em;- padding-bottom: 0.5em; }- body h2 {- font-size: 1.5em;- padding-top: 1em;- padding-bottom: 0.5em; }- body h1, body h2 {- font-family: "Raleway", serif;- color: #222222; }- body h1 a, body h2 a {- background-color: transparent;- color: #222222;- text-decoration: none;- border-bottom-style: solid;- border-bottom-width: 2px;- border-bottom-color: #969696; }- body h1 a:visited, body h2 a:visited {- opacity: 0.7;- color: #222222;- text-decoration: none;- border-bottom-style: solid;- border-bottom-width: 2px;- border-bottom-color: #bd67c9; }- body h1 a:hover, body h2 a:hover {- opacity: 0.7;- text-decoration: none; }- body blockquote {- border-left: 0.25rem solid #c8c8c8;- font-style: italic;- margin: 0.5rem 0 1rem 0;- padding: 0 0 0 1rem;- color: #646464; }- body .footer {- color: #888888;- font-size: 0.75em;- text-align: right; }- body hr {- height: 0;- margin: 1em 0;- overflow: hidden;- background: transparent;- border: 0;- border-bottom: 1px solid #c8c8c8; }- body pre {- color: #ab1f27;- background-color: #f5f0f0;- padding: 0.75em;- overflow: auto; }- body ul {- margin: 0.5rem 0;- padding-left: 0; }- body ul li {- counter-increment: this;- line-height: 1.313em;- list-style: none;- position: relative; }- body ul li:after {- color: #646464;- content: "-";- left: -1em;- position: absolute;- top: 0; }--.sourceCode {- background-color: whitesmoke;- color: #284628;- font-family: "Inconsolata", mono;- font-size: 1em; }- .sourceCode .ot, .sourceCode .kw {- color: #284628; }- .sourceCode .dt {- color: #ab1f27; }- .sourceCode .dv, .sourceCode .st {- color: #2536d6; }- .sourceCode .co {- color: #646464;- font-style: italic; }- .sourceCode .fu {- color: #e347e4; }--{-# START_FILE other/header.md #-}-<meta charset="utf-8">-<link rel="stylesheet" href="other/lhs.css">-<script type="text/javascript" async- src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML">-</script>--{-# START_FILE other/footer.md #-}-***--<div class="footer">-Powered by [haskell](https://haskell-lang.org/), [stack](https://docs.haskellstack.org/en/stable/README/) and [pandoc](http://pandoc.org/).-</div>--{-# START_FILE test/test.hs #-}-{-# OPTIONS_GHC -Wall #-}--module Main where--import Protolude-import Test.DocTest--main :: IO ()-main = do- doctest ["app/example.hs"]
other/readme-lhs.hsfiles view
@@ -5,73 +5,58 @@ [](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) [](https://hackage.haskell.org/package/{{name}}) [](http://stackage.org/lts/package/{{name}}) [](http://stackage.org/nightly/package/{{name}}) ```-stack build --test --exec "$(stack path --local-install-root)/bin/{{name}}" --exec "$(stack path --local-bin)/pandoc -f markdown+lhs -i other/header.md app/example.lhs other/footer.md -t html -o index.html --filter pandoc-include --mathjax" --file-watch+stack build --test --exec "$(stack path --local-install-root)/bin/{{name}}" --file-watch ``` {-# START_FILE app/example.lhs #-}+---+pagetitle: {{name}}+---+ [{{name}}](https://github.com/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) example === [ghc options](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html#flag-reference) --- -\begin{code}-{-# OPTIONS_GHC -Wall #-}-\end{code}+> {-# OPTIONS_GHC -Wall #-} [pragmas](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/lang.html) --- -\begin{code}--- doctest doesn't look at the cabal file, so you need pragmas here-{-# LANGUAGE NoImplicitPrelude #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE FlexibleInstances #-}-\end{code}+> {-# LANGUAGE NoImplicitPrelude #-}+> {-# LANGUAGE OverloadedStrings #-}+> {-# LANGUAGE DataKinds #-}+> {-# LANGUAGE DeriveGeneric #-}+> {-# LANGUAGE ScopedTypeVariables #-}+> {-# LANGUAGE TypeOperators #-}+> {-# LANGUAGE FlexibleInstances #-} [libraries](https://www.stackage.org/) --- - [protolude](https://www.stackage.org/package/protolude)-- [optparse-generic](https://www.stackage.org/package/optparse-generic)+- [readme-lhs](https://www.hackage.org/package/readme-lhs) -\begin{code}-import Protolude-import Options.Generic-\end{code}+> import Protolude+> import Readme.Lhs code --- - [hoogle](https://www.stackage.org/package/hoogle) -\begin{code}-data Opts w = Opts- { number :: w ::: Maybe Integer <?> "The number you want to product to"- } deriving (Generic)--instance ParseRecord (Opts Wrapped)+> main :: IO ()+> main = do+> let n = 10+> let answer = product [1..n::Integer]+> void $ runOutput ("app/example.lhs", LHS) ("readme.md", GitHubMarkdown) $ do+> output "example" (show answer) -main :: IO ()-main = do- o :: Opts Unwrapped <- unwrapRecord "{{name}}"- let n = fromMaybe 10 (number o)- let answer = product [1..n]- putStrLn (show answer <> " 👍" :: Text)- writeFile "other/answer.md"- ("$\\prod_{i=1}^{" <> show n <> "} i = " <>- show answer <> "$")-\end{code}+10! is equal to: -output----+```{.output .example} -```include-other/answer.md ``` tests@@ -79,57 +64,76 @@ - [doctest](https://www.stackage.org/package/doctest) -\begin{code}--- | doctests--- >>> let n = 10--- >>> product [1..n]--- 3628800-\end{code}--{-# START_FILE package.yaml #-}+> -- | doctests+> -- >>> let n = 10+> -- >>> product [1..n]+> -- 3628800+{-# START_FILE {{name}}.cabal #-} name: {{name}}-version: '0.0.0.1'+version: 0.0.0.1 synopsis: See readme.md description: See readme.md for description.+cabal-version: 2.0 category: project author: {{author-name}}{{^author-name}}Author name here{{/author-name}}-maintainer: tonyday567@gmail.com+maintainer: {{author-email}} copyright: {{copyright}}{{^copyright}}{{year}}{{^year}}2017{{/year}} {{authorName}}{{^authorName}}Author name here{{/authorName}}{{/copyright}} license: BSD3-github: {{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}+homepage: https://github.com/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}#readme+bug-reports: https://github.com/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}/issues+build-type: Simple extra-source-files:- - readme.md- - stack.yaml-default-extensions:- - NegativeLiterals- - NoImplicitPrelude- - OverloadedStrings- - UnicodeSyntax-dependencies:- - base >=4.7 && <5-executables:- {{name}}:- main: example.lhs- source-dirs: app- ghc-options:- - -funbox-strict-fields- - -fforce-recomp- - -threaded- - -rtsopts- - -with-rtsopts=-N- dependencies:- - protolude- - optparse-generic-tests:- test:- main: test.hs- source-dirs: test- dependencies:- - doctest- - protolude+ readme.md+source-repository head+ type: git+ location: https://github.com/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}} +executable {{name}}+ main-is: example.lhs+ hs-source-dirs: app+ default-extensions:+ NegativeLiterals+ NoImplicitPrelude+ OverloadedStrings+ UnicodeSyntax+ ghc-options:+ -funbox-strict-fields+ -fforce-recomp+ -threaded+ -rtsopts+ -with-rtsopts=-N+ build-depends:+ base >= 4.7 && < 5+ , doctest ^>= 0.16.0.1+ , protolude ^>= 0.2.3+ , readme-lhs ^>= 0.2.0+ default-language: Haskell2010++test-suite test+ type: exitcode-stdio-1.0+ main-is: test.hs+ hs-source-dirs: test+ default-extensions:+ NegativeLiterals+ NoImplicitPrelude+ OverloadedStrings+ UnicodeSyntax+ ghc-options:+ -funbox-strict-fields+ -fforce-recomp+ -threaded+ -rtsopts+ -with-rtsopts=-N+ build-depends:+ base >= 4.7 && < 5+ , doctest ^>= 0.16.0.1+ , protolude ^>= 0.2.3+ , readme-lhs ^>= 0.2.0+ default-language: Haskell2010+ {-# START_FILE .gitignore #-} /.stack-work/+/dist-newstyle/ TAGS {-# START_FILE .gitattributes #-}@@ -141,7 +145,7 @@ main = defaultMain {-# START_FILE LICENSE #-}-Copyright {{author-name}}{{^author-name}}Author name here{{/author-name}} (c) {{year}}{{^year}}2017{{/year}}+Copyright {{author-name}}{{^author-name}}Author name here{{/author-name}} (c) {{year}}{{^year}}2020{{/year}} All rights reserved. @@ -173,179 +177,68 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {-# START_FILE .travis.yml #-}-# This is the simple Travis configuration, which is intended for use-# on applications which do not require cross-platform and-# multiple-GHC-version support. For more information and other-# options, see:-#-# https://docs.haskellstack.org/en/stable/travis_ci/-#-# Copy these contents into the root directory of your Github project in a file-# named .travis.yml--# Use new container infrastructure to enable caching-sudo: false--# Do not choose a language; we provide our own build tools.-language: generic+language: haskell+dist: trusty -# Caching so the next build will be fast too. cache: directories: - $HOME/.stack+ - $TRAVIS_BUILD_DIR/.stack-work+ - $TRAVIS_BUILD_DIR/dist-newstyle -# Ensure necessary system libraries are present-addons:- apt:- packages:- - libgmp-dev+cabal: "2.4" -before_install:-# Download and unpack the stack executable-- mkdir -p ~/.local/bin-- export PATH=$HOME/.local/bin:$PATH-- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'+matrix:+ include:+ - env: BUILD=cabal+ ghc: "8.6.5"+ - env: BUILD=stack ARGS="--resolver lts-13.29 --system-ghc"+ ghc: "8.6.5"+ # a -Werror build that is allowed to fail+ - env: BUILD=werror ARGS="--resolver lts-13.29 --system-ghc"+ ghc: "8.6.5"+ - env: BUILD=stack ARGS="--resolver nightly --system-ghc"+ ghc: "8.6.5" + allow_failures:+ - env: BUILD=stack ARGS="--resolver nightly --system-ghc"+ - env: BUILD=werror ARGS="--resolver lts-13.29 --system-ghc"+ install:-# Build dependencies-- stack --no-terminal --install-ghc test --only-dependencies+- |+ case "$BUILD" in+ cabal)+ cabal --version+ ghc --version+ ;;+ stack|werror)+ ghc --version+ PATH=$HOME/.local/bin:$PATH+ mkdir -p ~/.local/bin+ if [ `uname` = "Darwin" ]+ then+ travis_retry curl --insecure -L https://get.haskellstack.org/stable/osx-x86_64.tar.gz | tar xz --strip-components=1 --include '*/stack' -C ~/.local/bin+ else+ travis_retry curl -L https://get.haskellstack.org/stable/linux-x86_64.tar.gz | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'+ fi+ ;;+ esac script:-# Build the package, its tests, and its docs and run the tests-- stack --no-terminal test --haddock --no-haddock-deps--{-# START_FILE other/lhs.css #-}-* {- background: transparent;- border: 0;- font-size: 100%;- margin: 0;- padding: 0;- text-decoration: none;- vertical-align: baseline; }--body {- background-color: #fafafa;- color: #3c3c3c;- font-family: "Lora", "Seravek", sans-serif;- line-height: 1.5;- word-wrap: break-word;- min-width: 200px;- max-width: 900px;- margin: 0 auto;- padding: 3em; }- body a {- background-color: transparent;- color: #3c3c3c;- border-bottom-style: solid;- border-bottom-width: 1px;- border-bottom-color: #969696;- text-decoration: none; }- body a:visited {- border-bottom-style: solid;- border-bottom-width: 1px;- border-bottom-color: #bd67c9;- text-decoration: none; }- body a:visited:hover {- opacity: 0.7; }- body a:hover {- opacity: 0.7; }- body h1 {- font-size: 2em;- padding-top: 1em;- padding-bottom: 0.5em; }- body h2 {- font-size: 1.5em;- padding-top: 1em;- padding-bottom: 0.5em; }- body h1, body h2 {- font-family: "Raleway", serif;- color: #222222; }- body h1 a, body h2 a {- background-color: transparent;- color: #222222;- text-decoration: none;- border-bottom-style: solid;- border-bottom-width: 2px;- border-bottom-color: #969696; }- body h1 a:visited, body h2 a:visited {- opacity: 0.7;- color: #222222;- text-decoration: none;- border-bottom-style: solid;- border-bottom-width: 2px;- border-bottom-color: #bd67c9; }- body h1 a:hover, body h2 a:hover {- opacity: 0.7;- text-decoration: none; }- body blockquote {- border-left: 0.25rem solid #c8c8c8;- font-style: italic;- margin: 0.5rem 0 1rem 0;- padding: 0 0 0 1rem;- color: #646464; }- body .footer {- color: #888888;- font-size: 0.75em;- text-align: right; }- body hr {- height: 0;- margin: 1em 0;- overflow: hidden;- background: transparent;- border: 0;- border-bottom: 1px solid #c8c8c8; }- body pre {- color: #ab1f27;- background-color: #f5f0f0;- padding: 0.75em;- overflow: auto; }- body ul {- margin: 0.5rem 0;- padding-left: 0; }- body ul li {- counter-increment: this;- line-height: 1.313em;- list-style: none;- position: relative; }- body ul li:after {- color: #646464;- content: "-";- left: -1em;- position: absolute;- top: 0; }--.sourceCode {- background-color: whitesmoke;- color: #284628;- font-family: "Inconsolata", mono;- font-size: 1em; }- .sourceCode .ot, .sourceCode .kw {- color: #284628; }- .sourceCode .dt {- color: #ab1f27; }- .sourceCode .dv, .sourceCode .st {- color: #2536d6; }- .sourceCode .co {- color: #646464;- font-style: italic; }- .sourceCode .fu {- color: #e347e4; }--{-# START_FILE other/header.md #-}-<meta charset="utf-8">-<link rel="stylesheet" href="other/lhs.css">-<script type="text/javascript" async- src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML">-</script>--{-# START_FILE other/footer.md #-}-***--<div class="footer">-Powered by [haskell](https://haskell-lang.org/), [stack](https://docs.haskellstack.org/en/stable/README/) and [pandoc](http://pandoc.org/).-</div>-+- |+ case "$BUILD" in+ cabal)+ cabal v2-update+ cabal v2-build all+ cabal v2-test all --enable-test+ ;;+ stack)+ stack --no-terminal $ARGS test --haddock --no-haddock-deps+ ;;+ werror)+ stack --no-terminal $ARGS test --haddock --no-haddock-deps --ghc-options -Werror --ghc-options -Wcompat --ghc-options -Wincomplete-record-updates --ghc-options -Wincomplete-uni-patterns --ghc-options -Wredundant-constraints+ ;;+ esac {-# START_FILE test/test.hs #-} {-# OPTIONS_GHC -Wall #-} @@ -357,3 +250,11 @@ main :: IO () main = do doctest ["app/example.lhs"]+{-# START_FILE stack.yaml #-}+resolver: lts-14.11++packages:+ - .++extra-deps:+ - readme-lhs-0.2.1
readme-lhs.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: readme-lhs-version: 0.2.0+version: 0.2.1 synopsis: See readme.md description: See readme.md for description. category: Development@@ -14,11 +14,7 @@ build-type: Simple extra-source-files: readme.md- index.html- stack.yaml other/readme-lhs.hsfiles- other/readme-hs.hsfiles- other/batteries.hsfiles source-repository head type: git@@ -77,5 +73,5 @@ base >=4.7 && <5 , doctest , protolude- , tasty+ , readme-lhs default-language: Haskell2010
readme.md view
@@ -3,24 +3,9 @@ <blockquote cite> The language in which we express our ideas has a strong influence on our-thought processes. \~ Knuth+thought processes. Knuth </blockquote> -This is an example of mixing literate haskell with markdown, and in-using Readme.Lhs. The file is composed of several elements:--- literate haskell. Bird-tracks are used, as the alternative method is- latex rather than markdown, which doesn’t survive a pandoc round- trip.-- markdown. All non bird-tracked lines are considered to be markdown.- It’s probably incompatible with haddock, but this may well resolve- with adoption of the [literate markdown ghc- proposal](https://gitlab.haskell.org/ghc/ghc/wikis/literate-markdown).-- fenced code blocks with an output class, which are used to insert- computation results. The fenced code blocks look like:-- \`\`\`{.output .example} \`\`\`- [ghc options](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/flags.html#flag-reference) -------------------------------------------------------------------------------------------------------- @@ -32,7 +17,6 @@ ------------------------------------------------------------------------------------ ``` haskell--- doctest doesn't look at the cabal file, so you need pragmas here {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DataKinds #-}@@ -62,7 +46,7 @@ main = do let n = 10 let answer = product [1..n::Integer]- _ <- runOutput ("example.lhs", LHS) ("readme.md", GitHubMarkdown) $ do+ void $ runOutput ("example.lhs", LHS) ("readme.md", GitHubMarkdown) $ do output "example1" "Simple example of an output" ``` @@ -80,35 +64,47 @@ 3628800 ``` -``` haskell- pure ()-```- Output that doesn’t exist is simply cleared. ``` output ``` -hsfiles writeup-===============+Technicals+========== -A literate-programming friendly; tight work-flow stack template.+This is an example of mixing literate haskell with markdown, and in+using readme-lhs. The file is composed of several elements: -other/readme-lhs.hsfiles+- literate haskell. Bird-tracks are used, as the alternative lhs+ method is latex. Pandoc can read this, but defaults to bird tracks+ when rendering `markdown+lhs`.+- markdown. All non bird-tracked lines are considered to be markdown.+ It’s probably incompatible with haddock. This might be easily+ fixable.+- fenced code blocks with an output class, which are used to insert+ computation results. The fenced code blocks look like: -other/batteries.hsfiles------------------------+ \`\`\`{.output .example} \`\`\` -This is my latest working template, overly influenced by [lexi-lambda’s-opinionated-guide](https://lexi-lambda.github.io/blog/2018/02/10/an-opinionated-guide-to-haskell-in-2018/).-The template includes:+As it currently stands, ghc cannot read a file with fenced code-blocks+that look like: -- some minor tweaks to protolude-- lens, foldl, formatting & text as must have libraries-- generic-lens-labels+ \```haskell+ \``` +Given this, a file cannot be both a valid haskell file, and a markdown+file that is rendered nicely by github. This would resolve with adoption+of the [literate markdown ghc+proposal](https://gitlab.haskell.org/ghc/ghc/wikis/literate-markdown).++template+========++A bare bones stack template is located in+[other/readme-lhs.hsfiles](other/readme-lhs.hsfiles). It contains what+you need to quickly get started with literate programming.+ workflow -------- - stack build --exec "$(stack path --local-install-root)/bin/readme-lhs-example" --file-watch+ stack build --test --exec "$(stack path --local-install-root)/bin/readme-lhs-example" --file-watch
src/Readme/Lhs.hs view
@@ -9,9 +9,14 @@ , Flavour(..) , readPandoc , renderMarkdown+ , Output(..)+ , OutputMap , output , runOutput , tweakHaskellCodeBlock+ , Block(..)+ , module Text.Pandoc.Definition+ , Alignment(..) ) where import Protolude@@ -21,8 +26,11 @@ import Text.Pandoc import qualified Data.Map as Map -type Output = Map Text Text+-- | output can be native pandoc, or text that replaces or inserts into the output code block.+data Output = Native [Block] | Replace Text | Fence Text +type OutputMap = Map Text Output+ -- | doctest -- >>> :set -XOverloadedStrings @@ -71,7 +79,9 @@ -- exts GitHubMarkdown is equivalent to 'gfm' exts :: Flavour -> Extensions exts LHS = enableExtension Ext_literate_haskell $ getDefaultExtensions "markdown"-exts GitHubMarkdown = githubMarkdownExtensions+exts GitHubMarkdown =+ enableExtension Ext_fenced_code_attributes+ githubMarkdownExtensions {- | literate haskell code blocks comes out of markdown+lhs to native pandoc with the following classes:@@ -104,31 +114,38 @@ writeMarkdown (def :: WriterOptions) { writerExtensions = exts f} (Pandoc meta (tweakHaskellCodeBlock <$> bs)) -insertOutput :: Output -> Block -> Block+insertOutput :: OutputMap -> Block -> [Block] insertOutput m b = case b of (b'@ (CodeBlock (id', classes, kv) _)) ->- bool b'+ bool [b'] (maybe- (CodeBlock (id', classes, kv) mempty)- (\x -> CodeBlock (id', classes, kv) . maybe mempty Text.unpack $ Map.lookup x m)+ [CodeBlock (id', classes, kv) mempty]+ (\x ->+ (maybe [CodeBlock (id', classes, kv) mempty]+ (\ot -> case ot of+ Fence t -> [CodeBlock (id', classes, kv) . Text.unpack $ t]+ Replace t -> [plain t]+ Native bs -> bs+ )+ (Map.lookup x m))) (headMay . Protolude.filter ((`elem` classes) . Text.unpack) . Map.keys $ m)) ("output" `elem` classes)- b' -> b'+ b' -> [b'] -- | add an output key-value pair to state-output :: (Monad m) => Text -> Text -> StateT (Map Text Text) m ()+output :: (Monad m) => Text -> Output -> StateT OutputMap m () output k v = modify (Map.insert k v) -- | insert outputs into a new file runOutput :: (FilePath, Flavour) -> (FilePath, Flavour)- -> StateT Output IO ()+ -> StateT OutputMap IO () -> IO (Either PandocError ()) runOutput (fi, flavi) (fo, flavo) out = do m <- execStateT out Map.empty p <- readPandoc fi flavi let w = do- p' <- fmap (\(Pandoc meta bs) -> Pandoc meta (insertOutput m <$> bs)) p+ p' <- fmap (\(Pandoc meta bs) -> Pandoc meta (mconcat $ insertOutput m <$> bs)) p renderMarkdown flavo p' either (pure . Left) (\t -> writeFile fo t >> pure (Right ())) w
− stack.yaml
@@ -1,3 +0,0 @@-resolver: lts-13.21--
test/test.hs view
@@ -1,12 +1,25 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -Wall #-}+{-# OPTIONS_GHC -fno-warn-unused-imports #-} module Main where import Protolude import Test.DocTest+import Readme.Lhs +-- | doctest+-- >>> :set -XOverloadedStrings++-- | The main differences between LHS and GitHubMarkdown is that GitHubMarkdown parses bird tracks as a BlockQuote.+-- >>> readPandoc "test/test.md" GitHubMarkdown+-- Right (Pandoc (Meta {unMeta = fromList []}) [Para [Str "haskell",Space,Str "LHS",Space,Str "style"],CodeBlock ("",["sourceCode","literate","haskell"],[]) "",Para [Str "bird-tracks"],BlockQuote [Para [Str "import",Space,Str "Readme.Lhs"]],Para [Str "code",Space,Str "block"],CodeBlock ("",[],[]) "indented\nunfenced code",Para [Str "github-style",Space,Str "fenced",Space,Str "code",Space,Str "blocks"],CodeBlock ("",["haskell"],[]) "",Para [Code ("",[],[]) "output test1"],Para [Str "php-style",Space,Str "fenced",Space,Str "code",Space,Str "blocks"],CodeBlock ("",["output","test1"],[]) ""])+-- >>> readPandoc "test/test.md" LHS+-- Right (Pandoc (Meta {unMeta = fromList []}) [Para [Str "haskell",Space,Str "LHS",Space,Str "style"],CodeBlock ("",["sourceCode","literate","haskell"],[]) "",Para [Str "bird-tracks"],CodeBlock ("",["haskell","literate"],[]) "import Readme.Lhs",Para [Str "code",Space,Str "block"],CodeBlock ("",[],[]) "indented\nunfenced code",Para [Str "github-style",Space,Str "fenced",Space,Str "code",Space,Str "blocks"],CodeBlock ("",["haskell"],[]) "",Para [Code ("",[],[]) "output test1"],Para [Str "php-style",Space,Str "fenced",Space,Str "code",Space,Str "blocks"],CodeBlock ("",["output","test1"],[]) ""])+ main :: IO () main =- doctest ["src/Readme/Lhs.hs"]+ doctest+ [ "src/Readme/Lhs.hs"+ , "test/test.hs"]