packages feed

daino (empty) → 0.1.5.2

raw patch · 24 files changed

+3288/−0 lines, 24 filesdep +ReplaceUmlautdep +basedep +daino

Dependencies added: ReplaceUmlaut, base, daino, data-default-class, deepseq, dir-traverse, filepath, pandoc, pandoc-sidenote, path, path-io, uniform-cmdLineArgs, uniform-http, uniform-json, uniform-latex2pdf, uniform-pandoc, uniform-shake, uniform-strings, uniform-watch, uniform-webserver, uniformBase, unix

Files

+ LICENSE view
@@ -0,0 +1,24 @@+Copyright 2017, andrew u frank+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.++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE 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 AUTHOR OR THE+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.
+ README.md view
@@ -0,0 +1,32 @@+#  Daino: A Static Site Generator+A static site generator designed by an academic to allow: ++- web pages written as [(Pandoc) markdown](https://pandoc.org/MANUAL.html#pandocs-markdown) (with YAML header for title etc.),+- use a page layout inspired by [Tufte](https://en.wikipedia.org/wiki/Edward_Tufte),+- create publication list to download copies from `bibtex` database,+- offer printable `pdf` files for all content,+- web site using multiple languages with tools to facilitate text input,+- content and appearances (theme) separated,+- a single `yaml` file for setup, and +- a self-contained result which can be hosted on any web server.++## Software reuse:+Daino is focused on software reuse. It uses  `pandoc` and other available packages on `Hackage` (e.g. shake, twitch, scotty), ++It was influenced by Chris Penner's [slick](https://github.com/ChrisPenner/slick#readme), newer, and seemingly simpler is [`Ema`](`https://github.com/srid/ema`) by  Sridhar Ratnakumar, but the documentation did not detail its features neither how it is built.++Relies on `git` for version management.++## Installation++The code can be installed with cabal or stack from hackage. ++Compilation and linking brings in a large number of packages, e.g. Pandoc, and may take a while; on a typically AMD computer 30..60 Minutes, on a ARM64 (e.g. RaspberryPi4) four times as long for the initial installation. Rebuilding, however, is quick.++# Example site+The example site [shown here](https://daino.gerastree.at) can be downloaded or cloned   from `github` with `git clone git@github.com:andrewufrank/dainoSite`.+++# Running your own site+Copying the folder `dainoSite` to a suitable directory and edit the `settinsNN.yaml` file found there is enough to start your own site with running `daino -qs` in this directory. The `ReadMe` shown in a browser with `localhost:3000` includes detailed instructions! +
+ app/daino.hs view
@@ -0,0 +1,64 @@+-------------------------------------------------------------------+--+-- Module      :   daino+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++{- | the main for the sgg+ uses shake only to convert the md files+ copies all resources+ must start in dir with settings3.yaml+-}+module Main where -- must have Main (main) or Main where++import ShakeBake.CmdLineArgs ( parseArgs2input )  +import Foundational.CmdLineFlags ( PubFlags, progName, progTitle  )+-- import Foundational.SettingsPage (sourceDirTestSite )  ++import ShakeBake.StartDainoProcess ( dainoProcess )  +-- import Uniform.StartApp ( startProgWithTitle )  +import UniformBase +-- ( Text, NoticeLevel(NoticeLevel0), unlinesT )  +import Data.Version+import Paths_daino (version)++-- programName, progTitle :: Text+-- programName = "daino" :: Text+-- progTitle = "constructing a static site generator" :: Text+progVersion = showT version  -- "0.1.5.2":: Text++-- the process is centered on the current working dir++main :: IO ()+main =+    startProg+        (unwords' [progName, progTitle, "\n", progVersion])+        ( do+            flags :: PubFlags <-+                parseArgs2input+                    -- sourceDirTestSite +                    --  add a delete flag+                    ( unlinesT+                        [ "the flags to select what is included:"+                        , "default is publish and public included"+                        , "\n -p private"+                        , "\n -d drafts"+                        -- , "\n -o old"+                        , "\n -t test (use data in dainoSite (in current directory), continue)"+                        , "\n -T test (use data in dainoSite (in current directory), fresh start)"+                        , "\n -q quick (not producing the pdfs, which is slow)"+                        , "\n -w start to watch the files for changes and rebake (implies -s)"+                        , "\n -s start local server (port is fixed in siteHeader)"+                        , "\n -l location of settingsFile"+                        -- , "\n -u upload to external server (not yet implemented"+                        ]+                    )+                    "list flags to include"+            -- dainoProcess NoticeLevel2 flags -- produces debug output+            dainoProcess NoticeLevel0 flags+        )
+ changelog.md view
@@ -0,0 +1,60 @@+a static site generator+    version 0.0.2.0  used for myhomepage  - fixes+    0.0.2.1 add check for all pages, study content pdf, tex+    0.0.3.0 copy all structure (exclude with DNB)+    0.0.3.1 change to 15.13 (pandoc not resolvable)+    0.0.4   start with hpack, lts-16.0 (8.8.)+ +# to 0.0.4 +-     0.0.4   start with hpack, lts-16.0 (8.8.)+- go to hpack to produce cabal; reduces duplication in dependencies +## 0.0.4.1+    clean read yaml and check, needs default values+## 0.0.4.2 +    recovering from 2000, rebuild Docrep, restricted use of JSON to docrep processing, moved the uniform-modules for blog inside daino/ssg+# 0.0.4.3 +    clean up, then build test +# 0.0.4.4+    construct the test environment, +    generalized the bake any (aka convert any)  +# 0.0.4.5 to fix references +    with uniformBase 0.1.2, pandoc 0.0.2.3+    pdf produced for every blog +    made images in banner+  0.0.4.6  fixed pdf production, new flag +  0.0.4.7  use Pandoc processCitations - for ghc 8.10.7++  0.0.4.8  reduced, removed unused code, cleaned+  0.0.4.9  change for error to use ExceptionT+  0.0.4.10  add the private/public and the completion status+                visibility (private/public) command line flag private includes the privates, otherwise only public +                version: idea/sketch/draft/nearly/publish+                        include command line flag with these values+                        include what is more than stated +                landing page is mostly produced from index.md in dough, needed is only top directory structure.+                        must not include the banner image (must be in settingsN.yml): difference in formatting+    0.0.4.11 add shiftHeaderLevel to use title as h1, `#` as h2 etc. this corresponds better with latex                        +    0.0.4.12 reconstruct feb 2023 for ghc 9.0.2++0.1.5 branch for ghc 9.2.5+0.1.5.1 changed name from ssg to daino+0.1.5.2 new ReadMe.md, exampleSite not in extra-source but +    in separate dainoSite (with own git)   +    added swith l for location (example crun daino -- -tl ../dainoSite)++used versions 9.0.2+- twitch-0.1.7.2.1 (lib) (requires build)+ - uniform-algebras-0.1.4.2 (lib) (requires build)+ - uniform-strings-0.1.3.5 (lib) (requires build)+ - uniform-error-0.1.3.2 (lib) (requires build)+ - uniform-time-0.1.3 (lib) (requires build)+ - uniform-fileio-0.1.3 (lib) (requires build)+ - uniformBase-0.1.4.2 (lib) (requires build)+ - uniform-webserver-0.0.10.3 (lib) (requires build)+ - uniform-watch-0.0.1.3 (lib) (requires build)+ - uniform-json-0.0.6.1 (lib) (requires build)+ - uniform-cmdLineArgs-0.0.1.0 (lib) (requires build)+ - uniform-shake-0.0.1.3 (lib) (requires build)+ - uniform-pandoc-0.0.2.4 (lib) (requires build)+ - uniform-latex2pdf-0.0.1.2 (lib) (requires build)+ - uniform-http-0.0.2.8 (lib) (requires build)
+ daino.cabal view
@@ -0,0 +1,111 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.35.2.+--+-- see: https://github.com/sol/hpack++name:           daino+version:        0.1.5.2+synopsis:       daino is a static site generator (SSG) using shake and pandoc+description:    A static site generator using Pandoc and other available packages on Hackage (e.g. shake, twitch, scotty), influenced by Chris Penner's [slick](https://github.com/ChrisPenner/slick#readme). It uses text files (in Markdown codes) to manage data and relies on   version management with git. Page appearances are directed with YAML headers. For each page a PDF file is produced to allow regular print output. Index pages for navigation between pages are automatically created.+category:       Development Web+homepage:       https://github.com/andrewufrank/u4blog.git#readme+bug-reports:    https://github.com/andrewufrank/u4blog.git/issues+author:         Andrew Frank+maintainer:     Andrew U. Frank <frank@geoinfo.tuwien.ac.at>+copyright:      2021 Andrew U. Frank+license:        GPL+license-file:   LICENSE+build-type:     Simple+extra-source-files:+    changelog.md+    README.md++source-repository head+  type: git+  location: https://github.com/andrewufrank/u4blog.git+  subdir: daino++library+  exposed-modules:+      Foundational.CmdLineFlags+      Foundational.Filetypes4sites+      Foundational.MetaPage+      Foundational.SettingsPage+      Lib.CheckProcess+      Lib.IndexCollect+      Lib.IndexMake+      Lib.Templating+      ShakeBake.Bake+      ShakeBake.CmdLineArgs+      ShakeBake.ConvertFiles+      ShakeBake.ReadSettingFile+      ShakeBake.Shake2+      ShakeBake.StartDainoProcess+      ShakeBake.Watch+      Wave.Docrep2panrep+      Wave.Md2doc+      Wave.Panrep2html+      Wave.Panrep2pdf+  other-modules:+      Paths_daino+  hs-source-dirs:+      src+  other-extensions:+      OverloadedStrings+  build-depends:+      ReplaceUmlaut+    , base >4.7 && <5+    , data-default-class+    , deepseq+    , dir-traverse+    , filepath+    , pandoc+    , pandoc-sidenote+    , path+    , path-io+    , uniform-cmdLineArgs >=0.1.5.1+    , uniform-http+    , uniform-json >=0.1.5.2+    , uniform-latex2pdf >=0.1.5.2+    , uniform-pandoc >=0.1.5.2+    , uniform-shake+    , uniform-strings >=0.1.5.1+    , uniform-watch+    , uniform-webserver+    , uniformBase >=0.1.5.1+    , unix+  default-language: Haskell2010++executable daino+  main-is: daino.hs+  other-modules:+      Paths_daino+  hs-source-dirs:+      app+  other-extensions:+      OverloadedStrings+  build-depends:+      ReplaceUmlaut+    , base >4.7 && <5+    , daino+    , data-default-class+    , deepseq+    , dir-traverse+    , filepath+    , pandoc+    , pandoc-sidenote+    , path+    , path-io+    , uniform-cmdLineArgs >=0.1.5.1+    , uniform-http+    , uniform-json >=0.1.5.2+    , uniform-latex2pdf >=0.1.5.2+    , uniform-pandoc >=0.1.5.2+    , uniform-shake+    , uniform-strings >=0.1.5.1+    , uniform-watch+    , uniform-webserver+    , uniformBase >=0.1.5.1+    , unix+  default-language: Haskell2010
+ src/Foundational/CmdLineFlags.hs view
@@ -0,0 +1,63 @@+----------------------------------------------------------------------+--+-- Module      : l flags  values from command line+----------------------------------------------------------------------+-- {-# LANGUAGE DeriveAnyClass #-}+-- {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+-- {-# LANGUAGE TypeSynonymInstances  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++{- | the defintion for a layout and a flags type+  which carry info from the command line and the siteHeader file+ the defaults for flags are set up for testing  are overridden+ the defaults for layout must correspond to what is set in the test siteHeader file.+ layout defaults are used in testing++ content dirs are those, which have *.md files+-}+module Foundational.CmdLineFlags+    (module Foundational.CmdLineFlags+    , def ) where++import Data.Default.Class ( Default(..) )+import UniformBase ( Text, Zeros(zero) ) -- to define a default class for pub flags ++progName, progTitle :: Text+progName = "daino"  +progTitle = "constructing a static site generator" :: Text++++-- | the flags represent the switches from CmdLineArgs+-- see there for meaning+data PubFlags = PubFlags+    { privateFlag+      , draftFlag+    --   , oldFlag+      , testFlag+      , testNewFlag +      , quickFlag+      , watchFlag+      , serverFlag :: Bool+      , locationDir :: FilePath -- can be absolute or relative+    }+    deriving (Show, Eq) -- no read for path++instance Zeros PubFlags where+    zero = PubFlags zero zero zero zero zero zero zero zero+instance Default PubFlags where +        def = testFlags ++testFlags :: PubFlags+testFlags =+    zero+        { privateFlag = False -- not including draft+        , draftFlag = False+        }++
+ src/Foundational/Filetypes4sites.hs view
@@ -0,0 +1,182 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LiberalTypeSynonyms #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++---------------------------------------------------------------------+--+-- Module      : all the filetype used for daino+----------------------------------------------------------------------++{- | daino uses sequences of transformations between data structures (types)+ MD -> Docrep -> Panrep -> TexSnip -> Tex -> PDF+                 Pandrep -> HTML+ Each result is written as a typed file with a specific extension+-}+module Foundational.Filetypes4sites (+    module Foundational.Filetypes4sites,+) where++import Uniform.Json (FromJSON, ToJSON, Value)+import Uniform.Pandoc  +import UniformBase+import Foundational.MetaPage ( MetaPage, extPDF )+-- import Wave.Md2doc (pandoc2docrep)+++--------------------------------------------typed file Docrep++{- | representation of a document+ the yam part contains the json formated yaml metadata+ which is extensible+ Attention the Pandoc is Pandoc (Meta (Map Text MetaValue) [Block]+ means that title etc is duplicated in the Meta part.+ I keep the pandoc structure (Pandoc Meta [Block] - Text.Pandoc.Definition+ because it is possible to convert the Meta from Pandoc to JSON+ with flattenMeta (in PandocImports)+ but I do not see an easy way to convert back+ - Where would this be required? + - probably for the index construction? +-}+data Docrep = Docrep {meta1 :: MetaPage, pan1 :: Pandoc} -- a json value+    deriving (Show, Read, Eq, Generic, Zeros)++instance FromJSON Docrep+instance ToJSON Docrep++extDocrep :: Extension+extDocrep = Extension "docrep"++-- instance NiceStrings Docrep where+--   shownice = showNice . unDocrep++docrepFileType :: TypedFile5 Text Docrep+docrepFileType =+    TypedFile5{tpext5 = extDocrep} :: TypedFile5 Text Docrep++instance TypedFiles7 Text Docrep where+    wrap7 = readNote ("Docrep wrap7 sfasdwe") . t2s+    --    wrap7 a = readNote (show a) . t2s $ a++    unwrap7 = showT++-------------------- fileType Panrep ----------++extPanrep :: Extension+extPanrep = Extension "panrep"++-- | a file containing what pandoc internally works on+-- plus the complete set of the metadata+panrepFileType :: TypedFile5 Text Panrep+panrepFileType =+    TypedFile5{tpext5 = extPanrep} :: TypedFile5 Text Panrep++data Panrep = Panrep {panyam :: MetaPage, panpan :: Pandoc}+    deriving (Eq, Show, Read)++instance Zeros Panrep where zero = Panrep zero zero++instance TypedFiles7 Text Panrep where+    -- handling Pandoc and read them into PandocText+    wrap7 = readNote "wrap7 for pandoc 223d" . t2s+    unwrap7 = showT++--- variant 1 panrep +extPanrep1 :: Extension+extPanrep1 = Extension "panrep1"++panrep1FileType :: TypedFile5 Text Panrep1+panrep1FileType =+    TypedFile5{tpext5 = extPanrep1} :: TypedFile5 Text Panrep1++newtype Panrep1 = Panrep1 {unPanrep1 :: Panrep}+-- data Panrep = Panrep {panyam :: MetaPage, panpan :: Pandoc}+    deriving (Eq, Show, Read)++-- instance Zeros Panrep where zero = Panrep zero zero++instance TypedFiles7 Text Panrep1 where+    wrap7 = readNote "wrap7 for pandocrep1" . t2s+    unwrap7 = showT+--------------------  TexSnip++extTexSnip :: UniformBase.Extension+extTexSnip = Extension "texsnip"++{- | a wrapper around TexSnip+ snipyam is not used+a tex snip is a piece of latex code, but not a full compilable+latex which results in a pdf+-}+data TexSnip = TexSnip {snipyam :: MetaPage, unTexSnip :: Text}+    deriving (Show, Read, Eq)++-- unTexSnip (TexSnip a) = a   --needed for other ops++instance Zeros TexSnip where+    zero = TexSnip zero zero++texSnipFileType :: TypedFile5 Text TexSnip+texSnipFileType =+    TypedFile5{tpext5 = extTexSnip} :: TypedFile5 Text TexSnip++instance TypedFiles7 Text TexSnip where+    -- handling TexSnip and read them into TexSnipText+    -- the file on disk is readable for texstudio++    wrap7 = readNote "wrap7 for TexSnip dwe11d" . t2s+    unwrap7 = showT++----------------  Tex++extTex :: Extension+extTex = Extension "tex"++texFileType :: TypedFile5 Text Latex+texFileType = TypedFile5{tpext5 = extTex} :: TypedFile5 Text Latex++instance TypedFiles7 Text Latex where+    wrap7 = Latex+    unwrap7 = unLatex++-- | this is a full file, not just a snippet+newtype Latex = Latex {unLatex :: Text}+    deriving (Eq, Ord, Read, Show)++instance Zeros Latex where+    zero = Latex zero++---------------------------------------------- PDF+-- extension in metapage++pdfFileType :: TypedFile5 Text PDFfile+pdfFileType = TypedFile5{tpext5 = extPDF} :: TypedFile5 Text PDFfile++-- | a file in PDF format+newtype PDFfile = PDFfile {unpdffile :: Text}+    deriving (Eq, Ord, Read, Show)++instance Zeros PDFfile where+    zero = PDFfile zero++instance TypedFiles7 Text PDFfile where+    wrap7 = PDFfile+    unwrap7 = unpdffile++-------------------- fileType ---------- CSL+-- extCSL = Extension "csl"+-- cslFileType = TypedFile5 {tpext5 = extCSL} :: TypedFile5 Text Style++-- instance TypedFiles7 Text Style where+--     wrap7 = id+--     unwrap7 = id+--------------------------------- Bib+-- extBib = Extension "bib"+-- bibFileType = TypedFile5 {tpext5 = extBib}++-- instance TypedFiles7 Text
+ src/Foundational/MetaPage.hs view
@@ -0,0 +1,293 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+---------------------------------------------------------------+--+-- MetaPage   : The information taken from the yaml header of each md file. +--  LayoutFlags deals with the data from the settingsN.yaml+---------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans+            -fno-warn-missing-signatures+            -fno-warn-missing-methods+            -fno-warn-duplicate-exports+            -fno-warn-unused-imports+            -fno-warn-unused-matches #-}+{-# OPTIONS_GHC -Wno-incomplete-patterns #-}+{-# LANGUAGE InstanceSigs #-}++{- | The data describing a page of the site (i.e. an md file)+ the default is merged with the values in the yaml head+ all entries there should be from this list+ all JSON related functions here!+-}+module Foundational.MetaPage (+    module Foundational.MetaPage,+    Default (..),+) where++import Data.Default.Class  +import Foundational.SettingsPage  +import Uniform.Json+import Uniform.Shake+import Uniform.Pandoc+import Uniform.Latex +import Uniform.Yaml+import Uniform.HTMLout (extHTML)++-- the fields in the yaml header of each md file +-- maybe values can be empty++data MetaPage = MetaPage+    { -- | the original dough fn+      dyFn :: FilePath+    , -- | the relative filename+      -- relative to the browser origin+      -- set in ? initializeIndex+      dyLink :: FilePath+     -- | the fields of miniblog+    , dyLang :: Text -- DocLanguage not used yet +    , dyTitle :: Text  -- must be set +    , dyAbstract :: Text -- must be set +    , dyAuthor :: Text  -- default ?+    , -- | this is maybe a string,+      --  should be utctime+      dyDate :: Maybe Text -- must be set +    , dyKeywords :: Text -- should be [Text] +    , dyImage ::  Text  -- empty if nothing given+    , dyImageCaption :: Text +    , dyBibliography :: Maybe Text+    -- a bibliography is trigger to process+    , dyStyle :: Maybe Text+    , dyStyleBiber :: Text+    , dyReferences :: Maybe Value --  [Reference]+    -- when references are given in markdown text+    , dyReference_section_title :: Text +            --set default always, suppressed when not needed+    , dyContentFiles :: [Text] -- the list of md files to include +    , dyNoCite :: Maybe Text+    , dyBook :: Text -- "book" to produce collection pdf+    , dyVersion ::  Text -- should be "publish"+    , dyVisibility ::  Text -- should be "public"+    -- , dyIndexPage :: Bool+    , dyIndexSort :: Maybe Text+    , dyIndexEntry :: IndexEntry+    -- , dyDirEntries   :: [IndexEntry]  -- reduce to one for indexEntry+    -- , dyFileEntries  :: [IndexEntry]+    -- is defined later, necessary here?+    , dyDoNotReplace:: [Text]+    , dyHeaderShift :: Int -- pandoc seems not to parse int in the yaml, mark, values    'zero' or 'one' +    -- shift the header level, such that one # is hl2,+    -- because hl1 is title+    }+    deriving (Show, Eq, Generic, Zeros, Read) -- ord missing for references+instance Zeros Integer where zero = 0++-- instance Default MetaPage where+--     -- how is this used - defaults are set in pandoc2MetaPage+--     def :: MetaPage+--     def =+--         zero+--             { dyFn = zero+--             , dyLink = zero+--             , dyLang = "en_US" -- DLenglish+--             , dyTitle = "FILL_dytitle"+--             , dyAbstract = zero+--             , dyAuthor = "AOS"+--             , dyDate = Just . showT $ year2000+--             , dyKeywords = zero+--             , dyBibliography = Just "resources/BibTexLatex.bib"+--             , dyStyle = Just "chicago-fullnote-bibliography-bb.csl"+--             , dyStyleBiber = "authoryear"+--             , dyReferences = Nothing+--             , dyReference_section_title = "References"+--             , dyVersion =  "private"+--             , dyVisibility =  "draft"+--             -- , dyIndexPage = False+--             , dyIndexSort = zero+--             , dyIndexEntry = zero+--             -- , dyDirEntries = zero+--             -- , dyFileEntries = zero+--             , dyHeaderShift = zero +--             }++docyamlOptions :: Options+docyamlOptions =+    defaultOptions+        { fieldLabelModifier = t2s . toLowerStart . s2t . drop 2+        }++instance ToJSON MetaPage where+    toJSON = genericToJSON docyamlOptions++instance FromJSON MetaPage where+    parseJSON = genericParseJSON docyamlOptions++pandoc2MetaPage::  Settings ->  Path Abs File  -> Pandoc -> MetaPage+-- removed most default values, left only for image and caption, keywords+pandoc2MetaPage sett3 filename  pd =  meta6+  where++    layout = siteLayout sett3+    doughP = doughDir layout+    defAuthor = defaultAuthor layout +    -- defBiblio = defaultBibliography layout  ++    meta2 = flattenMeta . getMeta $ pd+    relfn = makeRelativeP doughP filename+    -- fromJustN means give error if not present!+    meta4 =+        MetaPage+            { dyFn = toFilePath filename+            , dyLink = toFilePath relfn+            , dyLang = fromMaybe "en_US" $ getAtKey meta2 "language"+            , dyTitle = fromJustN "title" $ getAtKey meta2 "title"+            -- , dyAbstract = fromJustN "abstract" $ getAtKey meta2 "abstract"+            , dyAbstract = fromMaybe "" $ getAtKey meta2 "abstract" +                    -- allow empty abstract+            -- , dyAuthor = fromJustN "author" $ getAtKey meta2 "author"+            , dyAuthor = fromMaybe defAuthor $ getAtKey meta2 "author"+            -- allow empty author ??+            , dyDate = getAtKey meta2 "date"+            , dyBibliography = getAtKey meta2 "bibliography"+            -- not defaulted, value used is the one read into pandoc+            -- , dyBibliography = Just $ fromMaybe defBiblio $ getAtKey meta2 "bibliography"+            -- used as signal for processing biblio+            -- perhaps not the best idea? +            , dyImage = fromMaybe "" $ getAtKey meta2 "image"+            , dyImageCaption = fromMaybe "" $ getAtKey meta2 "caption"+            , dyKeywords = fromMaybe "" $ getAtKey meta2 "keywords"+            -- , dyKeywords = fromJustN "keywords" $ getAtKey meta2 "keywords"+            , dyStyle = Just $ fromMaybe "resources/chicago-fullnote-bibliography-bb.csl" $ getAtKey meta2 "style"+            , dyStyleBiber = fromMaybe "authoryear" $ getAtKey meta2 "styleBiber"+            , dyNoCite = getAtKey meta2 "nocite"+            , dyReferences = getAtKey meta2 "references"+            , dyReference_section_title= fromMaybe "References" $ getAtKey meta2 "reference-section-title"+            -- default should be set depending on the language +            -- default does not work, needs to be put into yaml +            , dyContentFiles = maybeToList  . getAtKey meta2 $ "content"+            -- TODO make reading a list+            , dyBook = fromMaybe "" $ getAtKey meta2 "book"+            , dyVersion = fromJustN "version" $ getAtKey meta2 "version"  -- no default here, must be present +            , dyVisibility = fromMaybe "public" $ getAtKey meta2 "visibility"   +            -- public is default, private must be set+            -- but not default for publish! +            --   dyIndexPage = fromMaybe False $ getAtKey meta2 "indexPage"+            , dyIndexSort = getAtKey meta2 "indexSort"+            , dyIndexEntry =   zero+            , dyHeaderShift = parseHeaderShift $ getAtKey  meta2 $ "headerShift"+                                        -- value 1 is correct+            , dyDoNotReplace = maybe [] words' $ getAtKey meta2 $ "doNotReplace"+            -- , dyDoNotReplace = maybe [] (\t -> fromJustNote "sdfwer" $ splitOnflip  "," t) $ getAtKey meta2 $ "doNotReplace"+            }++    -- splitOnflip sep inp = splitOn' inp sep ++    ix1 =  initializeIndex meta4+    -- meta5 = meta4   -- {dyAuthor=blankAuthorName hpnames (dyAuthor meta4) }+    meta6 = meta4{dyIndexEntry = ix1} ++    fromJustN :: Text -> Maybe a -> a +    fromJustN a = fromJustNoteT ["fromJust Nothing pandoc2MetaPage\n", showT filename, "\n", a]++    parseHeaderShift :: Maybe Text -> Int +    parseHeaderShift Nothing = 1   -- this is the default+    parseHeaderShift (Just "zero") = 0 +    parseHeaderShift (Just "one") = 1 +    parseHeaderShift (Just "0") = 0 +    parseHeaderShift (Just "1") = 1 +    parseHeaderShift (Just a) = errorT ["parseHeaderShift", "unexpected Value", a, "!"] ++    -- fromJust Nothing = errorT ["fromJust Nothing pandoc2MetaPage", showT filename]+    -- fromJust (Just a) = a+ ++initializeIndex :: MetaPage -> IndexEntry+-- initialize the index with the values from the metapage yaml+initializeIndex MetaPage{..} = ix1+  where+    ix1 =+        zero+            { ixfn = dyFn  +            , title = dyTitle+            , link = dyLink +            , abstract = dyAbstract+            , author = dyAuthor+            , date = fromMaybe (showT year2000) dyDate+            , content = zero+            -- , publish = dyVersion+            , dirEntries = zero+            , fileEntries = zero+            , headerShift = dyHeaderShift+            }++isIndexPage :: Path Abs File -> Bool +isIndexPage filename =  getNakedFileName filename == "index"++convertLink2html ix = s2t . -- s2t . toFilePath $ +          setExtension (unExtension extHTML)   $ link ix++convertLink2pdf ix =  s2t . -- s2t . toFilePath $ +          setExtension (unExtension extPDF)   $ link ix+++-- extHTML :: Extension+-- extHTML = Extension "html"+++extPDF :: Extension+extPDF = Extension "pdf"++-- addFileMetaPage :: Path Abs Dir -> Path Abs Dir -> Path Abs File -> MetaPage+-- addFileMetaPage doughP bakedP fn =+--     if getNakedFileName fn == "index"+--         then mp1{dyIndexPage = True}+--         else mp1+--   where+--     mp1 =+--         zero+--             { dyFn = toFilePath fn+--             , dyLink =+--                 toFilePath+--                     (makeRelativeP doughP fn :: Path Rel File)+--             , dyStyle =  addBakedRoot bakedP ( dyStyle zero)+--             , dyBibliography = addBakedRoot bakedP                                           (dyBibliography zero)+--             } ::+--             MetaPage++-- addBakedRoot :: Path Abs Dir -> Maybe Text -> Maybe Text+-- addBakedRoot bakedP Nothing = Nothing+-- addBakedRoot bakedP (Just fp) = Just . s2t . toFilePath $ addFileName bakedP . t2s $ fp++-- -- | another data type to rep languages+-- not yet used - go for de_AT style and uses standard lang codes+-- data DocLanguage = DLgerman | DLenglish+--     deriving (Show, Read, Ord, Eq, Generic)++-- instance Zeros DocLanguage where zero = DLenglish++-- instance FromJSON DocLanguage++-- instance ToJSON DocLanguage++-- TODO is this clever to have a new language datatype?++-- this is not used yet:+-- data PublicationState = PSpublish | PSdraft | PSold | PSzero+--     deriving (Generic, Show, Read, Ord, Eq)+-- -- ^ is this file ready to publish++-- instance Zeros PublicationState where+--     zero = PSzero++-- instance NiceStrings PublicationState where+--     shownice = drop' 2 . showT++-- instance ToJSON PublicationState++-- instance FromJSON PublicationState
+ src/Foundational/SettingsPage.hs view
@@ -0,0 +1,153 @@+----------------------------------------------------------------------+--+-- Module      : layout and flags  takes data from the settinsgN.yaml file (metaPage deals with the md file YAML header)+----------------------------------------------------------------------+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+-- {-# LANGUAGE TypeSynonymInstances  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++{- | the defintion for a layout and a flags type+  which carry info from the command line and the siteHeader file+ the defaults for flags are set up for testing  are overridden+ the defaults for layout must correspond to what is set in the test siteHeader file.+ layout defaults are used in testing++ content dirs are those, which have *.md files+-}+module Foundational.SettingsPage+    (module Foundational.SettingsPage+    , def +    ) where++import UniformBase+import Data.Default.Class ( Default(def) ) -- to define a default class for siteLayout +import Uniform.Json ( FromJSON, ToJSON )++import Path (parent)+progName, progTitle :: Text+progName = "daino"  +progTitle = "constructing a static site generator" :: Text++settingsFileName :: Path Rel File+-- ^ the yaml file in which the siteHeader are fixec+settingsFileName = makeRelFile "settings3" -- the yaml file++-- | the siteHeader file with all fields +data Settings = Settings+    { siteLayout :: SiteLayout +    , localhostPort :: Int +    , settingsAuthor :: Text +    , settingsDate :: Text -- should be UTC +    , siteHeader :: SiteHeader +    , menuitems :: MenuItems+    -- , today :: Text+    } deriving (Show, Read, Ord, Eq, Generic, Zeros)++instance ToJSON Settings+instance FromJSON Settings++data SiteHeader = SiteHeader +    { sitename :: FilePath +    , byline :: Text +    , banner :: FilePath +    , bannerCaption :: Text +    } deriving (Show, Read, Ord, Eq, Generic, Zeros)+instance ToJSON SiteHeader+instance FromJSON SiteHeader++newtype MenuItems = MenuItems {menuNav:: [MenuItem]+                            -- , menuB:: Text+                            } deriving (Show, Read, Ord, Eq, Generic, Zeros)+instance ToJSON MenuItems +instance FromJSON MenuItems ++data MenuItem = MenuItem  +    { navlink :: FilePath +    , navtext :: Text+    -- , navpdf :: Text  -- for the link to the pdf +    -- not a good idead to put here+    } deriving (Show, Read, Ord, Eq, Generic, Zeros)+instance ToJSON MenuItem+instance FromJSON MenuItem++data SiteLayout = SiteLayout+    { -- | the place of the  theme files (includes templates)+      themeDir :: Path Abs Dir+    , -- | where the content is originally (includes resources)+      doughDir :: Path Abs Dir+    , -- | the webroot, the dir with all the produced files+      bakedDir :: Path Abs Dir+    , masterTemplateFile :: Path Rel File  -- for html+    , texTemplateFile :: Path Rel File   -- for latex +    , doNotBake :: Text +    -- todo probably not used+    , blogAuthorToSuppress :: [Text]+    , defaultAuthor :: Text+    , replaceErlaubtFile :: Path Abs File+    -- the list of permitted (not to replace)+    +    -- , defaultBibliography:: Text+    -- cannot be defaulted, value must be read by pandoc +    }+    deriving (Show, Read, Ord, Eq, Generic, Zeros)+instance ToJSON SiteLayout+instance FromJSON SiteLayout+ ++sourceDirTestDocs :: Path Abs Dir+sourceDirTestDocs = makeAbsDir "/home/frank/daino/docs/"++sourceDirTestSite :: Path Abs Dir+sourceDirTestSite = sourceDirTestDocs </> (makeRelDir "site")+-- ^ the dir with the source for the test site++layoutDefaults :: Path Abs Dir -> Path Abs Dir ->  SiteLayout+-- used for finding the test cases+-- must correspond to the settings3.yaml in source code repository+-- fix this later for use in testing todo +layoutDefaults dough4test homeDir =+    zero -- SiteLayout+        { doughDir = dough4test+        , bakedDir = homeDir </> makeRelDir "bakedTestSite" :: Path Abs Dir+        ,  themeDir = (parent (parent dough4test)) </> makeRelDir "theme"+ +        ,  masterTemplateFile = makeRelFile "master7tufte.dtpl"+        , texTemplateFile = makeRelFile "resources/theme/templates/latex7.dtpl"+        ,  doNotBake = "DNB"+        -- included in filenames (and directories) to exclude from bake process+        , blogAuthorToSuppress = []+        , defaultAuthor = "AOS"+        , replaceErlaubtFile = makeAbsFile "/home/frank/Workspace11/replaceUmlaut/nichtUmlaute.txt"+        -- , defaultBibliography = "resources/BibTexLatex.bib"+        }++-- instance Default SiteLayout where +--         def = layoutDefaults++-- notDNB :: SiteLayout -> FilePath -> Bool +-- notDNB siteLayout = not . isInfixOf' (t2s $ doNotPublish siteLayout)++resourcesName =  "resources"+templatesName = "templates"+themeName = "theme"++templatesDir :: SiteLayout -> Path Abs Dir+templatesDir layout = themeDir layout `addFileName` (makeRelDir templatesName)++blankAuthorName :: [Text] -> Text -> Text +-- suppress/oppress author name, if the author name is the same as one in the first arg (AUF, Andrew U..) then set it to empty else copy +-- goal is to avoid to have each page say the obvious "author XX"+blankAuthorName names current = +    if current `elem` names +        then zero +        else current ++++
+ src/Lib/CheckProcess.hs view
@@ -0,0 +1,120 @@+----------------------------------------------------------------------+--+-- Module      :   check the md files +----------------------------------------------------------------------+{-# LANGUAGE OverloadedStrings #-}+-- {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -Wall #-}++module Lib.CheckProcess where++import UniformBase+import ShakeBake.ReadSettingFile  +import Foundational.SettingsPage+import System.Directory.Recursive+import Uniform.Pandoc+-- import Foundational.Filetypes4sites  +-- import Wave.Md2doc +import Foundational.MetaPage +-- import Control.Exception+-- import Control.DeepSeq+import Data.Char++checkProcess :: NoticeLevel -> Path Abs File-> ErrIO ()+{- ^ the top call to check the md files. first collect all the filenames+-}+checkProcess debug sitefn = do+    when (inform debug) $ putIOwords ["checkProcess", "start"]+    sett3 <- readSettings debug (sitefn)+    let doughP = doughDir (siteLayout sett3)+    when (inform debug) $ putIOwords ["checkProcess 1", "doughP", showPretty doughP]++    -- get all md files in doughP +    fns :: [FilePath] <- callIO $ getDirRecursive (toFilePath doughP) ++    when (inform debug) $ putIOwords ["checkProcess 1", "fns", showT . take 10 $ fns]++    let mds = filter (hasExtension "md") fns +    -- let mds = filter (hasExtension extMD) fns -- TODO +    +    when (inform debug) $ putIOwords ["checkProcess 2", "mds", showT . take 10 $ mds]++    let mds1 = mds -- filter (notDNB (siteLayout sett3)) mds+    when (inform debug) $ putIOwords ["checkProcess 2", "mds1", showT . take 10 $ mds1]+    let mds2 = map makeAbsFile mds1+    -- let hpname = blogAuthorToSuppress.storag sett3++    mapM_ (checkOneMD debug ) mds2 ++    when (inform debug) $ putIOwords ["checkProcess", "end"]+    return ()++++checkOneMD:: NoticeLevel ->  Path Abs File -> ErrIO ()+-- check one md file (only the yaml head) for necessary values +checkOneMD debug  fnin  =+    +    ( do+        when (inform debug) $ putIOwords ["checkOneMD fnin", showPretty fnin]+        -- same setup as Startdainoprocess +        currDir :: Path Abs Dir  <- currentDir +        let settfn =  currDir </> settingsFileName++        sett3 <- readSettings debug settfn ++        -- (Docrep y1 _) <- readMarkdownFile2docrep debug doughP fnin+        -- copied from md2doc.hs+        -- mdfile <- read8 fnin markdownFileType +        -- pd <- readMarkdown2 mdfile+        +        -- let doughP = doughDir (siteLayout sett3)+        -- let doughP = makeAbsDir "/home/frank/Workspace11/daino/docs/site/dough/"+                -- is not used +        mdfile <- read8 fnin markdownFileType +        pd <- readMarkdown2 mdfile++        when (inform debug) $ putIOwords ["checkOneMD 1"]+        y1 <- check_readMeta debug sett3 fnin  pd ++        when (inform debug) $ putIOwords ["checkOneMD 2", "metapage", showPretty  y1]++        when (inform debug) $ putIOwords ["checkOneMD", "done"]+        return ()+    )+    `catchError` (\e -> do+        putIOwords ["checkOneMD", "discovered error in file", showT fnin]+        -- putIOwords ["the yaml head is read as:", showPretty y1]+        putIOwords ["the error msg is:", e ] -- showT (e :: SomeException)]+        return () +        )++check_readMeta:: NoticeLevel -> Settings ->  Path Abs File -> Pandoc -> ErrIO  MetaPage+check_readMeta debug sett3 fnin  pd = +    (do +        when (inform debug) $ putIOwords ["check_readMeta 1"]++        let meta6 = pandoc2MetaPage sett3 fnin  pd+        when (inform debug) $ putIOwords ["check_readMeta 2", "metapage", showPretty  meta6]    ++        -- let y2 = meta6+        -- return y2+        let ll = sum .  map ord . show $ meta6+        -- y2 <- liftIO $ do +            -- putStr .   show $ ll  +            -- let y3 =   deepseq ll y1+        -- output is necessary to force evaluation - deepseq seems not to do it+        putIOwords [showT  ll]+        return meta6+      )++-- catch error is never reached. problem is in pure code (pandoc2meta)+-- discovered when output is forced +--   `catchError` (\e -> do +--             putIOwords ["\n\ncheck_readMeta", "discovered error in file", showT fnin]+--             -- putIOwords ["the yaml head is read as:", showPretty y1]+--             putIOwords ["the error msg is:", showT (e :: SomeException), "\n"]+--             return zero +--             )+
+ src/Lib/IndexCollect.hs view
@@ -0,0 +1,154 @@+----------------------------------------------------------------------+--+-- Module      :   create an index for a directory+---- | create an index for a directory+--  in two steps: +--  IndexCollect collect all the date+--  with call to completeIndex+--  and+--  indexmake: convert collected data for printing (convertIndexEntries)+--  .+--  the data is stored in a file separately and managed by Shake+--  operates on metapage (or less? )+----------------------------------------------------------------------+{-# LANGUAGE OverloadedStrings #-}+-- {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# OPTIONS_GHC -Wall #-}++module Lib.IndexCollect where++-- import Uniform.Json  +import Uniform.Pandoc ( extMD )+import Uniform.Latex+import Foundational.Filetypes4sites ( Docrep(Docrep) )+import Foundational.MetaPage+ +import Foundational.CmdLineFlags ( PubFlags )++import UniformBase++import Wave.Md2doc+    ( includeBakeTest3docrep, readMarkdownFile2docrep ) +-- import ShakeBake.Bake (readMarkdownFile2docrep)+import Foundational.SettingsPage  +import Data.List (sortOn)++++completeIndex :: NoticeLevel -> PubFlags -> Settings -> Path Abs Dir -> Maybe Text ->   IndexEntry -> ErrIO IndexEntry+{- ^ the top call to form the index data into the MetaPage+later only the format for output must be fixed+-}+completeIndex debug pubf sett4 doughP indexSortField ix1 = do+    when (inform debug) $ putIOwords ["completeIndex", "start", showPretty ix1]++    let fn = doughP </> (link ix1) :: Path Abs File+    -- changed to search in dough (but no extension yet)++    when (inform debug) $   -- to have indication where error is if pandoc error +        putIOwords+            [ "completeIndex"+            , "fn"+            , showT fn+            ]+    -- unless (isIndexPage fn) $ errorT ["completeIndex should only be called for indexPage True"]++    (dirs, files) <- getDirContent2dirs_files debug pubf sett4 doughP  fn+    let+        dirs1 = sortField dirs +        files1 = sortField files+    -- sort entries ++    when (inform debug) $ putIOwords ["completeIndex", "\n dirs", showT dirs, "\n files", showT files]+    let ix2 = ix1{dirEntries = dirs1, fileEntries = files1}+    when (inform debug) $ putIOwords ["completeIndex", "x2", showT ix2]+    return ix2++  where +    sortField = case (indexSortField) of +        Just "filename" -> sortOn link+        Just "date"      -> sortOn date +        Just "reversedate" -> reverse . sortOn  date+        _ -> sortOn link   -- what is best default? id?+++{- | get the contents of a directory, separated into dirs and files+ the directory is given by the index file+ which files to check: index.md (in dough) or index.docrep (in baked)+ currently checks index.docrep in dough (which are not existing)+ indexfile itself is removed and files which are not markdown+-}+getDirContent2dirs_files :: NoticeLevel -> PubFlags -> Settings -> Path Abs Dir ->  Path Abs File -> ErrIO ([IndexEntry], [IndexEntry])+getDirContent2dirs_files debug pubf sett4 doughP   indexpageFn = do+    when (inform debug) $ putIOwords ["getDirContent2dirs_files for", showPretty indexpageFn]+    let pageFn = makeAbsDir $ getParentDir indexpageFn :: Path Abs Dir+    -- get the dir in which the index file is embedded+    when (inform debug) $ putIOwords ["getDirContent2dirs_files pageFn", showPretty pageFn]++    dirs1 :: [Path Abs Dir] <- getDirectoryDirs' pageFn+    let dirs2 =  filter (not . isInfixOf' (doNotBake (siteLayout sett4)). s2t . getNakedDir) dirs1+    let dirs3 = filter ( not . (isPrefixOf' resourcesName) .  getNakedDir) dirs2+    let dirs4 = filter ( not . (isPrefixOf'  templatesName) . getNakedDir) dirs3+    let dirs5 = filter ( not . (isPrefixOf' "."+         ) .   getNakedDir) dirs4+    -- TODO may need extension (change to list of excluded)+    -- build from constants in foundation++    when (inform debug) $ putIOwords ["\ngetDirContent2dirs_files dirs4", showPretty dirs4]++    files1 :: [Path Abs File] <- getDirContentFiles pageFn++    when (inform debug) $ putIOwords ["getDirContent2dirs_files files1", showPretty files1]+ +    let files2 =+            filter (indexpageFn /=) -- should not exclude all index pages but has only this one in this dir?+                . filter (hasExtension extMD)  +                . filter (not . isInfixOf' (doNotBake (siteLayout sett4)) . s2t. toFilePath)+                $ files1+    when (inform debug) $ putIOwords ["getDirContent2dirs files2", showPretty files2]+    -- let hpname = blogAuthorToSuppress sett4+    ixfiles <- mapM (getFile2index debug pubf sett4 ) files2++    when (inform debug) $ putIOwords ["getDirContent2dirs ixfiles", showPretty ixfiles]++    let subindexDirs = map (\d -> d </> makeRelFile "index.md") dirs5+    +    when (inform debug) $  putIOwords ["getDirContent2dirs subindexDirs", showPretty subindexDirs]+    ixdirs <- mapM (getFile2index  debug pubf sett4 ) subindexDirs++    when (inform debug) $ putIOwords ["getDirContent2dirs xfiles", showPretty ixfiles, "\n ixdirs", showPretty ixdirs]++    return (catMaybes ixdirs, catMaybes ixfiles)++++getFile2index :: NoticeLevel -> PubFlags -> Settings  -> Path Abs File -> ErrIO (Maybe IndexEntry)+-- get a file and its index+-- collect data for indexentry (but not recursively, only this file)+-- the directories are represented by their index files+-- produce separately to preserve the two groups+-- the excluded (do not bake) files are filtered out before+getFile2index debug pubf sett4   fnin =+    do+        when (inform debug) $ putIOwords ["getFile2index fnin", showPretty fnin+                ,"\ndebug", showT debug]++        -- mdfile <- read8 fnin markdownFileType +        -- pd <- readMarkdown2 mdfile+        -- -- could perhaps "need" all ix as files?++        -- let (Docrep y1 _) = pandoc2docrep doughP fnin pd+        (Docrep y1 _) <- readMarkdownFile2docrep debug sett4  fnin +        -- needs the indexentry initialized+        -- does include the DNB files, bombs with ff ligature+        let incl = includeBakeTest3docrep pubf y1+        +        if incl then do+            let ix1 :: IndexEntry =  dyIndexEntry y1+            when (inform debug) $ putIOwords ["getFile2index ix1", showPretty ix1]+            return . Just $ ix1+                        +        else return Nothing ++
+ src/Lib/IndexMake.hs view
@@ -0,0 +1,176 @@+{-# LANGUAGE DeriveGeneric         #-}+---------------------------------------------------------------------+--+-- Module      :   +-- | create an index for a directory+--  in two steps: +--  IndexCollect: collect all the date +--  with call to addIndex2yam+--  and+--  indexMake: convert collected data for printing (convertIndexEntries)+--  . +--  the data is stored in a file separately and managed by Shake+--  operates on metapage (or less? )+-- this could all be pure code?+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}++module Lib.IndexMake (module Lib.IndexMake) where++-- import           Foundational.Filetypes4sites+import           Foundational.MetaPage+import Uniform.Json ( FromJSON, ToJSON, ErrIO ) +import Uniform.Latex +import           UniformBase+import Data.List (sortOn)+-- import Wave.Md2doc (includeBakeTest3docrep)++convertIndexEntries :: NoticeLevel ->  [Text] -> Text -> IndexEntry -> ErrIO MenuEntry+-- ^ take the index entries and convert their+-- form and push them back into the json+-- converts to values for printing if indexpage else null+-- date today is passed to feed in pages +-- the authors which should be oppressed are passed +-- is pure except for today! TODO today is not used +-- use the date from the siteHeader? TODO+convertIndexEntries debug hpAuthor indexSortField  ixe1 =+  do+    when (inform debug) $ putIOwords ["convertIndexEntries", "start ixe1", showT ixe1+        , "\n\thpAuthor", showT hpAuthor]+    let fn = makeAbsFile $ ixfn ixe1+    when (inform debug) $ putIOwords ["convertIndexEntries", "fn", showT fn]+    menu4 <- if isIndexPage fn+        then do+            let fils = fileEntries ixe1  +            let dirs = dirEntries ixe1  ++            let menu1 = convert2index hpAuthor (indexSortField ) (ixe1, fils, dirs)+            -- let menu3 = menu1{today3 = "2021-01-01"}  +            -- to avoid the changes in testing leading to failures+            today1 :: UTCTime <- getCurrentTimeUTC+            let menu3 = menu1 -- {today3 = showT today1}+            when (inform debug) $ putIOwords ["convertIndexEntries", "menu3", showT menu3]+            return menu3+        else return zero+    return menu4++-- | convert the indexEntry1s and put some divider between+-- TODO  - avoid dividers if list empty+convert2index :: [Text] -> Text -> +  (IndexEntry, [IndexEntry], [IndexEntry]) ->+  MenuEntry+convert2index hpAuthor indexSortField (this, fils, dirs) =+    MenuEntry+        { menu2subdir = sortField . (getIndexEntryPure hpAuthor) $ dirs+        , menu2files  = sortField . (getIndexEntryPure hpAuthor) $ fils+        -- . indexFilter - if needed then use includeBakeTest3docrep from md2doc +        -- , today3 = zero -- is set afterwards+        }+ where   -- done in collection now?+    sortField = case (indexSortField) of +        "filename" -> sortOn text2+        "date"      -> sortOn date2+        "reversedate" -> reverse . sortOn  date2+        _ -> sortOn text2  -- what is best default? id?++-- indexFilter :: [IndexEntry] -> [IndexEntry]+-- indexFilter ixs = ixs -- filter ((Just "true" ==) . publish ) ixs+--     -- does not work because publish is not set+--     -- todo remove +++-- | the lines for the index +-- TODO make a variant for the breaing marks+data Index4html = Index4html+  { -- fn :: Path Abs File   -- ^ naked filename -- not shown+    text2      :: Text, -- the filename with no extension as title ++    -- | the url relative web root+    link2      :: Text,  -- ^ link to html +    pdf2        :: Text, -- ^ link to pdf +    -- | the title as shown+    title2     :: Text,+    abstract2  :: Text,+    author2    :: Text,+    date2      :: Text -- UTCTime -- read the time early one to find errors+    -- publish2   :: Text  -- not yet used +                -- add language ?+    -- indexPage2 :: Bool -- mark for index entries+    }+  deriving (Generic, Eq, Ord, Show, Read)++instance Zeros Index4html where+  zero = Index4html zero zero zero zero zero zero zero +instance FromJSON Index4html++-- parseJSON = genericParseJSON h4Options+instance ToJSON Index4html+++getIndexEntryPure :: [Text]-> [IndexEntry] -> [Index4html]+-- pass the author names which should be oppressed in indices+getIndexEntryPure hpAuthor ixe2 = map (getOneIndexEntryPure hpAuthor)  ixe2+                    -- mapMaybe (\i -> if (Just "true" == publish i)+                    --               then Just $ getOneIndexEntryPure i+                    --               else error "xsdwer" ) ixe2++getOneIndexEntryPure :: [Text] -> IndexEntry -> Index4html++-- | the pure code to compute an IndexEntry+-- Text should be "/Blog/postTufteStyled.html"+getOneIndexEntryPure hpAuthor indexEntry1 =+  Index4html+    { text2 = s2t . takeBaseName'   . ixfn $ indexEntry1+    , link2 =  convertLink2html indexEntry1+    , pdf2 =  convertLink2pdf  indexEntry1 +    , abstract2 = abstract indexEntry1+    , title2 =+        if isZero (title indexEntry1 :: Text)+          then s2t . takeBaseName'   .  ixfn $ indexEntry1+          else title indexEntry1+    , author2 = blankAuthorName hpAuthor (author indexEntry1)+    , date2 = date indexEntry1+    -- , publish2 = shownice $ publish indexEntry1+    --   indexPage2 = indexPage indexEntry1+    }++blankAuthorName :: [Text] -> Text -> Text +-- suppress/oppress author name, if the author name is the same as one in the first arg (AUF, Andrew U..) then set it to empty else copy +-- idea is to avoid to have each page say the obvious "author XX"+blankAuthorName names current = +    if current `elem` names +        then zero +        else current ++-- hpAuthor :: [Text]+-- the list of authornames which are blanked+-- should be the author of the blog+-- hpAuthor = ["AUF", "Andrew U. Frank"]++--       ------  S U P P O R T+-- the MenuEntry is one entry in the menu list +data MenuEntry = MenuEntry {menu2subdir :: [Index4html]+                            , menu2files :: [Index4html]+    -- , today3 :: Text +                            }+  -- menu2 is referenced in the template+  deriving (Generic, Eq, Ord, Show, Read)++-- instance NiceStrings MenuEntry where+--     shownice = showNice++instance Zeros MenuEntry where+  zero = MenuEntry zero zero ++instance FromJSON MenuEntry++-- parseJSON = genericParseJSON h4Options++instance ToJSON MenuEntry++--  toJSON = genericToJSON h4Options
+ src/Lib/Templating.hs view
@@ -0,0 +1,73 @@+----------------------------------------------------------------------+--+-- Module      :   applying a template (using pandoc)+--+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+-- {-# LANGUAGE TypeSynonymInstances  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++module Lib.Templating where -- (openMain, htf_thisModuelsTests)++import Uniform.Http -- ( HTMLout(HTMLout) )++import Uniform.Json ( Value, ErrIO )+import Uniform.PandocHTMLwriter ( applyTemplate4 )+import UniformBase++putValinMaster :: NoticeLevel -> [Value] -> Path Abs File -> ErrIO HTMLout+{- ^ get the master html template and put the val into it+ takes the master filename from val+ not clear what intended+ for now: use the master TODO+-}+putValinMaster debug vals masterfn = do+    when (inform debug) $ putIOwords ["putValinMaster", "masterfn", showT masterfn]++    template2 :: Text <- readFile2 (toFilePath masterfn)++    -- templatapplyTemplate3 debug masterfn vals -- inTemplate.html+    html2 <- applyTemplate4 (inform debug) template2 vals  +    return . HTMLout $ html2++{- list of variables potentially used by Master5.dtpl:+css - name of stylesheet+date +keywords  (list)+page-title +page-title-isPostfix +include-before +siteHeader+    sitename +    byline +    banner +    bannerCaption+menu +    link +    text +title +subtitle +author +menu2 +    link2 +    title2 +    abstract2+    author2 +    date2 +    -- publish2 +table-of-contents +beforeContent+abstract +contentHtml +afterContent +dainoversion+today+Filenames +filename3  -- the current filename producing the page+include_after  +dainoversion+-}
+ src/ShakeBake/Bake.hs view
@@ -0,0 +1,195 @@+---------------------------------------------------------------------+--+-- Module      :+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans +            -fno-warn-missing-signatures+            -fno-warn-missing-methods +            -fno-warn-unused-matches #-}++{- |  process to convert+              files from md to all the formats required+              orginals are found in dire doughDir and go to bakeDir+-}+module ShakeBake.Bake where++import Foundational.SettingsPage  +import Foundational.CmdLineFlags++import Foundational.Filetypes4sites++import Wave.Docrep2panrep +import Wave.Md2doc  +import Wave.Panrep2pdf+++-- import Uniform2.Markdown  +-- import Uniform.Pandoc+-- import Uniform2.ProcessPDF  +import Uniform.Http++import Wave.Panrep2html  +import UniformBase+-- import Foundational.SettingsPage (SiteLayout(texTemplateFile))++type BakeOp =+    NoticeLevel ->+    PubFlags ->+    -- | md file+    Path Abs File ->+    Settings->+    Path Abs File ->+    ErrIO [FilePath] -- additional needs found ++bakeOneMD2docrep :: BakeOp --    MD -> DOCREP+-- process the md to pandoc format (parser)+-- and add the refs +bakeOneMD2docrep debug flags inputFn sett3 resfn2 = do+    when (inform debug) $    putIOwords+        [ "\n-----------------"+        , "bakeOneMD2docrep 1 fn", showT inputFn+        , "\n resfn2", showT resfn2+        ]+    -- let layout = siteLayout sett3+    -- let doughP = doughDir layout+    -- let hpname = blogAuthorToSuppress . siteLayout $ sett3+    dr3 <- readMarkdownFile2docrep debug sett3  inputFn +    dr4 <- addRefs debug dr3++    write8 resfn2 docrepFileType dr4++    when (inform debug) $+        putIOwords+            [ "\n-----------------"+            , "bakeOneMD2docrep done resfn2"+            , showT resfn2+            ]+    return []++bakeOneDocrep2panrep :: BakeOp --  DOCREP -> PANREP+--   add index  +bakeOneDocrep2panrep debug flags inputFn sett3 resfn2 = do+    when (inform debug) $    putIOwords+        [ "-----------------"+        , "bakeOneDocrep2panrep 1 inputFn"+        , showT inputFn+        , showT resfn2+        ]+    dr1 <- read8 inputFn docrepFileType++    -- let layout = siteLayout sett3+    (p3, needsFound) <- docrep2panrep debug flags sett3 dr1+            -- completes index and should process reps +            -- what to do with needs?+    -- needP needsFound ++    write8 resfn2 panrepFileType p3 -- content is html style+    when (inform debug) $+        putIOwords+            ["\n-----------------", "bakeOneDocrep2panrep done produced resf2n", showT resfn2]+    return needsFound+++bakeOnePanrep2html :: BakeOp -- PANREP -> HTML  -- TODO+bakeOnePanrep2html debug flags inputFn sett3 resfn2 = do+    when (inform debug) $    putIOwords+        [ "\n-----------------"+        , "bakeOnePanrep2html 1 fn"+        , showT inputFn+        , "\n resfn2"+        , showT resfn2+        ]+    dr1 <- read8 inputFn panrepFileType+    -- let layout = siteLayout sett3+    -- this gives the siteLayout section of settingsN.yml file+    -- let staticMenu = sett3+    -- let mf = masterTemplateFile layout+    -- let masterfn = templatesDir layout </> mf++    p <- panrep2html debug  sett3 dr1++    write8 resfn2 htmloutFileType p -- content is html style+    when (inform debug) $+        putIOwords+            ["\n-----------------", "bakeOnePanrep2html done fn", showT resfn2]+    return []+++bakeOnePanrep2texsnip :: BakeOp --  PANREP -> TEXSNIP+-- TODO+bakeOnePanrep2texsnip debug flags inputFn sett3 resfn2 = do+                -- debug flags inputFn layout resfn2 +    when (inform debug) $    putIOwords+        [ "\n-----------------"+        , "bakeOnePanrep2texsnip 1 fn"+        , showT inputFn+        , "debug"+        , showT debug+        , "\n resfn2"+        , showT resfn2+        ]++    dr1 <- read8 inputFn panrepFileType+    snip1 <- panrep2texsnip debug dr1+    write8 resfn2 texSnipFileType snip1 -- content is html style+    when (inform debug) $+        putIOwords+            ["\n-----------------", "bakeOneFile2html done fn", showT resfn2]+    return []++bakeOneTexsnip2tex :: BakeOp -- TEXSNIP -> TEX+bakeOneTexsnip2tex debug flags inputFn sett3 resfn2 = do+    when (inform debug) $   putIOwords+        [ "\n-----------------"+        , "bakeOneFile2tex 1 fn"+        , showT inputFn+        , "\n resfn2"+        , showT resfn2+        ]+++    snip1 <- read8 inputFn texSnipFileType++    let layout = siteLayout sett3+    let doughP = doughDir layout+        bakedP = bakedDir layout +++    tex1 <- texsnip2tex NoticeLevel0 doughP bakedP snip1 +        ((templatesDir layout) </> (texTemplateFile layout))+    -- let tex1 = tex2latex2 zero [snip1]+    write8 resfn2 texFileType tex1 -- content is html style+    when (inform debug) $+        putIOwords+            ["\n-----------------", "bakeOneFile2tex done fn", showT resfn2]+    return []++bakeOneTex2pdf :: BakeOp+bakeOneTex2pdf debug flags inputFn sett3 resfn2 = do+    when (inform debug) $    putIOwords+        [ "\n-----------------"+        , "bakeOneTex2pdf 1 fn:"+        , showT inputFn+        , "\n\t debug:"+        , showT debug+        , "\n\t resfn2:"+        , showT resfn2+        ]++    -- let refDir =+            -- makeAbsDir . getParentDir . toFilePath $ inputFn :: Path Abs Dir+    -- dr1 <- read8 inputFn docrepFileType+    let layout = siteLayout sett3+    let doughP = doughDir layout++    tex2pdf debug  inputFn resfn2 doughP -- content is html style+    when (inform debug) $+        putIOwords+            ["\n-----------------", "bakeOneTex2pdf done fn", showT resfn2]+    return []
+ src/ShakeBake/CmdLineArgs.hs view
@@ -0,0 +1,139 @@+----------------------------------------------------------------------+--+-- Module      :   +-- | a command line argument setup+--                  is a Main and starts with convenience+-- for information see https://github.com/pcapriotti/optparse-applicative+-- change the getAttr function to return Text+----------------------------------------------------------------------+  {-# LANGUAGE+  MultiParamTypeClasses+      , FlexibleInstances+      , FlexibleContexts+      , ScopedTypeVariables+      , OverloadedStrings+      , TypeFamilies++  #-}++module ShakeBake.CmdLineArgs where+import UniformBase+import Uniform.CmdLineArgs   -- from u2to +  +import Foundational.CmdLineFlags +-- import Foundational.SettingsPage +import Foundational.MetaPage+-- import Options.Applicative.Builder()++-- | the command line arguments raw+--  number of args must correspond in order and number with the+--  command arguments described in the parser+data LitArgs = LitArgs+  {+   draftSwitch -- x^ d+  , privateSwitch -- x^ v+--   , publishSwitch  -- x^ p+--   , oldSwitch -- x^ o+--   , finishedSwitch -- x^ f +  , testSwitch  -- x^ t+  , testNewSwitch -- x^ T -- test after delete to create all new+  , quickSwitch -- x^ q+  , serverSwitch -- x^ s +  , watchSwitch -- x^ w +--   , uploadSwitch -- x^ u  -- not yet used  +         :: Bool+  , locationDirArg -- x^ l +        :: String+   } deriving (Show)++cmdArgs :: Parser LitArgs+-- | strings which have no default result in enforced arguments+-- order and type of arguments must correspod to LitArgs+cmdArgs  =  +  LitArgs+    <$> switch (long "draft" <> short 'd' +        <> help "include draft material, else only `publish`")+    <*> switch+          (long "private" <> short 'p' <> help+            "include the private data, else only public"+          )+    -- <$> switch+    --       (long "publish" <> short 'p' <> help+    --         "include material ready to publish"+    --       )+    -- <*> switch (long "old" <> short 'o' <> help "include old material")+    <*> switch+          (long "test" <> short 't' <> help+            "use test data (site/dough), continue test, start server on port set"+          )+    <*> switch+          (long "testComplete" <> short 'T' <> help+            "use test data (site/dough), complete test, start server on port set"+          )+    <*> switch+          (long "quick" <> short 'q' <> help+            "produce only html, but not the (slow) pdf's"+          )+    <*> switch+          (long "server" <> short 's' +                -- <> value True   -- not working+                <> help "start a server on port set in siteHeader file")+    <*> switch+        (long "watch" <> short 'w' <> help+          "start the watch of files for restarting bake"+        )+    <*>  strOption+        (long "location" <> short 'l' <> value "." <> help +            "the directory in which to find the settings file")+    -- <*> switch+    --     (long "upload" <> short 'u' <> help+    --       "upload to external server"+    --     )++++++parseArgs2input ::   Text -> Text -> ErrIO PubFlags+-- getting cmd line arguments, produces the input in the usable form+--  with a default value for the file name+-- the two text arguments are used in the cmd arg parse+-- is specific to the parser (and thus to the cmd line arguments++parseArgs2input   t1 t2 = do+  args1 <- getArgsParsed t1 t2+  when False $ putIOwords ["parseArgs2input: args found", showPretty args1]+  workingdir1 :: Path Abs Dir <- currentDir+++  let flags1 = PubFlags { draftFlag    = draftSwitch args1+                        -- , publishFlag  = publishSwitch args1+                        --  , oldFlag      = oldSwitch args1+                         , privateFlag  = privateSwitch args1+                         , testFlag     = testSwitch args1+                         , testNewFlag = testNewSwitch args1+                         , quickFlag    = quickSwitch args1+                         , serverFlag   = serverSwitch args1+                         , watchFlag    = watchSwitch args1+                         , locationDir = locationDirArg args1+                         -- perhaps wrong, could be site/dough?+                        -- ,  uploadFlag = uploadSwitch args1+                         }++--   let flags2 = if testFlag flags1+--         then flags1 { settingsFile = testdataDir </> settingsFileName }+--                     --  ,  PortNumber = sourceDirTest+--         else flags1++  when False $ putIOwords ["parseArgs2input:  inputs ", showPretty flags1]+  return flags1++++getArgsParsed :: Text -> Text -> ErrIO LitArgs+getArgsParsed  t1 t2 = do+        args <- callIO $ execParser opts+        return args+    where+        opts  = info (helper <*> cmdArgs)+                  (fullDesc <> (progDesc . t2s $ t1) <> (header . t2s $ t2))
+ src/ShakeBake/ConvertFiles.hs view
@@ -0,0 +1,140 @@+---------------------------------------------------------------+--+-- Module      :+---------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans +            -fno-warn-missing-signatures+            -fno-warn-missing-methods +            -fno-warn-unused-matches #-}++{- | convert the files and put in targe dir+              input is target filename+          this is the interface (only one) from shake to bake+-}+module ShakeBake.ConvertFiles where++import ShakeBake.Bake++import Foundational.Filetypes4sites+import Foundational.SettingsPage+import Foundational.CmdLineFlags++import Uniform.Pandoc++import Uniform.Shake+-- import UniformBase+++io2bool :: MonadIO m => ErrIO b -> m b+io2bool op = do+    -- todo move+    x <- liftIO $ runErr op+    let res = case x of+            Left msg -> errorT [msg]+            Right b -> b+    return res++convertAny ::+    NoticeLevel ->+    Path Abs Dir ->+    Path Abs Dir ->+    PubFlags ->+    Settings ->+    FilePath ->+    -- | the name of the operation+    Text ->+    Action ()+-- produce any (either copy available in baked or produce with anyop)+convertAny debug sourceP targetP flags layout out anyopName = do+    when (inform debug) $ +        putIOwords ["-----------------", "convertAny for", anyopName]+    let outP = makeAbsFile out :: Path Abs File+    when (inform debug) $ putIOwords ["\nconvertAny 1", "\n file out", showT out]+    let (anyop, sourceExtA) = case anyopName of +            "convMD2docrep" -> (bakeOneMD2docrep, extMD)+            "convDocrep2panrep" -> (bakeOneDocrep2panrep, extDocrep)+            "convPanrep2texsnip" -> (bakeOnePanrep2texsnip, extPanrep )+            "convPanrep2html" -> (bakeOnePanrep2html, extPanrep )+            "convTex2pdf" -> (bakeOneTex2pdf, extTex )+            "convTexsnip2tex" -> (bakeOneTexsnip2tex, extTexSnip )+            _  -> errorT ["convertAny error unknown anyopName ", anyopName]++    let fromfilePath = sourceP </> makeRelativeP targetP outP+    let fromfilePathExt = replaceExtension' (s2t . unExtension $ sourceExtA) fromfilePath ++    when (inform debug) $ putIOwords +        ["\nconvertAny 2", anyopName+        , "extension", (s2t . unExtension $ sourceExtA)+        ,  "\n fromfilePath", showT fromfilePath+        , " was causing NEED"   +        ,  "\n fromfilePathExt", showT fromfilePathExt   +        ,  "\n file out", showT out+        ] ++    fileExists <-  if sourceP == targetP +        then return False +        else io2bool $ doesFileExist' fromfilePath  --targetExt++    when (inform debug) $+        putIOwords+            [ "\nconvertAny - fromfile exist:"+            , showT fileExists+            -- , "\nfile"+            -- , showT fromfilePath+            ]+    if fileExists +        -- gives recursion, if the file is produced in earlier run+        then do  -- copy file from source to target+            copyFileChangedP fromfilePath outP+            when (inform debug) $+                -- liftIO $+                    putIOwords+                        ["\n convertAny  copied"+                         ,   "\n\tfromfilePath ", showT fromfilePath, "added NEED automatically"+                         ,  "\n\t  file out", showT out]+        else do+            when (inform debug) $ putIOwords +                ["\nconvertAny call", anyopName+                ,  "\n\t fromfilePathExt"+                    ,  " cause NEED for" ,showT fromfilePathExt  +                ,  "\n\t file out", showT out+                ] +            need [toFilePath fromfilePathExt]    +            when (inform debug) $ putIOwords +                ["\nconvertAny runErr2Action", anyopName+                ,  "\n\t fromfilePathExt",  " caused NEED which was then probably satisfied for ", showT fromfilePathExt   +                ,  "\n\t file out", showT out+                ]+            needsFound <- runErr2action $ anyop debug flags fromfilePathExt layout outP+            need needsFound+    when (inform debug) $ putIOwords ["convertAny end for", anyopName]+    return ()++{- | the generic copy for all the files+ which can just be copied+ (exceptions md, which are a special case of needed)+-}+copyFileToBaked ::+    ( Filenames3 fp (Path Rel File)+    , FileResultT fp (Path Rel File) ~ Path Abs File+    ) =>+    NoticeLevel ->+    fp ->+    Path Abs Dir ->+    FilePath ->+    Action ()+copyFileToBaked debug doughP bakedP out = do+    let outP = makeAbsFile out :: Path Abs File+    when (inform debug) $ liftIO $ putIOwords ["\ncopyFileToBaked outP", showT outP]+    let fromfile = doughP </> makeRelativeP bakedP outP+    when (inform debug) $+            putIOwords+                ["\ncopyFileToBaked fromfile ", showT fromfile, "added NEED automatically"]+    copyFileChangedP fromfile outP
+ src/ShakeBake/ReadSettingFile.hs view
@@ -0,0 +1,36 @@+---------------------------------------------------------------------+--+-- Module      :   read the setting file++----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++module ShakeBake.ReadSettingFile where  ++import Foundational.SettingsPage+-- import Uniform.Json+import Uniform.Yaml+import UniformBase++readSettings :: NoticeLevel -> Path Abs File -> ErrIO  Settings++{- | must be the settingsNN.yaml file, (absolute, fixed before to current dir)+ which contain the rest of the siteHeader+ returns layout and port+-}+readSettings debug settingsfilename =+    do+        when (inform debug) $+            putIOwords+                [ "readSettings"+                , "file"+                , showPretty settingsfilename+                ]+        sett3 :: Settings <- readYaml2rec settingsfilename +        return sett3 +
+ src/ShakeBake/Shake2.hs view
@@ -0,0 +1,412 @@+----------------------------------------------------------------------+--+-- Module Shake2 :+----------------------------------------------------------------------+{-  die struktur geht von den files aus, die man braucht und+    diese rekonstruieren die directories wieder, wenn sie kreiert werden.++    the start is with /getNeeds/ in phony:+        - md produces pdf+            - with convTex2pdf, calling+            - write2pdf (runs lualatex)+        - md produces html+            - with convPanrep2html, calling+            - bakeOneFile2panrep+            - docrep2panrep++    wird moeglicherweise ein filetyp (durch extension fixiert) aus zwei quellen produziert so muss dass in der regel fuer die generation+        beruecksichtigt werden+        (probleme html - entweder durch uebersestzen oder als resource eingestellt+        (problem pfd - dito )+        )++        anders geloest: +        test ob file in dough existiert, dann kopiert++    ausgeschlossene directories werden durch DNB  markiert+    die files die in diesen gefunden werden, nicht zum umwandeln+        anzumelden, indem deren namen nicht in "want" eingeschlossen+        werden.++    pdf werden aus tex erzeugt, die aus texsnip erzeugt werden.+    jedes md ergibt ein texsnip+    jedes texsnip gibt ein tex+        die indexseiten, die grosse themen zusammenfassen+        produzieren ein tex mit includes fuer die subseiten+        und der preamble/post fuer e.g. biblio+    jedes tex gibt ein pdf+    das heisst: jedes md gibt ein pdf (auch eingestellte)+    -}+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans+            -fno-warn-missing-signatures+            -fno-warn-missing-methods+            -fno-warn-duplicate-exports  #-}+++module ShakeBake.Shake2 where++import           Uniform.Shake++import Foundational.SettingsPage+    -- ( SiteLayout(doughDir, bakedDir, themeDir),+    --   Settings(siteLayout) )+import Foundational.CmdLineFlags+      +import ShakeBake.ConvertFiles+    ( io2bool, convertAny, copyFileToBaked )++import Wave.Md2doc ++-- shakeDelete :: SiteLayout -> FilePath -> ErrIO ()+-- {- ^ experimental - twich found delete of md+--  not yet used+-- -}+-- shakeDelete _ filepath =+--     putIOwords+--         [ "\n\n*******************************************"+--         , "experimental -- twich found  DELETED MD file "+--         , s2t filepath+--         ]++shakeArgs2 :: Path b t -> Rules () -> IO ()++{- | set the options for shake+ called in shakeMD+-}+shakeArgs2 bakedP = do+    -- putIOwords ["shakeArgs2", "bakedP", s2t . toFilePath $ bakedP]+    res <-+        shake+            shakeOptions+                { shakeFiles = toFilePath bakedP  -- wgy should the shake files to into baked?+                , shakeVerbosity = Info -- Verbose --  Loud+                        -- verbose gives a single line for each file processed+                        --          plus info for copying+                        -- info gives nothing in normal process +                , shakeLint = Just LintBasic+                }+    -- putIOwords ["shakeArgs2", "done"]+    return res++shakeAll :: NoticeLevel -> Settings -> PubFlags -> FilePath -> ErrIO ()+-- ^ calls shake in the IO monade. this is in the ErrIO+shakeAll debug sett3 flags causedby = do+    let layout = siteLayout sett3 +        doughP = doughDir layout -- the regular dough+        bakedP = bakedDir layout+        themeP = themeDir layout+    putIOwords+        [ "\n\n===================================== shakeAll start"+        , "\n flags"+        , showPretty flags+        , "\ncaused by"+        , s2t causedby+        , "."+        , "\ndebug:", showT debug+        , "\ndough", showT doughP +        , "\nbaked", showT bakedP +        , "\ntheme", showT themeP ++        , "\n======================================="+        ]+            +    callIO $ shakeMD debug sett3 flags doughP bakedP++-- todo remove shakeMD and pass only layout++shakeMD ::+    NoticeLevel ->+    Settings ->+    PubFlags ->+    Path Abs Dir -> -- dough (source for files)+    Path Abs Dir -> -- baked (target dir for site)+    IO ()+{- ^ bake all md files and copy the resources+ from each md produce:+    - html +    - pdf + sets the current dir to doughDir+ copies banner image+ in IO+ TOP shake call+-}+shakeMD debug sett4 flags doughP bakedP = shakeArgs2 bakedP $ do+    -- the special filenames which are necessary+    -- because the file types are not automatically+    -- copied+    -- todo remove doughP and bakedP++    when (inform debug) $ putIOwords+                                [ "shakeMD dirs\n"+                                    , "\tbakedP\n"+                                , showT bakedP+                                ]+    -- let siteDirs = siteLayout sett4 +        -- doughP = doughDir siteDirs -- the regular dough+        -- bakedP = bakedDir siteDirs+        -- themeP = themeDir siteDirs++++    want ["allMarkdownConversion"]++    phony "allMarkdownConversion" $ do+        -- these are functions to construct the desired results+        -- which then produce them+        -- the original start needs in baked (from the files in dough)++        -- put a link to the themplates folder into dough/resources+        -- otherwise confusion with copying the files from two places++        -- from the theme folder copy woff, css and jpg/JPG +        -- woffTheme <- getNeeds debug sett4 themeP bakedP "woff" "woff"+        -- needP woffTheme+        -- imgsTheme <- getNeeds debug sett4   themeP bakedP "jpg" "jpg"+        -- imgs2Theme <- getNeeds debug sett4   themeP bakedP "JPG" "JPG"+        -- needP imgsTheme+        -- needP imgs2Theme+        -- cssTheme <- getNeeds debug sett4 themeP bakedP "css" "css"+        -- needP cssTheme++            -- do the images first to be findable by latex processor+        imgs <- getNeeds debug sett4   doughP bakedP "jpg" "jpg"+        imgs2 <- getNeeds debug sett4   doughP bakedP "JPG" "JPG"+        needP imgs+        needP imgs2++        unless (quickFlag flags) $ do +            pdfs <- getNeedsMD debug flags sett4 doughP bakedP "md" "pdf"+            needP pdfs++        htmls <- getNeedsMD debug flags sett4 doughP bakedP "md" "html"+        needP htmls++        csss <- getNeeds debug sett4   doughP bakedP "css" "css"+        needP csss++        -- fonts, takes only the woff+        -- from the link to the template folder+        woffs <- getNeeds debug sett4   doughP bakedP "woff" "woff"+        needP woffs++        publist <- getNeeds debug sett4   doughP bakedP "html" "html"+        needP publist+        -- for the pdfs which are already given in dough+        pdfs2 <- getNeeds debug sett4   doughP bakedP "pdf" "pdf"+        needP pdfs2+        bibs <- getNeeds debug sett4   doughP bakedP "bib" "bib"+        needP bibs+++    (toFilePath bakedP <> "**/*.html") %> \out -> -- from Panrep+    -- calls the copy html if a html exist in dough +            -- else calls the conversion from md++        do+            when (inform debug) $ putIOwords ["rule **/*.html", showT out]++            let outP = makeAbsFile out :: Path Abs File+            let fromfile = doughP </> makeRelativeP bakedP outP+            fileExists <- io2bool $ doesFileExist' fromfile+            when (inform debug) $ putIOwords ["rule **/*.html - fileExist:", showT fileExists]+            +            if fileExists +                then copyFileToBaked debug doughP bakedP out+                else +            -- csss <- getNeeds debug sett4 doughP bakedP "css" "css"+            -- needP csss+            -- -- csss seems not necessary+            -- imgs <- getNeeds debug sett4 doughP bakedP "jpg" "jpg"+            -- imgs2 <- getNeeds debug sett4 doughP bakedP "JPG" "JPG"+            -- needP imgs+            -- needP imgs2+            -- when (inform debug) $ putIOwords ["rule **/*.html", showT out]+  +                    convertAny debug bakedP bakedP flags sett4 out  "convPanrep2html"+++    (toFilePath bakedP <> "**/*.pdf") %> \out -> -- insert pdfFIles1+        do+            when (inform debug) $ putIOwords ["rule **/*.pdf", showT out]+            -- imgs <- getNeeds debug sett4 doughP bakedP "jpg" "jpg"+            -- imgs2 <- getNeeds debug sett4 doughP bakedP "JPG" "JPG"+            -- needP imgs+            -- needP imgs2+            -- why is this here necessary: failed on testSort.pdf?+            -- was ein jpg will ?+            -- TODO improve error from lualatex+            -- when (inform debug) $ putIOwords ["rule **/*.pdf need", showT imgs, showT imgs2]++            let outP = makeAbsFile out :: Path Abs File+            let fromfile = doughP </> makeRelativeP bakedP outP+            fileExists <- io2bool $ doesFileExist' fromfile+            when (inform debug) $ putIOwords ["fileExist:", showT fileExists]+            +            if fileExists +                then copyFileToBaked debug doughP bakedP out+                else             +                    convertAny debug bakedP bakedP flags sett4 out  "convTex2pdf"++    (toFilePath bakedP <> "**/*.tex") %> \out -> -- insert pdfFIles1+        convertAny debug bakedP bakedP flags sett4 out  "convTexsnip2tex"++    (toFilePath bakedP <> "**/*.texsnip") %> \out -> -- insert pdfFIles1+        convertAny debug bakedP bakedP flags sett4 out  "convPanrep2texsnip"++    (toFilePath bakedP <> "**/*.panrep") %> \out -> -- insert pdfFIles1+        do convertAny debug bakedP bakedP flags sett4 out  "convDocrep2panrep"++    (toFilePath bakedP <> "**/*.docrep") %> \out -> -- insert pdfFIles1  -- here start with doughP+        do+            -- bibs <- getNeeds debug sett4 doughP bakedP "bib" "bib"+            -- needP bibs+            -- csls <- getNeeds debug sett4 doughP bakedP "csl" "csl"+            -- needP csls+            -- when (inform debug) $ putIOwords ["rule **/*.docrep need", showT bibs]+            -- when (inform debug) $ putIOwords ["rule **/*.docrep need", showT csls]++            convertAny debug doughP bakedP flags sett4 out  "convMD2docrep"+            return ()++    -- rest are copies++    -- (toFilePath bakedP <> "/*.md") -- is required because the convA2B - but this is fixed +    --     %> \out -> -- insert css -- no subdir+            -- copyFileToBaked debug doughP bakedP out+    (toFilePath bakedP <> "/*.css")+        %> \out -> -- insert css -- no subdir+            copyFileToBaked debug doughP bakedP out+    (toFilePath bakedP <> "/*.csl")  -- not used with biber TODO +        %> \out -> -- insert css -- no subdir+            copyFileToBaked debug doughP bakedP out++    [toFilePath bakedP <> "/*.JPG", toFilePath bakedP <> "/*.jpg"]+    -- seems not to differentiate the JPG and jpg; copies whatever the original +    -- the html and/or the pdf includegraphics seem to be case sensitive, even for the extension+        |%> \out -> -- insert img files+        -- no subdir (for now)+            copyFileToBaked debug doughP bakedP out++    (toFilePath bakedP <> "**/*.bib")+        %> \out -> copyFileToBaked debug doughP bakedP out+    -- the fonts in a compressed format +    (toFilePath bakedP <> "**/*.woff")+        %> \out -> copyFileToBaked debug doughP bakedP out++getNeeds ::+    NoticeLevel +    -> Settings -- ^ the site layout etc+    -> Path Abs Dir  -- ^ source dir+    -> Path Abs Dir  -- ^ target dir+    -> Text  -- ^ extension source+    -> Text  -- ^ extension target+    -> Action [Path Abs File]+{- ^ find the files which are needed (generic)+  from source with extension ext+  does not include directory DNB (do not bake)+-}+getNeeds debug  sett4 sourceP targetP extSource extTarget = do+    let sameExt = extSource == extTarget+    when (inform debug) $+        putIOwords+            [ "===================\ngetNeeds extSource"+            , extSource+            , "extTarget"+            , extSource+            , "sameExt"+            , showT sameExt+            ]++    filesWithSource :: [Path Rel File] <- -- getDirectoryFilesP+        getFilesToBake+            (doNotBake  (siteLayout sett4)) -- exclude files containing+            sourceP+            ["**/*." <> t2s extSource]+    -- subdirs+    let filesWithTarget =+            if sameExt+                then [targetP </> c | c <- filesWithSource]+                else+                    map+                        (replaceExtension' extTarget . (targetP </>))+                         filesWithSource  +                                :: [Path Abs File]+    when (inform debug) $ do+        putIOwords+            [ "===================\ngetNeeds -  source files 1"+            , "for ext"+            , extSource+            , "files\n"+            , showT filesWithSource+            ]+        putIOwords+            [ "\nbakePDF -  target files 2"+            , "for ext"+            , extTarget+            , "files\n"+            , showT filesWithTarget+            ]+    return filesWithTarget++getNeedsMD ::+    NoticeLevel +    -> PubFlags +    -> Settings   -- perhaps the next two can be+    -> Path Abs Dir  -- ^ source dir+    -> Path Abs Dir  -- ^ target dir+    -> Text  -- ^ extension source+    -> Text  -- ^ extension target+    -> Action [Path Abs File]+{- ^ find the files which are needed (generic)+  from source with extension ext+  does not include directory DNB (do not bake)+-}+getNeedsMD debug flags sett4 sourceP targetP extSource extTarget = do+    let sameExt = extSource == extTarget+    when (inform debug) $+        putIOwords+            [ "===================\ngetNeeds extSource"+            , extSource+            , "extTarget"+            , extSource+            , "sameExt"+            , showT sameExt+            ]++    filesWithSource :: [Path Rel File] <- -- getDirectoryFilesP+        getFilesToBake+             (doNotBake  (siteLayout sett4))   -- exclude files containing+            sourceP+            ["**/*." <> t2s extSource]+    files2 <- runErr2action $ mapM (filterNeeds debug flags sett4 ) filesWithSource+    -- subdirs+    let filesWithTarget =+            if sameExt+                then [targetP </> c | c <- filesWithSource]+                else+                    map+                        (replaceExtension' extTarget . (targetP </>))+                            (catMaybes files2) :: [Path Abs File]+    when (inform debug) $ do+        putIOwords+            [ "===================\ngetNeeds -  source files 1"+            , "for ext"+            , extSource+            , "files\n"+            , showT filesWithSource+            ]+        putIOwords+            [ "\nbakePDF -  target files 2"+            , "for ext"+            , extTarget+            , "files\n"+            , showT filesWithTarget+            ]+    return filesWithTarget
+ src/ShakeBake/StartDainoProcess.hs view
@@ -0,0 +1,186 @@+----------------------------------------------------------------------+--+-- Module      :   convert a homepage+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans +            -fno-warn-missing-signatures+            -fno-warn-missing-methods +            -fno-warn-duplicate-exports +            -fno-warn-unused-imports +            -fno-warn-unused-matches #-}++{- | to convert+              files in any input format (primarily md) +                to html and to pdf +              orginals are found in dire doughDir and go to bakeDir+-}++module ShakeBake.StartDainoProcess (dainoProcess) where++import ShakeBake.ReadSettingFile (readSettings)+import ShakeBake.Shake2 (shakeAll)+import ShakeBake.Watch (mainWatch)+import Uniform.WebServer (runScotty)+import Foundational.SettingsPage+import Foundational.CmdLineFlags+import Paths_daino  +import UniformBase+import qualified Path.Posix as Path+import qualified System.FilePath.Posix as P+-- import System.Directory (canonicalizePath)+-- import Filesystem.Path.CurrentOS (decodeString, encodeString, collapse)++import Path.IO (resolveDir, getHomeDir, createDirLink, getSymlinkTarget, removeDirLink)+-- now in fileio+-- import System.Posix.Files (readSymbolicLink,createSymbolicLink)++dainoProcess :: NoticeLevel -> PubFlags -> ErrIO ()+dainoProcess debug flags = do+    let useTestSite = (testFlag flags || testNewFlag flags)+    putIOwords ["dainoProcess 1 useTestSite", showT useTestSite]+    currDir :: Path Abs Dir  <- currentDir +    let relSettingsFile :: Path Rel File = makeRelFile "settings3.yaml"+    sett4dir <- if useTestSite +        then do+            when (inform debug) $ putIOwords ["dainoProcess 2test useTestSite"]+            return $ (Path.parent currDir) </> makeRelDir "dainoSite"  +  +        else if (P.isAbsolute (locationDir flags)) +            then do +                putIOwords ["dainoProcess 2test location abs dir",  showT (locationDir flags)]+                return $  (makeAbsDir . locationDir $ flags)  +            else if (P.isRelative (locationDir flags))+                then do +                    putIOwords ["dainoProcess 5 location relative",  showT (locationDir flags)]+                    absdir <- resolveDir currDir (locationDir flags)+                    -- problem initial .. bad hack!+                     +                    -- canonFP <- liftIO $ canonicalizePath (locationDir flags)+                    -- let    absdir = makeAbsDir canonFP +                        -- combPath = toFilePath currDir </> (locationDir $ flags) :: FilePath +                        -- collPath = collapse . decodeString $ combPath   +                        -- absdir = makeAbsDir . encodeString $ collPath :: Path Abs Dir +                    return absdir +                    -- return . makeAbsDir . collapse $ (toFilePath currDir </> (locationDir $ flags))  -- path starting with .. possible ++            else +                errorT ["dainoProcess 5 location not valid",  showT $ locationDir flags]+                 +    when (inform debug) $ putIOwords ["dainoProcess 5 dir of settings file",  showT sett4dir]+    let sett4file = sett4dir </> relSettingsFile +    when (inform debug) $ putIOwords ["dainoProcess 5  settings file",  showT sett4file]+ +    existSett <- doesFileExist' (sett4file) +    sett4 <- if existSett +        then readSettings debug sett4file -- (currDir </> settingsFileName) +        else  errorT ["dainoProcess 1", "error settingsFile not present in"+                    , showT sett4file +                    , "perhaps need install dainoSite with `git clone git@github.com:andrewufrank/dainoSite.git"]            +++-- put a link to theme into dough/resources+    let themeDir1 = themeDir (siteLayout sett4) :: Path Abs Dir+    let doughP = doughDir (siteLayout sett4) :: Path Abs Dir++    doughExist <- doesDirExist' doughP+    unless doughExist $+            errorT ["dainoProcess 2", "error dough not present", "install dainoSite with `git clone git@github.com:andrewufrank/dainoSite.git"]++++    let link1 =  doughP </> (makeRelDir resourcesName) </> (makeRelDir themeName) :: Path Abs Dir+    let target1 = themeDir1  :: Path Abs Dir+    when (inform debug) $ putIOwords ["dainoProcess 3 check simlink \n    target   ",  showT target1+                                            , "\n    linked to", showT link1]+    linkExists <- doesDirExist' link1+    targetOK <- if linkExists +        then do+            targetNow <- getSymlinkTarget link1+            when (inform debug) $ putIOwords ["dainoProcess 5 current \n    target for theme  ",  showT targetNow]+            if (makeAbsDir targetNow) == target1 then return True+                else do +                    removeDirLink link1+                    putIOwords ["dainoProcess remove previous link"]++                    return False++        else do+            return False ++    unless targetOK $ do +            putIOwords ["dainoProcess 4 create simlink \n    target   ",  showT target1+                                            , "\n    linked to", showT link1]+            createDirLink  ( target1) ( link1)+++-- set the currentWorkingDir CWD to doughDir++    putIOwords ["\n dainoProcess"+        , "currDir is doughP", showT currDir+        ]+    when (inform debug) $ putIOwords ["\ndainoProcess starts baking with"+        , "siteLayout" , showT (siteLayout sett4) +        ]+    setCurrentDir doughP++    if watchFlag flags -- implies server+        then mainWatch debug sett4 flags +        else do+            when (testNewFlag flags) $ do+                let bakedP = bakedDir (siteLayout sett4)+                deleteDirRecursive bakedP +            shakeAll debug sett4 flags ""+            -- the last is the filename that caused the shake call+            when (serverFlag flags) $ do +                runScotty (localhostPort sett4) +                    (bakedDir (siteLayout sett4)) +                    (makeRelFile "index.html") +                    -- was landingPageName+                putIOwords ["server started on "+                            , showT (localhostPort sett4)]++-- return the dir as set before+    setCurrentDir currDir+    when (inform debug) $ putIOwords ["dainoProcess", "again currDir as before", showT currDir, "\nwas doughP", showT doughP] +    when (inform debug) $ putIOwords ["dainoProcess done"]+    return ()++-- settingsFileName :: Path Rel File+-- -- ^ the yaml file in which the siteHeader are fixec+-- settingsFileName = makeRelFile "settings3" -- the yaml file+-- testNew bakes all test data, test alone continue the previous test++-- idea to automate upload (before call to shakeAll)+    -- read the time of the last upload+    -- uploadFileExist <- doesFileExist' testLastUploadFileName+    -- lastUpload <-+    --     if uploadFileExist+    --         then do+    --             lastUpload1 <- readFile2 testLastUploadFileName+    --             let lastUpload = read lastUpload1 :: UTCTime+    --             return lastUpload+    --         else return year2000++    -- let testWithLastTime  = testNewerModTime  lastUpload+    -- compare with year2000 if all should be uploaded+   -- let layout2 = siteLayout sett3 +    -- let port2 = localhostPort sett3 ++-- nach call to shake all +   -- sollte default index.html sein (landingPage layout2)+    -- when (uploadFlag flags) $ do+    --     (_,_) <- runStateT+    --         (ftpUploadDirsRecurse testWithLastTime (bakedDir layout2)+    --             (if testFlag flags then makeAbsDir "/daino.gerastree.at/"+    --                         else makeAbsDir "/frank.gerastree.at/")+    --         )+    --             ftp0+    --     currentTime <- getCurrentTimeUTC+    --     writeFile2 testLastUploadFileName (show currentTime)+
+ src/ShakeBake/Watch.hs view
@@ -0,0 +1,65 @@+----------------------------------------------------------------------+--+-- Module      :   watching files for changes+-- restart bake+-- include running server+----------------------------------------------------------------------+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++module ShakeBake.Watch where++-- import Lib.CmdLineArgs (PubFlags (..))+import Foundational.SettingsPage+import Foundational.CmdLineFlags++import ShakeBake.Shake2 (shakeAll)+import Uniform.Watch (+    Glob (..),+    WatchOpType,+    makeWatch, --  mainWatch2, forkIO, killThread)+    watchMain,+ )+import Uniform.WebServer (Port, runScotty)+import UniformBase++mainWatch :: NoticeLevel -> Settings -> PubFlags -> ErrIO ()++{- | the landing page must be given here because it is special for scotty+ and the name of the banner imgage which must be copied by shake+-}+mainWatch debug sett3 flags = do+    let layout = (siteLayout sett3)+    let port = (localhostPort sett3)++    let bakedPath = bakedDir layout+        doughPath = doughDir layout+    let watchDough2, watchThemes2 :: WatchOpType+        watchDough2 =+            makeWatch+                doughPath+                (shakeAll debug sett3 flags)+                [Glob "**/*.md", Glob "**/*.bib", Glob "**/*.yaml"]++        watchThemes2 =+            makeWatch+                doughPath+                (shakeAll debug sett3 flags)+                [ Glob "**/*.yaml"+                , Glob "**/*.dtpl"+                , Glob "**/*.css"+                , Glob "**/*.jpg"+                , Glob "**/*.JPG"+                ]++    watchMain+        [watchDough2, watchThemes2]+        ( runScotty+            port+            bakedPath+            (makeRelFile "index.html")+        )
+ src/Wave/Docrep2panrep.hs view
@@ -0,0 +1,105 @@+---------------------------------------------------------------------+--+-- Module      :  Uniform.Doc2html+--  converts an md document in 2steps +--      docrep -> panrep+        --     includes preparing of index pages +        --     the processsing of the refs are already done in doc processing +        -- panrep -> html +---------------------------------------------------------------------+{-# LANGUAGE ConstraintKinds #-}+-- {-# LANGUAGE DeriveAnyClass #-}+-- {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DoAndIfThenElse #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans+            -fno-warn-missing-signatures+            -fno-warn-missing-methods+            -fno-warn-duplicate-exports+            -fno-warn-unused-imports+            -fno-warn-unused-matches #-}++ +module Wave.Docrep2panrep (+    module Wave.Docrep2panrep,+) where++import Foundational.Filetypes4sites+    ( Docrep(Docrep), Panrep(Panrep, panyam) )+import Foundational.SettingsPage+ +import Foundational.CmdLineFlags ( PubFlags )++import Foundational.MetaPage++import GHC.Generics (Generic)++import Uniform.Json ( ToJSON(toJSON), Value, ErrIO )+import Uniform.Pandoc ( writeHtml5String2 )+import Uniform.Latex+import Uniform.Http --- out ( HTMLout )+import UniformBase++import Data.Maybe (fromMaybe)++import Lib.IndexMake ( convertIndexEntries, MenuEntry )+import Lib.IndexCollect ( completeIndex )+import Lib.Templating ( putValinMaster )++------------------------------------------------docrep -> panrep++-- | transform a docrep to a panrep (which is the pandoc rep)+--  completes the index (if indexpage else nothing done)++--  the refs are processed before in md2docrep++docrep2panrep :: NoticeLevel -> PubFlags -> Settings -> Docrep -> ErrIO (Panrep, [FilePath])+docrep2panrep debug pubf sett4 (Docrep y1 p1) = do+    when (inform debug) $+        putIOwords ["\n\ty1,p1-------------------------docrep2panrep"+                , "\ny1: ", showT y1+                , "\np1: ", showT p1]+    -- let pr = Panrep+    --             { panyam = y1+    --             , panpan = p1+    --             }+    let layout = siteLayout sett4 +        hpname = blogAuthorToSuppress layout+        authorReduced = blankAuthorName hpname (dyAuthor y1)+        y2 = y1{dyAuthor = authorReduced}+    +        panrep2 = Panrep y2 p1++    when (inform debug) $ putIOwords ["docrep2panrep"+                , "hpname", showT hpname+                , "\nauthorReduced", authorReduced]++    if isIndexPage (makeAbsFile . dyFn . panyam $ panrep2 )+        then do+    -- if dyIndexPage . panyam $ pr+            let m1 = panyam panrep2+            let ix1 =dyIndexEntry  m1+            -- let bakedP = bakedDir layout+            let doughP = doughDir layout+            ix2 <- completeIndex debug pubf sett4 doughP (dyIndexSort . panyam $ panrep2) ix1+            -- todo put ix2 into pr+            let m2 = m1{dyIndexEntry = ix2}+            let ixs = dirEntries  ix2 ++ fileEntries ix2+            let needs :: [FilePath] = map ixfn ixs +            when (inform debug) $+                putIOwords ["\n\tm2------------------------docrep2panrep end if"+                , showT m2+                , "needs", showT needs]++            return (panrep2{panyam = m2}, needs)+        else+            return (panrep2, [])++
+ src/Wave/Md2doc.hs view
@@ -0,0 +1,168 @@+---------------------------------------------------------------------+--+-- Module      :  Wave.Md2doc+-- the conversion of markdown to docrep+------------------------------------------------------------------+{-# LANGUAGE ConstraintKinds       #-}+-- {-# LANGUAGE DeriveAnyClass #-}+-- {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DoAndIfThenElse       #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE FlexibleInstances     #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}+{-# OPTIONS_GHC -Wall #-}++module Wave.Md2doc (+    module Wave.Md2doc,+    -- MarkdownText (..),+) where++import UniformBase++import Foundational.SettingsPage  +import Foundational.MetaPage+  +import Foundational.Filetypes4sites ( Docrep(Docrep), meta1)+import Foundational.CmdLineFlags+    ( PubFlags(draftFlag, privateFlag) )+import Uniform.Pandoc+    (pandocProcessCites, markdownFileType, readMarkdown2 )+import Uniform.Latex+import Lib.FileHandling+import Lib.OneMDfile+import Foundational.MetaPage (MetaPage(dyDoNotReplace))+import Lib.FileHandling (readErlaubt)++readMarkdownFile2docrep  :: NoticeLevel -> Settings ->  Path Abs File ->  ErrIO Docrep +-- read a markdown file and convert to docrep+readMarkdownFile2docrep debug sett3 fnin = do+    when (inform debug) $ putIOwords +        ["readMarkdownFile2docrep fnin", showPretty fnin]+        -- place to find PandocParseError++    mdfile <- read8 fnin markdownFileType +    pd <- readMarkdown2 mdfile+    -- could perhaps "need" all ix as files?++    -- let doc1 = pandoc2docrep doughP fnin  pd+    let meta6 = pandoc2MetaPage sett3 fnin  pd +    -- gets value from pandoc reading of yaml header+    -- fills values which can be defaulted (if not present)+    let doc1 = Docrep meta6 pd ++    let langCode = latexLangConversion . dyLang . meta1 $ doc1+    let debugReplace = inform debug +    doc2 <- if langCode == "ngerman"  -- obtained e.g. from YAML header+        then  do +            erl1 <- readErlaubt (replaceErlaubtFile . siteLayout $ sett3)+            let addErl = dyDoNotReplace . meta1 $ doc1+                -- allow additions to the list in the YAML header+                -- addErl2 = fromJustNote "sdfwer" $ splitOn' addErl ","+                erl2 = addErl ++ erl1+            changed <- applyReplace debugReplace erl2   fnin +            if (changed && (not debugReplace)) +                then readMarkdownFile2docrep debug  sett3 fnin +                -- when debug true then changed files are not written +                else return doc1+        else return doc1+    return doc2++applyReplace :: Bool -> [Text] -> Path Abs File -> ErrIO Bool +-- apply the replace for german +-- if any change true; needs rereading +applyReplace debugReplace erl2 fnin = do +    when debugReplace $ putIOwords +        ["applyReplace fnin", showPretty fnin+        , "\t erlaubt:", showT erl2]+    +    -- let         fnerl = makeAbsFile "/home/frank/Workspace11/replaceUmlaut/nichtUmlaute.txt" :: Path Abs File+    -- cdir <- currentDir+    -- let fnerlabs =   fnerl :: Path Abs File+    -- erl2 <- readErlaubt fnerlabs+    res <- procMd1 debugReplace erl2 fnin+    when debugReplace $ putIOwords ["applyReplace done. Changed:", showT res ]++    return res ++    +++-- pandoc2docrep ::  Path Abs Dir ->  Path Abs File  -> Pandoc -> Docrep+-- {- | convert the pandoc text to DocrepJSON+--  reads the markdown file with pandoc and extracts the yaml metadat+--  the metadata are then converted to metaPage from the json pandoc+--  -- duplication possible for data in the pandoc metada (no used)+--  TODO may use json record parse, which I have already done+-- -}+-- -- pure +-- pandoc2docrep  doughP filename  pd = Docrep meta6  pd+--     where +--         meta6 = pandoc2MetaPage doughP filename  pd ++++--------------------------------+addRefs :: NoticeLevel -> Docrep -> ErrIO Docrep+{- ^ add the references to the pandoc block+ the biblio is in the yaml (otherwise nothing is done)+ the cls file must be in the yaml as well++-}+++-- Process a Pandoc document by adding citations formatted according to a CSL style. Add a bibliography (if one is called for) at the end of the document.++addRefs debug dr1@(Docrep y1 p1) = do+    -- the biblio entry is the signal that refs need to be processed+    when (inform debug) $ putIOwords ["addRefs", showT dr1, "\n"]+    case (dyBibliography y1) of+        Nothing -> (return dr1) +        Just _ ->  do++            when (inform debug) $ putIOwords +                ["addRefs2-1", showT $ dyFn y1+                    -- , "\npandoc", showT dr1, "\n"+                    , "\n\t biblio1" , showT $ dyBibliography y1+                    , "\n\t style1" , showT $ dyStyle y1+                    ]++            p2 <- pandocProcessCites  p1+        +            when (inform debug) $ putIOwords ["addRefs2-4", "p2\n", showT p2]++            return (Docrep y1 p2)++filterNeeds :: NoticeLevel -> PubFlags -> Settings -> Path Rel File -> ErrIO(Maybe (Path Rel File))+-- ^ for md check the flags++filterNeeds debug pubf sett4 fn =  do +    when (inform debug) $ +        putIOwords ["filterNeeds", "\nPubFlags", showT pubf ]+    let doughP = doughDir . siteLayout $ sett4+    d1 <- readMarkdownFile2docrep debug sett4  (doughP </> fn) +    when (inform debug) $ +        putIOwords ["filterNeeds2", "\nMeta", showT (meta1 d1) ]++    let t = includeBakeTest3docrep pubf (meta1 d1)+    return $ if t then Just fn else Nothing++++includeBakeTest3docrep :: PubFlags -> MetaPage -> Bool ++-- ^ decide whether this is to be included in the bake ++includeBakeTest3docrep pubf doc1 = +        (draftFlag pubf || vers1 ==   "publish") +        -- should be less than eq+            && (privateFlag pubf || vis1 ==  "public")+    where+        -- draftF = draftFlag pubf +        vers1 = dyVersion   doc1+        vis1 = dyVisibility  doc1+
+ src/Wave/Panrep2html.hs view
@@ -0,0 +1,143 @@+---------------------------------------------------------------------+--+-- Module      :  Uniform.Doc2html+--  converts an md document in 2steps +--      docrep -> panrep+        --     includes preparing of index pages +        --     the processsing of the refs are already done in doc processing +        -- panrep -> html +---------------------------------------------------------------------+{-# LANGUAGE ConstraintKinds #-}+-- {-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DoAndIfThenElse #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans+            -fno-warn-missing-signatures+            -fno-warn-missing-methods+            -fno-warn-duplicate-exports+            -fno-warn-unused-imports+            -fno-warn-unused-matches #-}++ +module Wave.Panrep2html (+    module Wave.Panrep2html,+) where++-- import Data.Default+import Foundational.Filetypes4sites ( Panrep(Panrep) )+import Foundational.SettingsPage+    -- ( Settings(siteLayout), SiteLayout(blogAuthorToSuppress) )+import Foundational.MetaPage+    -- ( convertLink2html,+    --   convertLink2pdf,+    --   IndexEntry,+    --   MetaPage(dyIndexEntry, dyIndexSort) )+import GHC.Generics (Generic)++import Uniform.Json ( ToJSON(toJSON), Value, ErrIO )+import Uniform.Pandoc ( writeHtml5String2 )+import Uniform.Latex +import qualified Text.Pandoc.Shared as P+import Uniform.Http ( HTMLout ) +import UniformBase++import Data.Maybe (fromMaybe)++import Lib.IndexMake ( convertIndexEntries, MenuEntry )+-- import Lib.IndexCollect ( completeIndex )+import Lib.Templating ( putValinMaster )+import Text.Pandoc.SideNote ( usingSideNotes )+++-- ------------------------------------ panrep2html+-- panrep2html :: Panrep -> ErrIO HTMLout+-- implements the bake+-- siteHeader (sett3, above sett3) is the content of the settingsN.yml file+-- added here the transformations to tufte sidenotes (from pandoc-sidenotes)+panrep2html :: NoticeLevel -> Settings -> Panrep -> ErrIO HTMLout+panrep2html debug  sett3 (Panrep m1 p1) = do+    let mf = masterTemplateFile $ siteLayout sett3+    -- let mfn = templatesDir layout </> mf+    let masterfn = templatesDir (siteLayout sett3) </> mf+    let h = dyHeaderShift m1+    when (inform debug) $+        putIOwords ["\n\t---------------------------panrep2html"+                , "shiftHeaderLevel"+                , showT h]    +    let p2 = P.headerShift h p1+    let p3 = usingSideNotes p2  -- :: Pandoc -> Pandoc+    vals <- panrep2vals  debug sett3 (Panrep m1 p3)+    p :: HTMLout <- panrep2html2 debug masterfn vals+    return p++panrep2vals ::  NoticeLevel -> Settings -> Panrep -> ErrIO [Value]+panrep2vals debug sett3 (Panrep m1 p1) = do+    let ixe1 = dyIndexEntry m1+    let indexSortField = Data.Maybe.fromMaybe "" (dyIndexSort m1)++    when (inform debug) $+        putIOwords ["\n\t---------------------------panrep2vals"+                , "AuthorOppressed"+                , showT (blogAuthorToSuppress . siteLayout $ sett3)]++    menu4 :: MenuEntry <- convertIndexEntries  debug (blogAuthorToSuppress.siteLayout $ sett3) indexSortField ixe1+    html <- writeHtml5String2 p1+    -- in uniform.Pandoc (dort noch mehr moeglicherweise duplicated)+    p2 <-  fillContent ixe1 html++    when (inform debug) $ putIOwords ["panrep2vals", "m1", showPretty m1]+    when (inform debug) $ putIOwords ["panrep2vals", "sett3", showPretty sett3]+    when (inform debug) $ putIOwords ["panrep2vals", "menu4", showPretty menu4]+    when (inform debug) $ putIOwords ["panrep2vals", "p2", showPretty p2]++    let vals = [toJSON sett3, toJSON m1, toJSON menu4, toJSON p2]+    -- m1 is what is from the yaml meta from the file+    -- menu4 is menu collected +    -- order matters left preference?++    when (inform debug) $ putIOwords ["panrep2vals", "vals", showPretty vals]+    return vals++panrep2html2 :: NoticeLevel -- ^ +  -> Path Abs File -- ^ +  -> [Value] -- ^ +  -> ErrIO HTMLout+panrep2html2 debug masterfn vals = do+    p :: HTMLout <- putValinMaster debug vals masterfn+    when (inform debug) $ putIOwords ["\n panrep2html done"]+    return p++fillContent :: IndexEntry -> Text -> ErrIO ContentHtml+fillContent ix cont = do +        today1 :: UTCTime <- getCurrentTimeUTC+        let res = ContentHtml+                { content3 = cont +                , today3 = showT today1+                , linkpdf3 = convertLink2pdf ix   +                , filename3 = convertLink2html ix+                }+        return res++data ContentHtml = ContentHtml  +        { content3 :: Text+        , today3 :: Text +        , linkpdf3 :: Text +        , filename3 :: Text +        } deriving (Show, Generic)+-- | the record which contains the blog text in html format +-- the ref to the pdf File +-- todays date +-- filename3 the original file name +-- mit id,h1, h2,.. span und p tags ++instance ToJSON ContentHtml+instance Zeros ContentHtml where+  zero = ContentHtml zero zero zero zero
+ src/Wave/Panrep2pdf.hs view
@@ -0,0 +1,194 @@+---------------------------------------------------------------------+--+-- Module      :  Uniform.Panrep2pdf+---------------------------------------------------------------------+{-# LANGUAGE ConstraintKinds #-}+-- {-# LANGUAGE DeriveAnyClass #-}+-- {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DoAndIfThenElse #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -Wall -fno-warn-orphans+            -fno-warn-missing-signatures+            -fno-warn-missing-methods+            -fno-warn-duplicate-exports+            -fno-warn-unused-imports+            -fno-warn-unused-matches #-}++{- |  ready for processing to HTML or to TexSnip -> Tex -> Pdf+-}+{-# OPTIONS_GHC -Wno-deferred-type-errors #-}+module Wave.Panrep2pdf (+    module Wave.Panrep2pdf,+) where++import Foundational.Filetypes4sites+import Foundational.MetaPage+import GHC.Generics (Generic)+import Uniform.Pandoc ( writeTexSnip2 )+import UniformBase++import Uniform.Latex+import Uniform.WritePDF+import Paths_daino (version)++-- ------------------------------------ panrep2texsnip++panrep2texsnip :: NoticeLevel -> Panrep -> ErrIO TexSnip+panrep2texsnip debug (Panrep y p) = do+    when (inform debug) $ putIOwords ["\n panrep2texsnip start"]+    res1 <- writeTexSnip2 p+    when (inform debug) $ putIOwords ["\n panrep2texsnip res1", showT res1]+    let res = (TexSnip y res1)+    when (inform debug) $ putIOwords ["\n panrep2texsnip done"]+    return res+++text2absFile :: Path Abs Dir -> Text -> Path Abs File +text2absFile doughP t = doughP </> makeRelFile (t2s t)++texsnip2tex :: NoticeLevel ->  Path Abs Dir -> Path Abs Dir -> TexSnip ->  Path Abs File -> ErrIO Latex+-- the (lead) snip which comes from the md which gives the name to the resulting tex and pdf +-- and ist metadata are included (taken from the snip)+-- it may include other filenames, the snips of these+-- are then included in the pdf built. ++-- currently only one snip, +-- currently the biblio and references seem not to work with the new citeproc stuff (which takes the info from the )+texsnip2tex  debug doughP bakedP snip1 latexDtpl = do+    when (inform debug) $ putIOwords ["\n texsnip2tex start"]+    let yam = snipyam snip1 +    when (inform debug) $ putIOwords ["\n texsnip2tex for link", showT (dyFn yam)]+    let latexparam = LatexParam +            { latTitle = dyTitle yam +            , latAuthor = dyAuthor yam+            , latAbstract = dyAbstract yam+            , latLanguage = latexLangConversion $ dyLang yam +            , latFn = s2t $ dyFn yam+            , latBakedDir = s2t . toFilePath $ doughP +            , latDainoVersion = showT version+            , latBibliography = (s2t . toFilePath $ doughP) <> (maybe "resources/BibTexLatex.bib" id (dyBibliography yam))+                -- fix an absolute path for the bib files +                -- will be dificult if not in the resources?+            -- make this an abs file name +            , latBiblioTitle = "References"+            -- todo depends on latLanguage+            , latStyle    = dyStyleBiber (snipyam  snip1)+                --  maybe "authoryear" id $ dyStyleBiber yam+            , latReferences = maybe "" (shownice ) $ dyReferences yam+            , latBook = dyBook yam+            , latIndex = zero -- the collected index +            , latContent = unTexSnip snip1 -- the content of this file+            -- , latTheme = dy +            -- , latSnips = zero +        }+ ++    let webroot = doughP  -- use the images befor they are copied+        -- snip1 = unTexSnip p +    when (inform debug) $ putIOwords ["\n texsnip2tex dyIndexEntry"+        , showT (dyIndexEntry yam)]+    when (inform debug) $ putIOwords ["\n texsnip2tex latexparam"+        , showT latexparam]+    -- snips :: [Text] <- if "book" == dyBook yam +    --     then  collectSnips4index debug bakedP (dyIndexEntry yam)+    --     else return []+    -- let snips2 = concat' [snip1 , concat' snips ]+    -- -- let snips2 =  concat' .  map unTexSnip $ [p] :: Text+    -- res2 <- tex2latex debug webroot latexparam snips2+    latexparam4 <- if "book" == dyBook yam +        then do +            let latexparam2 = latexparam{latIndex=dyIndexEntry yam}+            latexparam3 <- completeIndexWithContent debug bakedP latexparam2+            return latexparam3+        else return latexparam+     ++    res2 <- tex2latex debug webroot latexparam4 latexDtpl +    when (inform debug) $ putIOwords ["texsnip2tex unprocessed texsnip ", showT res2]+   +    -- tex file must be full, ordinary latex content++    when (inform debug) $ putIOwords ["\n texsnip2tex done"]+    return . Latex $ res2++completeIndexWithContent :: NoticeLevel -> Path Abs Dir -> LatexParam -> ErrIO LatexParam+completeIndexWithContent debug bakedP latexparam2 = do +    let +        latix2 = latIndex latexparam2 +        fileixs = fileEntries latix2 +    fileixs2 <- mapM (completeOneIx debug bakedP)  fileixs+    +    let latix3 = latix2{fileEntries = fileixs2}+    return $ latexparam2{latIndex = latix3}++-- collectSnips4index :: NoticeLevel -> Path Abs Dir -> IndexEntry -> ErrIO [Text]+-- -- collect the TexSnip for the index  +-- -- uses the link which is a web page relative to web root +-- -- get title and abstract and add to snip +-- collectSnips4index debug bakedP ix = do +--     when (informAll debug) $ putIOwords ["\n collectSnips4index start"+--                 , "for ix", showT (ixfn ix)+--                 ]+--     texsnips :: [Text] <-  (completeOneSnip debug bakedP) (fileEntries ix)+--     return texsnips++--     -- let fns = map (link)(fileEntries ix) :: [FilePath] +--     --         -- what to do with the dirEntries? +--     --     fnsFP = map makeRelFile fns :: [Path Rel File]+--     --     fnsP = map (\fn -> bakedP </> fn) fnsFP :: [Path Abs File]+--     -- -- texsnips :: [TexSnip] <- mapM (\fn -> read8 fn texSnipFileType) fnsP +--     -- let snips = map unTexSnip texsnips +--     -- let res = snips +--     -- when (informAll debug) $ putIOwords ["\n collectSnips4index end"+--     --             , "for res", showT res]+--     -- return res++completeOneIx :: NoticeLevel -> Path Abs Dir -> IndexEntry -> ErrIO IndexEntry+    -- get the snip for one index entry +    -- only the content (abstract and title collected before) +completeOneIx debug bakedP ix = do +    when (inform debug) $ putIOwords ["\n completeOneIx start", showT ix]+    let+        -- tit = title ix+        -- titsnip = "\\part{"<> title ix <> "}"+        -- abssnip = "\\begin{abstract}" <> abstract ix <> "\\end{abstract}"+        ln = makeRelFile . link $ ix +        lnfp = bakedP </> ln :: Path Abs File ++    texsnip1 :: TexSnip <-   read8 lnfp texSnipFileType +    -- let res = unlines' [zero, titsnip, "", abssnip, "", unTexSnip texsnip1]+    let ix2 = ix{content =  unTexSnip texsnip1}+    when (inform debug) $ putIOwords ["\n completeOneIx end", showT ix2]+    return ix2+++-- ------------------------------------ tex2pdf+++-- refdir must be set to the dir where searches for +-- biblio etc start - seems not correct+-- the refdir is where the intermediate files are put+-- this is fnres - just the doughPath+tex2pdf :: NoticeLevel -> Path Abs File ->  Path Abs File ->  Path Abs Dir ->  ErrIO ()+tex2pdf debug fn fnres doughP  =  do+    when (inform debug) $ putIOwords ["\n tex2pdf start for", showT fn]+    let refDir = -- makeAbsDir "/home/frank/bakedTestSite"+                    -- dough does not work either+                    -- must be local dir of file to process+            makeAbsDir . getParentDir . toFilePath $ fn :: Path Abs Dir+    -- refDir must be the place where biblio is place (or searched from - best ) - i.e. the root for dough +    when (inform debug) $ putIOwords ["\n tex2pdf refDir", showT refDir]+    texf <- read8 fn texFileType+    when (inform debug) $ putIOwords ["\n tex2pdf texf content", showT texf]+    writePDF2 debug  fn fnres refDir+    -- for debug put only the file unprocessed+    -- write8 fnres pdfFileType (PDFfile . unLatex $ texf)+    when (inform debug) $ putIOwords ["\n tex2pdf done"]+    return ()