"Fossies" - the Fresh Open Source Software Archive

Member "pp-2.14.3/src/Environment.hs" (24 Nov 2021, 7213 Bytes) of package /linux/privat/pp-2.14.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Haskell source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "Environment.hs": 2.14.2_vs_2.14.3.

    1 {- PP
    2 
    3 Copyright (C) 2015-2021 Christophe Delord
    4 
    5 http://cdelord.fr/pp
    6 
    7 This file is part of PP.
    8 
    9 PP is free software: you can redistribute it and/or modify
   10 it under the terms of the GNU General Public License as published by
   11 the Free Software Foundation, either version 3 of the License, or
   12 (at your option) any later version.
   13 
   14 PP is distributed in the hope that it will be useful,
   15 but WITHOUT ANY WARRANTY; without even the implied warranty of
   16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17 GNU General Public License for more details.
   18 
   19 You should have received a copy of the GNU General Public License
   20 along with PP.  If not, see <http://www.gnu.org/licenses/>.
   21 -}
   22 
   23 module Environment ( Env(..)
   24                    , Var(..)
   25                    , Val(..)
   26                    , Macro(..)
   27                    , fromVal
   28                    , getSymbol
   29                    , clean
   30                    , lookupMacro
   31                    , call
   32                    , initialEnvironment
   33                    , addDep
   34                    , addDeps
   35                    -- exported for test purpose
   36                    , defaultMacroChars
   37                    , defaultOpenCloseChars
   38                    , defaultBlockChars
   39                    , defaultLiterateMacroChars
   40                    )
   41 where
   42 
   43 import Data.Maybe
   44 import System.Environment
   45 
   46 import Formats
   47 import Localization
   48 import OSAbstraction
   49 
   50 -- defaultMacroChars is the list of characters used to execute a macro
   51 defaultMacroChars :: Chars
   52 defaultMacroChars = ['!']
   53 
   54 -- defaultOpenCloseChars is the list of characters that can delimit macro parameters.
   55 defaultOpenCloseChars :: [(Char, Char)]
   56 defaultOpenCloseChars = [('(', ')'), ('{', '}'), ('[', ']')]
   57 
   58 -- defaultBlockChars is the list of characters that can delimit macro parameters with
   59 -- the Markdown code block syntax.
   60 defaultBlockChars :: Chars
   61 defaultBlockChars = ['~', '`']
   62 
   63 -- literate programming macros
   64 defaultLiterateMacroChars :: Chars
   65 defaultLiterateMacroChars = ['@']
   66 
   67 -- symbol type of a definition in the environment
   68 data Var = Def String           -- user macro definition
   69          | EnvVar String        -- environment variable
   70          deriving (Eq)
   71 
   72 -- values stored in the environment
   73 data Val = Val String           -- regular (stripped) value
   74          | Block String         -- code block (unstripped) value
   75          deriving (Eq, Show)
   76 
   77 type Chars = String
   78 
   79 -- pp environment (macros, parameters, ...)
   80 data Env = Env { vars :: [(Var, Val)]               -- lookup table of global variables and user macros
   81                , docstrings :: [(Var, String)]      -- docstrings of user macros
   82                , arguments :: [(String, Val)]       -- local arguments of a user defined macro
   83                , currentLang :: Lang                -- current language
   84                , fileFormat :: Maybe Format         -- current file format
   85                , currentDialect :: Dialect          -- current dialect
   86                , mainFile :: Maybe FilePath         -- main file name (given on the command line)
   87                , currentFile :: Maybe FilePath      -- current file name (can be included in other files)
   88                , makeTarget :: Maybe FilePath       -- target name for the dependency file (-M)
   89                , dependencies :: [FilePath]         -- list of dependencies
   90                , litFiles :: [(FilePath, String)]   -- literate file name
   91                , litMacros :: [(String, String)]    -- literate macro name
   92                , litLangs :: [(String, String)]     -- language of a literate file or macro
   93                , imagePath :: String                -- prefix added to the image path (diagrams)
   94                , codeBlock :: Maybe String          -- format of code blocks generated by source
   95                , macroChars :: Chars                -- chars that execute macros
   96                , openCloseChars :: [(Char, Char)]   -- parameter delimiters
   97                , blockChars :: Chars                -- block delimiter chars
   98                , literateMacroChars :: Chars        -- literate programming macro delimiters
   99                , ignoreStdin :: Bool                -- some command line arguments disable stdin
  100                , customPlantuml :: Maybe FilePath   -- external PlantUML jar file to use
  101                , customDitaa :: Maybe FilePath      -- external ditaa jar file to use
  102                }
  103 
  104 fromVal :: Val -> String
  105 fromVal (Val s) = s
  106 fromVal (Block s) = s
  107 
  108 -- `clean name env` removes an outdated variable from the environment
  109 clean :: Eq a => a -> [(a, b)] -> [(a, b)]
  110 clean var = filter ((/=var) . fst)
  111 
  112 -- Get a variable in the environment
  113 getSymbol :: Env -> Var -> Val
  114 getSymbol Env{vars=vs} var = fromMaybe (Val "") (lookup var vs)
  115 
  116 -- A macro takes an environment and arguments
  117 -- and returns a new environment and the result of the macro as a string.
  118 -- It also as some additional metadata (docstring)
  119 type MacroFunc = Env -> [Val] -> IO (Env, String)
  120 data Macro = Macro String [String]  -- name and aliases
  121                    String           -- docstring
  122                    MacroFunc        -- implementation
  123 
  124 -- Lookup a macro in a macro list
  125 lookupMacro :: String -> [Macro] -> Maybe Macro
  126 lookupMacro name (macro@(Macro name' aliases' _ _) : macros)
  127     | name `elem` (name':aliases') = Just macro
  128     | otherwise = lookupMacro name macros
  129 lookupMacro _ [] = Nothing
  130 
  131 -- Call a macro
  132 call :: Macro -> Env -> [Val] -> IO (Env, String)
  133 call macro = let Macro _ _ _ macroImpl = macro in macroImpl
  134 
  135 -- Build the initial environment
  136 initialEnvironment :: Lang -> Dialect -> IO Env
  137 initialEnvironment defaultLang defaultDialect = do
  138     -- get $LANG (en, fr, ...)
  139     envVars <- getEnvironment
  140     let lang = fromMaybe defaultLang $ readCapMaybe $ take 2 <$> lookup "LANG" envVars
  141     -- get $FORMAT (html, pdf, ...)
  142     let fmt = readCapMaybe $ lookup "FORMAT" envVars
  143     -- get $DIALECT (md, rst, ...)
  144     let dial = fromMaybe defaultDialect $ readCapMaybe $ lookup "DIALECT" envVars
  145     -- the initial environment contains the language, the format and the environment variables
  146     return Env { vars = [(EnvVar (envVarStorage name), Val val) | (name, val) <- envVars]
  147                , docstrings = []
  148                , arguments = []
  149                , currentLang = lang
  150                , fileFormat = fmt
  151                , currentDialect = dial
  152                , mainFile = Nothing
  153                , currentFile = Nothing
  154                , makeTarget = Nothing
  155                , dependencies = []
  156                , litFiles = []
  157                , litMacros = []
  158                , litLangs = []
  159                , imagePath = ""
  160                , codeBlock = Nothing
  161                , macroChars = defaultMacroChars
  162                , openCloseChars = defaultOpenCloseChars
  163                , blockChars = defaultBlockChars
  164                , literateMacroChars = defaultLiterateMacroChars
  165                , ignoreStdin = False
  166                , customPlantuml = Nothing
  167                , customDitaa = Nothing
  168                }
  169 
  170 -- track dependencies
  171 -- see issue 30, thanks to trygvis for the idea
  172 addDep :: Env -> FilePath -> Env
  173 addDep env@Env{dependencies=deps} name = env{dependencies=name:deps}
  174 
  175 addDeps :: Env -> [FilePath] -> Env
  176 addDeps = foldl addDep