yst 0.1 → 0.2
raw patch · 6 files changed
+60/−50 lines, 6 files
Files
- README.markdown +33/−35
- Yst/Build.hs +4/−2
- Yst/Data.hs +14/−8
- Yst/Types.hs +5/−1
- demo/index.yaml +3/−3
- yst.cabal +1/−1
README.markdown view
@@ -51,7 +51,7 @@ template : index.st requires : event.st data :- recentevents : events.yaml ORDER BY date DESC LIMIT 2+ recentevents : FROM events.yaml ORDER BY date DESC LIMIT 2 This says: build the page `index.html` from the string template `index.st` (and subtemplate `event.st`) and data from `events.yaml`. Sort this data@@ -220,8 +220,8 @@ though it may): data:- events: events.yaml order by date desc group by title then location- people: people.csv order by birthday then lastname where+ events: from events.yaml order by date desc group by title then location+ people: from people.csv order by birthday then lastname where birthstate = 'CA' limit 5 First we have the name of the stringtemplate attribute to be populated@@ -235,20 +235,20 @@ `ORDER BY field [ASC|DESC] [THEN field [ASC|DESC]]*` > Sorts a list by comparing the value of `field`. `ASC`- (the default) means "ascending", and `DESC` means "descending".- The keyword `THEN` is used to separate fields that will be- compared in order. So, if we are ordering by `birthday then lastname`,- we will compare birthdays, and if these are equal, we will break- the tie by comparing last names. +(the default) means "ascending", and `DESC` means "descending".+The keyword `THEN` is used to separate fields that will be+compared in order. So, if we are ordering by `birthday then lastname`,+we will compare birthdays, and if these are equal, we will break+the tie by comparing last names. `GROUP BY field [THEN field]*` > Converts a list into a list of lists, where each sublist contains- only items with the same value for `field`. So, for example,- `group by date` takes a list of events and produces a list of- lists of items, where each sublist contains events occuring at- a single date. `GROUP BY date THEN venue` would produce a list- of lists of lists, and so on.+only items with the same value for `field`. So, for example,+`group by date` takes a list of events and produces a list of+lists of items, where each sublist contains events occuring at+a single date. `GROUP BY date THEN venue` would produce a list+of lists of lists, and so on. `LIMIT n` @@ -259,16 +259,24 @@ > Selects only items that meet a condition. > A *condition* in a `WHERE` statement is a Boolean combination (using- `NOT`, `AND`, `OR`, and parentheses for disambiguation) of *basic- conditions*. A *basic condition* is of the form `value op value`,- where `value` may be either a fieldname or a constant. Note that- all constants must be enclosed in quotes. `op` may be one of the- following: `=`, `>=`, `<=`, `>`, `<`.+`NOT`, `AND`, `OR`, and parentheses for disambiguation) of *basic+conditions*. A *basic condition* is of the form `value op value`,+where `value` may be either a fieldname or a constant. Note that+all constants must be enclosed in quotes. `op` may be one of the+following: `=`, `>=`, `<=`, `>`, `<`. Note that the order of transformations is significant. You can get different results if you use `LIMIT` before or after `ORDER BY`, for example. +If you want to specify an attribute's value directly, rather than+reading it from a file, just omit the "FROM":++ date:+ deadline: 11/20/2009++Any YAML value can be given to an attribute in this way.+ ### Static files Any file or subdirectory in the `files` directory (or whatever is@@ -281,11 +289,11 @@ `yst` will recognize date fields in data files automatically, if the dates are in one of the following formats: - - the locale's standard date format- - MM/DD/YYYY (e.g. 04/28/1953)- - MM/DD/YY (e.g. 04/28/53)- - YYYY-MM-DD (e.g. 1953-04-28)- - DD MON YYYY (e.g. 28 Apr 1953)+ - the locale's standard date format+ - MM/DD/YYYY (e.g. 04/28/1953)+ - MM/DD/YY (e.g. 04/28/53)+ - YYYY-MM-DD (e.g. 1953-04-28)+ - DD MON YYYY (e.g. 28 Apr 1953) Dates may be formatted in templates using a stringtemplate "format" directive. There's an example in the demo file `date.st`:@@ -404,7 +412,7 @@ Just give it the extension `.csv`. In `index.yaml`, you'd have: data:- events: events.csv order by date desc+ events: from events.csv order by date desc This can be handy if you're using existing data, because spreadsheets and databases can easily be dumped to CSV. In the case of a SQL@@ -440,17 +448,7 @@ The solution is to set up your text editor so that it doesn't add the newline at the end of the file. Using [vim][], you can do this-with the commands `set binary` and `set noeol`. To make this the-default for `.st` files, add this line to `augroup filetypedetect`-in `~\.vim\filetype.vim`:-- au! BufRead,BufNewFile *.st setfiletype stringtemplate--Then add a file `stringtemplate.st` in `~/.vim/ftplugin` with-the following contents:-- set binary- set noeol+with the commands `set binary` and `set noeol`. ### Layout templates
Yst/Build.hs view
@@ -22,7 +22,7 @@ import Yst.Util import Yst.Render import qualified Data.Map as M-import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe, mapMaybe) import Data.List import System.FilePath import System.Directory@@ -44,7 +44,9 @@ case sourceFile page of TemplateFile f -> stripStExt f <.> "st" SourceFile f -> f- dataFiles = map (\(_,(f,_)) -> dataDir site </> f) $ pageData page+ fileFromSpec (DataFromFile f _) = Just f+ fileFromSpec _ = Nothing+ dataFiles = map (dataDir site </>) $ mapMaybe (\(_,s) -> fileFromSpec s) $ pageData page in indexFile site : layout : srcdir : (requires ++ dataFiles) buildSite :: Site -> IO ()
Yst/Data.hs view
@@ -26,15 +26,16 @@ import Control.Monad import Data.Char import Data.Maybe (fromMaybe)-import Data.List (sortBy, nub)+import Data.List (sortBy, nub, isPrefixOf) import Text.ParserCombinators.Parsec import System.FilePath (takeExtension) -getData :: (FilePath, [DataOption]) -> IO Node-getData (file, opts) = do+getData :: DataSpec -> IO Node+getData (DataFromFile file opts) = do raw <- catch (readDataFile file) (\e -> errorExit 15 ("Error reading data from " ++ file ++ ": " ++ show e) >> return undefined) return $ foldl applyDataOption raw opts+getData (DataConstant n) = return n readDataFile :: FilePath -> IO Node readDataFile f =@@ -97,14 +98,19 @@ reverseIfDescending Descending LT = GT reverseIfDescending Descending GT = LT -parseDataField :: Node -> (FilePath, [DataOption])-parseDataField (NString s) = case parse pDataField s s of- Right res -> res- Left err -> error $ show err-parseDataField x = error $ "Expected string node, got " ++ show x+parseDataField :: Node -> DataSpec+parseDataField n@(NString s) = case parse pDataField s s of+ Right (f,opts) -> DataFromFile f opts+ Left err -> if "from" `isPrefixOf` (dropWhile isSpace $ map toLower s)+ then error $ "Error parsing data field: " ++ show err+ else DataConstant n +parseDataField n = DataConstant n pDataField :: GenParser Char st ([Char], [DataOption]) pDataField = do+ spaces+ pString "from"+ pSpace fname <- pIdentifier <?> "name of YAML or CSV file" opts <- many $ (pOptWhere <?> "where [CONDITION]") <|> (pOptLimit <?> "limit [NUMBER]")
Yst/Types.hs view
@@ -42,7 +42,7 @@ deriving (Show, Read, Eq) data Page = Page {- pageData :: [(String, (FilePath, [DataOption]))]+ pageData :: [(String, DataSpec)] , layoutFile :: Maybe FilePath , sourceFile :: Source , requiresFiles :: [FilePath]@@ -73,6 +73,10 @@ compare (NString _) _ = GT compare (NDate _) _ = GT compare _ _ = GT++data DataSpec = DataConstant Node+ | DataFromFile FilePath [DataOption]+ deriving (Show, Read, Eq) data DataOption = OrderBy [(String, SortDirection)] | GroupBy [String]
demo/index.yaml view
@@ -3,21 +3,21 @@ template : index.st requires : event.st data :- recentevents : events.yaml ORDER BY date DESC LIMIT 2+ recentevents : FROM events.yaml ORDER BY date DESC LIMIT 2 - url : events.html title : Events template : events.st requires : [event.st, eventgroup.st, date.st] data :- eventsbydate : events.yaml ORDER BY date DESC GROUP BY date+ eventsbydate : FROM events.yaml ORDER BY date DESC GROUP BY date - url : april_events.tex title : April Events template : april_events.st requires : event.st data :- april : events.yaml WHERE date >= '2009-04-01' AND date < '2009-05-01' ORDER BY date+ april : FROM events.yaml WHERE date >= '2009-04-01' AND date < '2009-05-01' ORDER BY date layout : layout.tex.st inmenu : no
yst.cabal view
@@ -1,5 +1,5 @@ name: yst-version: 0.1+version: 0.2 Cabal-version: >= 1.2 build-type: Simple synopsis: Builds a static website from templates and data in YAML or