packages feed

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 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 &amp; 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&#39;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">&lt;?&gt;</span> <span class="st">&quot;The number you want to product to&quot;</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">&lt;-</span> unwrapRecord <span class="st">&quot;an example app for readme-lhs&quot;</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">&lt;&gt;</span> <span class="st">&quot; 👍&quot;</span><span class="ot"> ::</span> <span class="dt">Text</span>)-  writeFile <span class="st">&quot;other/answer.md&quot;</span>-    (<span class="st">&quot;$\\prod_{i=1}^{&quot;</span> <span class="fu">&lt;&gt;</span> show n <span class="fu">&lt;&gt;</span> <span class="st">&quot;} i = &quot;</span> <span class="fu">&lt;&gt;</span>-     show answer <span class="fu">&lt;&gt;</span> <span class="st">&quot;$&quot;</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">-- &gt;&gt;&gt; let n = 10</span>-<span class="co">-- &gt;&gt;&gt; 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}}-===--[![Build Status](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}.svg)](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) [![Hackage](https://img.shields.io/hackage/v/{{name}}.svg)](https://hackage.haskell.org/package/{{name}}) [![lts](https://www.stackage.org/package/{{name}}/badge/lts)](http://stackage.org/lts/package/{{name}}) [![nightly](https://www.stackage.org/package/{{name}}/badge/nightly)](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}}-===--[![Build Status](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}.svg)](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) [![Hackage](https://img.shields.io/hackage/v/{{name}}.svg)](https://hackage.haskell.org/package/{{name}}) [![lts](https://www.stackage.org/package/{{name}}/badge/lts)](http://stackage.org/lts/package/{{name}}) [![nightly](https://www.stackage.org/package/{{name}}/badge/nightly)](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 @@ [![Build Status](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}.svg)](https://travis-ci.org/{{github-username}}{{^github-username}}githubuser{{/github-username}}/{{name}}) [![Hackage](https://img.shields.io/hackage/v/{{name}}.svg)](https://hackage.haskell.org/package/{{name}}) [![lts](https://www.stackage.org/package/{{name}}/badge/lts)](http://stackage.org/lts/package/{{name}}) [![nightly](https://www.stackage.org/package/{{name}}/badge/nightly)](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"]