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 +24/−0
- README.md +32/−0
- app/daino.hs +64/−0
- changelog.md +60/−0
- daino.cabal +111/−0
- src/Foundational/CmdLineFlags.hs +63/−0
- src/Foundational/Filetypes4sites.hs +182/−0
- src/Foundational/MetaPage.hs +293/−0
- src/Foundational/SettingsPage.hs +153/−0
- src/Lib/CheckProcess.hs +120/−0
- src/Lib/IndexCollect.hs +154/−0
- src/Lib/IndexMake.hs +176/−0
- src/Lib/Templating.hs +73/−0
- src/ShakeBake/Bake.hs +195/−0
- src/ShakeBake/CmdLineArgs.hs +139/−0
- src/ShakeBake/ConvertFiles.hs +140/−0
- src/ShakeBake/ReadSettingFile.hs +36/−0
- src/ShakeBake/Shake2.hs +412/−0
- src/ShakeBake/StartDainoProcess.hs +186/−0
- src/ShakeBake/Watch.hs +65/−0
- src/Wave/Docrep2panrep.hs +105/−0
- src/Wave/Md2doc.hs +168/−0
- src/Wave/Panrep2html.hs +143/−0
- src/Wave/Panrep2pdf.hs +194/−0
+ 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 ()