packages feed

yst 0.1 → 0.2

raw patch · 6 files changed

+60/−50 lines, 6 files

Files

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