Add References, --trace and other stuffs.
authorJulien Moutinho <julm+hdoc@autogeree.net>
Sun, 24 Dec 2017 00:15:23 +0000 (01:15 +0100)
committerJulien Moutinho <julm+hdoc@autogeree.net>
Sun, 24 Dec 2017 00:15:23 +0000 (01:15 +0100)
14 files changed:
Data/TreeSeq/Strict.hs
Language/DTC/Anchor.hs
Language/DTC/Document.hs
Language/DTC/Sym.hs
Language/DTC/Write/HTML5.hs
Language/DTC/Write/XML.hs
Language/TCT/Read.hs
Language/TCT/Read/Token.hs
Language/TCT/Write/XML.hs
Language/XML.hs
Text/Blaze/DTC.hs
Text/Blaze/Utils.hs
exe/cli/Main.hs
hdoc.cabal

index 6a899b60d20b906dd1a3c9a26f2d11f9cd0babad..37daefc9bb1bf44fd4f303fda9da0c331a108ef8 100644 (file)
@@ -57,14 +57,14 @@ unTree :: Tree a a -> a
 unTree (TreeN k _) = k
 unTree (Tree0 a)   = a
 
-mapWithKey :: (Maybe k -> a -> b) -> Tree k a -> Tree k b
-mapWithKey = go Nothing
+mapWithNode :: (Maybe k -> a -> b) -> Tree k a -> Tree k b
+mapWithNode = go Nothing
        where
        go _k f (TreeN k ts) = TreeN k (go (Just k) f <$> ts)
        go k  f (Tree0 a)    = Tree0 (f k a)
 
-mapAlsoKey :: (k -> l) -> (Maybe k -> a -> b) -> Tree k a -> Tree l b
-mapAlsoKey fk fv = go Nothing
+mapAlsoNode :: (k -> l) -> (Maybe k -> a -> b) -> Tree k a -> Tree l b
+mapAlsoNode fk fv = go Nothing
        where
        go _k (TreeN k ts) = TreeN (fk k) $ go (Just k) <$> ts
        go k  (Tree0 a)    = Tree0 (fv k a)
index 62c5bf077836d86fd54e66a2f1b28b6695de62de..b6ba4dd2f34a7e42506780019109b6e62c70e891 100644 (file)
@@ -3,7 +3,6 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
--- | Compute an Index for a DTC.
 module Language.DTC.Anchor where
 
 import Control.Applicative (Applicative(..))
@@ -32,6 +31,7 @@ import qualified Data.Sequence as Seq
 import qualified Data.Strict.Maybe as Strict
 import qualified Data.Text as Text
 import qualified Data.TreeMap.Strict as TreeMap
+-- import qualified Data.TreeSeq.Strict as Tree
 
 import Language.DTC.Document
 
@@ -57,15 +57,20 @@ irefsOfTerms = TreeMap.fromList const . (>>= f) . concat
        f [] = []
        f ws = maybe [] (\p -> [(p,[])]) $ pathFromWords ws
 
+-- ** Type 'Rrefs'
+type Rrefs = Map Ident [Anchor]
+
 -- * Type 'State'
 data State
  =   State
  {   state_irefs   :: Irefs
+ ,   state_rrefs   :: Rrefs
  ,   state_section :: Pos
  }
 state :: State
 state = State
  { state_irefs   = mempty
+ , state_rrefs   = mempty
  , state_section = def
  }
 
@@ -87,11 +92,7 @@ instance Anchorify (Tree BodyKey BodyValue) where
                        S.put after{state_section}
                        return t
 instance Anchorify Body where
-       anchorify b = do
-               State{..} <- S.get
-               case () of
-                () | null state_irefs -> return b
-                _ -> mapM anchorify b
+       anchorify = mapM anchorify
 instance Anchorify BodyKey where
        anchorify = \case
         Section{..} ->
@@ -107,6 +108,9 @@ instance Anchorify BodyValue where
                Figure pos attrs type_
                 <$> anchorify title
                 <*> anchorify blocks
+        References{..} ->
+               References pos attrs
+                <$> anchorify refs
         Block v ->
                Block <$> anchorify v
 instance Anchorify [Reference] where
@@ -122,17 +126,40 @@ instance Anchorify Block where
         Para{..}    -> Para    pos attrs <$> anchorify para
         OL{..}      -> OL      pos attrs <$> anchorify items
         UL{..}      -> UL      pos attrs <$> anchorify items
-        RL{..}      -> RL      pos attrs <$> anchorify refs
         Artwork{..} -> Artwork pos attrs <$> anchorify art
         d@Comment{} -> pure d
 instance Anchorify Para where
        anchorify ls = do
-               join <$> traverse indexifyLines ls
+               State{..} <- S.get
+               indexed <-
+                       if null state_irefs
+                       then return ls
+                       else join <$> traverse indexifyLines ls
+               traverse referencifyLines indexed
 instance Anchorify Reference where
        anchorify = return
 instance Anchorify Artwork where
        anchorify = return
 
+referencifyLines :: Lines -> S.State State Lines
+referencifyLines t =
+       case t of
+        Tree0{} -> return t
+        TreeN k ts -> do
+               k' <-
+                       case k of
+                        Rref{..} -> do
+                               State{..} <- S.get
+                               let anchs = Map.findWithDefault [] to state_rrefs
+                               let count = case anchs of [] -> def; Anchor{count=c}:_ -> succNat1 c
+                               let anch = Anchor{count, section=state_section}
+                               S.modify $ \s -> s{state_rrefs=
+                                       Map.insert to (anch:anchs) state_rrefs}
+                               return Rref{anchor=Just anch, to}
+                        _ -> return k
+               TreeN k'
+                <$> traverse referencifyLines ts
+
 indexifyLines :: Lines -> S.State State Para
 indexifyLines = \case
  Tree0 a -> indexifyPlain a
@@ -143,11 +170,11 @@ indexifyLines = \case
         Strict.Nothing ->
                Seq.singleton . TreeN k . join
                 <$> traverse indexifyLines ts
-        Strict.Just irefs -> do
-               let count = case irefs of [] -> def; Anchor{count=c}:_ -> succNat1 c
+        Strict.Just anchs -> do
+               let count = case anchs of [] -> def; Anchor{count=c}:_ -> succNat1 c
                let anch = Anchor{count, section=state_section}
                S.modify $ \s -> s{state_irefs=
-                       TreeMap.insert const words (anch:irefs) state_irefs}
+                       TreeMap.insert const words (anch:anchs) state_irefs}
                Seq.singleton . TreeN Iref{term, anchor=Just anch} . join
                 <$> traverse indexifyLines ts
  TreeN k ts ->
@@ -199,13 +226,13 @@ indexifyWords section = go mempty
                                        (<$> goWords node_descendants prev' next) $ \(anch, ls, ns, rs) ->
                                                (anch, ls, ns, TreeMap $
                                                        Map.insert w nod{TreeMap.node_descendants = rs} irefsByWord)
-                                Strict.Just irefs ->
+                                Strict.Just anchs ->
                                        case goWords node_descendants prev' next of
                                         Nothing ->
-                                               let count = case irefs of [] -> def; Anchor{count=c}:_ -> succNat1 c in
+                                               let count = case anchs of [] -> def; Anchor{count=c}:_ -> succNat1 c in
                                                let anch  = Anchor{count, section} in
                                                Just (anch, prev', next, TreeMap $
-                                                       Map.insert w nod{TreeMap.node_value = Strict.Just $ anch:irefs} irefsByWord)
+                                                       Map.insert w nod{TreeMap.node_value = Strict.Just $ anch:anchs} irefsByWord)
                                         Just (anch, ls, ns, rs) ->
                                                Just (anch, ls, ns, TreeMap $
                                                        Map.insert w nod{TreeMap.node_descendants = rs} irefsByWord)
index b6a77a67df7299f989c1ec94d581c0b624140c66..bdee41a9704eb9c525d894534d6e1678a8a5efd2 100644 (file)
@@ -76,7 +76,7 @@ instance Default About where
 instance Semigroup About where
        x <> y = About
         { titles   = titles   x <> titles   y
-        , url      = url      x <> url      y
+        , url      = url (x::About) <> url (y::About)
         , authors  = authors  x <> authors  y
         , editor   = editor   x <> editor   y
         , date     = date     x <> date     y
@@ -101,24 +101,28 @@ data BodyKey
 
 -- ** Type 'BodyValue'
 data BodyValue
- = ToC     { pos   :: Pos
-           , attrs :: CommonAttrs
-           , depth :: Maybe Nat
-           }
- | ToF     { pos   :: Pos
-           , attrs :: CommonAttrs
-           , types :: [Text]
-           }
- | Figure  { pos    :: Pos
-           , attrs  :: CommonAttrs
-           , type_  :: Text
-           , title  :: Title
-           , blocks :: Blocks
-           }
- | Index   { pos   :: Pos
-           , attrs :: CommonAttrs
-           , terms :: Terms
-           }
+ = ToC        { pos   :: Pos
+              , attrs :: CommonAttrs
+              , depth :: Maybe Nat
+              }
+ | ToF        { pos   :: Pos
+              , attrs :: CommonAttrs
+              , types :: [Text]
+              }
+ | Figure     { pos    :: Pos
+              , attrs  :: CommonAttrs
+              , type_  :: Text
+              , title  :: Title
+              , blocks :: Blocks
+              }
+ | Index      { pos   :: Pos
+              , attrs :: CommonAttrs
+              , terms :: Terms
+              }
+ | References { pos   :: Pos
+              , attrs :: CommonAttrs
+              , refs  :: [Reference]
+              }
  | Block Block
  deriving (Eq,Show)
 
@@ -172,10 +176,6 @@ data Block
            , attrs :: CommonAttrs
            , items :: [Blocks]
            }
- | RL      { pos   :: Pos
-           , attrs :: CommonAttrs
-           , refs  :: [Reference]
-           }
  | Artwork { pos   :: Pos
            , attrs :: CommonAttrs
            , art   :: Artwork
@@ -190,12 +190,6 @@ data CommonAttrs
  ,   classes :: [Text]
  } deriving (Eq,Show)
 
--- * Type 'Auto'
-data Auto
- =   Auto
- {   auto_id :: Ident
- } deriving (Eq,Show)
-
 -- * Type 'Blocks'
 type Blocks = [Block]
 
@@ -225,7 +219,7 @@ data LineKey
  | Eref {href :: URL}
  | Iref {anchor :: Maybe Anchor, term :: Words}
  | Ref  {to :: Ident}
- | Rref {to :: Ident}
+ | Rref {anchor :: Maybe Anchor, to :: Ident}
  deriving (Eq,Show)
 
 -- ** Type 'Anchor'
@@ -245,10 +239,11 @@ data LineValue
 newtype Title = Title { unTitle :: Para }
  deriving (Eq,Show,Default)
 
--- ** Type 'Address'
-data Address
- =   Address
- {   street  :: Text
+-- ** Type 'Entity'
+data Entity
+ =   Entity
+ {   name    :: Text
+ ,   street  :: Text
  ,   zipcode :: Text
  ,   city    :: Text
  ,   region  :: Text
@@ -256,10 +251,12 @@ data Address
  ,   email   :: Text
  ,   tel     :: Text
  ,   fax     :: Text
+ ,   url     :: Maybe URL
  } deriving (Eq,Show)
-instance Default Address where
-       def = Address
-        { street  = def
+instance Default Entity where
+       def = Entity
+        { name    = def
+        , street  = def
         , zipcode = def
         , city    = def
         , region  = def
@@ -267,7 +264,10 @@ instance Default Address where
         , email   = def
         , tel     = def
         , fax     = def
+        , url     = def
         }
+instance Semigroup Entity where
+       _x <> y = y
 
 -- * Type 'Include'
 data Include
@@ -294,20 +294,6 @@ reference id =
 instance Default Reference where
        def = reference def
 
--- * Type 'Entity'
-data Entity
- =   Entity
- {   name    :: Text
- ,   address :: Address
- } deriving (Eq,Show)
-instance Default Entity where
-       def = Entity
-        { name    = def
-        , address = def
-        }
-instance Semigroup Entity where
-       _x <> y = y
-
 -- * Type 'Date'
 data Date
  =   Date
index 4039f0345408bd42e381e2b6374486235dccea8e..51d185d51d04475e4de0a781371020d6d9e04ed2 100644 (file)
@@ -38,7 +38,6 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
        editor      :: repr DTC.Entity
        date        :: repr DTC.Date
        entity      :: repr DTC.Entity
-       address     :: repr DTC.Address
        link        :: repr DTC.Link
        serie       :: repr DTC.Serie
        alias       :: repr DTC.Alias
@@ -49,6 +48,7 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
        tof         :: repr DTC.BodyValue
        index       :: repr DTC.BodyValue
        figure      :: repr DTC.BodyValue
+       references  :: repr DTC.BodyValue
        reference   :: repr DTC.Reference
        include     :: repr DTC.Include
        
@@ -100,6 +100,7 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                 , tof
                 , index
                 , figure
+                , references
                 , DTC.Block <$> block
                 ]
        title = rule "title" $ DTC.Title <$> element "title" para
@@ -139,11 +140,6 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                         <$> position
                         <*> commonAttrs
                         <*> many (element "li" $ many block)
-                , element "rl" $
-                       DTC.RL
-                        <$> position
-                        <*> commonAttrs
-                        <*> many reference
                 {-
                 , anyElem $ \n@XmlName{..} ->
                                case xmlNameSpace of
@@ -191,6 +187,12 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                 <*> attribute "type" text
                 <*> title
                 <*> many block
+       references =
+               element "references" $
+               DTC.References
+                <$> position
+                <*> commonAttrs
+                <*> many reference
        para = rule "para" $ (Seq.fromList <$>) $ many lines
        lines =
                choice
@@ -207,7 +209,7 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                 , element "eref" $ TreeN . DTC.Eref <$> attribute "to" url <*> para
                 , element "iref" $ TreeN . DTC.Iref Nothing . wordify <$> attribute "to" text <*> para
                 , element "ref"  $ TreeN . DTC.Ref  <$> to <*> para
-                , element "rref" $ TreeN . DTC.Rref <$> to <*> para
+                , element "rref" $ TreeN . DTC.Rref Nothing <$> to <*> para
                 , element "br"   $ Tree0 DTC.BR <$ none
                 , Tree0 . DTC.Plain <$> text
                 ]
@@ -232,14 +234,10 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
        author = rule "author" $ element "author" entity
        editor = rule "editor" $ element "editor" entity
        entity = rule "entity" $
-               DTC.Entity
-                <$> name
-                <*> address
-       address = rule "address" $
-               element "address" $
                interleaved $
-               DTC.Address
-                <$?> (def, attribute "street"  text)
+               DTC.Entity
+                <$?> (def, attribute "name"    text)
+                <|?> (def, attribute "street"  text)
                 <|?> (def, attribute "zipcode" text)
                 <|?> (def, attribute "city"    text)
                 <|?> (def, attribute "region"  text)
@@ -247,6 +245,7 @@ class RNC.Sym_RNC repr => Sym_DTC repr where
                 <|?> (def, attribute "email"   text)
                 <|?> (def, attribute "tel"     text)
                 <|?> (def, attribute "fax"     text)
+                <|?> (def, Just <$> attribute "url" url)
        serie = rule "serie" $
                element "serie" $
                interleaved $
@@ -288,7 +287,6 @@ dtcRNC =
  , void $ editor
  , void $ date
  , void $ entity
- , void $ address
  , void $ link
  , void $ serie
  , void $ alias
@@ -299,6 +297,7 @@ dtcRNC =
  , void $ tof
  , void $ index
  , void $ figure
+ , void $ references
  , void $ reference
  , void $ include
   
index 024a0ddc8cb9ebba13ab2ae1b6a7eada1ac319ff..a7a1bda2178f667218459f26e92873e751339722 100644 (file)
@@ -22,12 +22,13 @@ import Control.Monad
 import Data.Bool
 import Data.Char (Char)
 import Data.Eq (Eq(..))
-import Data.Foldable (Foldable(..))
+import Data.Foldable (Foldable(..), concat)
 import Data.Function (($), const, flip, on)
 import Data.Functor (Functor(..), (<$>))
 import Data.Functor.Compose (Compose(..))
+import Data.Int (Int)
 import Data.Map.Strict (Map)
-import Data.Maybe (Maybe(..), maybe, mapMaybe, fromJust, listToMaybe)
+import Data.Maybe (Maybe(..), maybe, mapMaybe, fromJust, maybeToList)
 import Data.Monoid (Monoid(..))
 import Data.Ord (Ord(..))
 import Data.Semigroup (Semigroup(..))
@@ -72,19 +73,23 @@ type Html5 = StateMarkup State ()
 -- ** Type 'State'
 data State
  =   State
- { state_styles   :: Map FilePath CSS
- , state_scripts  :: Map FilePath Script
- , state_localize :: MsgHtml5 -> Html5
- , state_indexs   :: Map DTC.Pos (DTC.Terms, Anchor.Irefs)
- , state_figures  :: Map Text (Map DTC.Pos DTC.Title)
+ { state_styles     :: Map FilePath CSS
+ , state_scripts    :: Map FilePath Script
+ , state_localize   :: MsgHtml5 -> Html5
+ , state_indexs     :: Map DTC.Pos (DTC.Terms, Anchor.Irefs)
+ , state_rrefs      :: Anchor.Rrefs
+ , state_figures    :: Map Text (Map DTC.Pos DTC.Title)
+ , state_references :: Map DTC.Ident DTC.About
  }
 state :: State
 state = State
- { state_styles   = mempty
- , state_scripts  = mempty
- , state_localize = html5ify . show
- , state_indexs   = mempty
- , state_figures  = mempty
+ { state_styles     = mempty
+ , state_scripts    = mempty
+ , state_localize   = html5ify . show
+ , state_indexs     = mempty
+ , state_rrefs      = mempty
+ , state_figures    = mempty
+ , state_references = mempty
  }
 type CSS = Text
 type Script = Text
@@ -92,12 +97,13 @@ type Script = Text
 -- ** Type 'Keys'
 data Keys
  = Keys
- { keys_index  :: Map DTC.Pos DTC.Terms
- , keys_figure :: Map Text (Map DTC.Pos DTC.Title)
+ { keys_index     :: Map DTC.Pos DTC.Terms
+ , keys_figure    :: Map Text (Map DTC.Pos DTC.Title)
+ , keys_reference :: Map DTC.Ident DTC.About
  } deriving (Show)
 
 keys :: Trees DTC.BodyKey DTC.BodyValue -> Keys
-keys body = foldl' flt (Keys mempty mempty) (Compose body)
+keys body = foldl' flt (Keys mempty mempty mempty) (Compose body)
        where
        flt acc = \case
         DTC.Index{..} -> acc{keys_index =
@@ -106,6 +112,13 @@ keys body = foldl' flt (Keys mempty mempty) (Compose body)
                Map.insertWith (<>)
                 type_ (Map.singleton pos title) $
                keys_figure acc}
+        DTC.References{..} -> acc{keys_reference =
+               foldr
+                (\r -> Map.insert
+                        (DTC.id    (r::DTC.Reference))
+                        (DTC.about (r::DTC.Reference)))
+                (keys_reference acc)
+                refs}
         _ -> acc
 
 -- ** Class 'Html5ify'
@@ -132,16 +145,23 @@ html5Document ::
  LocaleIn ls -> Document -> Html
 html5Document locale DTC.Document{..} = do
        let Keys{..} = keys body
-       let (body',state_indexs) =
+       let (body',state_rrefs,state_indexs) =
                let irefs = foldMap Anchor.irefsOfTerms keys_index in
-               (<$> S.runState (Anchor.anchorify body) Anchor.state
-                        { Anchor.state_irefs = irefs }) $ \Anchor.State{state_irefs} ->
-                       (<$> keys_index) $ \terms ->
-                               (terms,) $
-                               TreeMap.intersection const state_irefs $
-                               Anchor.irefsOfTerms terms
+               let (body0, Anchor.State{state_irefs, state_rrefs=rrefs}) = 
+                       Anchor.anchorify body `S.runState`
+                       Anchor.state{Anchor.state_irefs=irefs} in
+               (body0,rrefs,) $
+               (<$> keys_index) $ \terms ->
+                       (terms,) $
+                       TreeMap.intersection const state_irefs $
+                       Anchor.irefsOfTerms terms
        let (html5Body, State{state_styles,state_scripts}) =
-               runStateMarkup state{state_indexs, state_figures=keys_figure} $ do
+               runStateMarkup state
+                { state_indexs
+                , state_rrefs
+                , state_figures    = keys_figure
+                , state_references = keys_reference
+                } $ do
                        liftStateMarkup $ S.modify $ \s -> s{state_localize = Locale.localize locale}
                        html5ify body'
        
@@ -272,25 +292,28 @@ html5BodyValue z = \case
                                                forM_ terms $ \aliases -> do
                                                        H.dt $$
                                                                H.ul ! HA.class_ "index-aliases" $$
-                                                                       forM_ (listToMaybe aliases) $ \term ->
+                                                                       forM_ (List.take 1 aliases) $ \term ->
                                                                                H.li ! HA.id (attrValue term) $$
                                                                                        html5ify term
-                                                       H.dd $$ do
+                                                       H.dd $$
                                                                let anchs =
                                                                        List.sortBy (compare `on` DTC.section . snd) $
                                                                        (`foldMap` aliases) $ \words ->
                                                                                fromJust $ do
                                                                                        path <- Anchor.pathFromWords words
                                                                                        Strict.maybe Nothing (Just . ((words,) <$>) . List.reverse) $
-                                                                                               TreeMap.lookup path refsByTerm
-                                                               sequence_ $
-                                                                       List.intersperse ", " $
-                                                                       (<$> anchs) $ \(term,DTC.Anchor{..}) ->
-                                                                               H.a ! HA.href ("#"<>attrValue (term,count)) $$
-                                                                                       html5ify $
-                                                                                               List.intercalate "." $
-                                                                                               toList $
-                                                                                               (<$> DTC.posAncestors section) $ \(_n,c) -> show c
+                                                                                               TreeMap.lookup path refsByTerm in
+                                                               html5CommasDot $
+                                                               (<$> anchs) $ \(term,DTC.Anchor{..}) ->
+                                                                       H.a ! HA.class_ "index-iref"
+                                                                           ! HA.href ("#"<>attrValue (term,count)) $$
+                                                                               html5ify $ DTC.posAncestors section
+        DTC.References{..} ->
+               html5CommonAttrs attrs $
+               H.div ! HA.class_ "references"
+                     ! HA.id (attrValue pos) $$ do
+                       H.table $$
+                               forM_ refs html5ify
 
 instance Html5ify DTC.Words where
        html5ify = html5ify . Anchor.plainifyWords
@@ -367,12 +390,6 @@ instance Html5ify DTC.Block where
                     ! HA.id (attrValue pos) $$ do
                        forM_ items $ \item ->
                                H.li $$ html5ify item
-        DTC.RL{..} ->
-               html5CommonAttrs attrs $
-               H.div ! HA.class_ "rl"
-                     ! HA.id (attrValue pos) $$ do
-                       H.table $$
-                               forM_ refs html5ify
         DTC.Comment t ->
                html5ify $ H.Comment (H.Text t) ()
 instance Html5ify DTC.Lines where
@@ -400,7 +417,9 @@ instance Html5ify DTC.Lines where
                 DTC.Eref{..} ->
                        H.a ! HA.class_ "eref"
                            ! HA.href (attrValue href) $$
-                               html5ify ls
+                               if null ls
+                               then html5ify $ DTC.unURL href
+                               else html5ify ls
                 DTC.Iref{..} ->
                        case anchor of
                         Nothing -> html5ify ls
@@ -414,10 +433,31 @@ instance Html5ify DTC.Lines where
                        if null ls
                        then html5ify to
                        else html5ify ls
-                DTC.Rref{..} ->
+                DTC.Rref{..} -> do
+                       when (not $ null ls) $ do
+                               refs <- liftStateMarkup $ S.gets state_references
+                               case Map.lookup to refs of
+                                Nothing -> pure ()
+                                Just DTC.About{..} ->
+                                       forM_ (List.take 1 titles) $ \(DTC.Title title) -> do
+                                               html5ify $ TreeN DTC.Q $
+                                                       case url of
+                                                        Nothing -> title
+                                                        Just u -> pure $ TreeN (DTC.Eref u) title
+                                               " "::Html5
+                                Nothing -> html5ify ls
+                       "["::Html5
                        H.a ! HA.class_ "rref"
-                           ! HA.href (attrValue to) $$
-                               html5ify ls
+                           ! HA.href ("#rref."<>attrValue to)
+                           ! HA.id ("rref."<>attrValue to<>maybe "" (\DTC.Anchor{..} -> "."<>attrValue count) anchor) $$
+                               html5ify to
+                       "]"
+instance Html5ify DTC.URL where
+       html5ify (DTC.URL url) =
+               H.a ! HA.class_ "eref"
+                   ! HA.href (attrValue url) $$
+                       html5ify url
+
 instance AttrValue DTC.Words where
        attrValue term =
                "iref" <> "." <> attrValue (Anchor.plainifyWords term)
@@ -426,25 +466,55 @@ instance AttrValue (DTC.Words,DTC.Nat1) where
                "iref"
                 <> "." <> attrValue (Anchor.plainifyWords term)
                 <> "." <> attrValue count
+instance Html5ify DTC.Date where
+       html5ify = html5ify . MsgHTML5_Date
 instance Html5ify DTC.About where
        html5ify DTC.About{..} =
-               forM_ titles $ \(DTC.Title title) ->
-                       html5ify $ Seq.singleton $ TreeN DTC.Q title
+               html5CommasDot $ concat $
+                [ (<$> List.take 1 titles) $ \(DTC.Title title) ->
+                       html5ify $ TreeN DTC.Q $
+                               case url of
+                                Nothing -> title
+                                Just u -> pure $ TreeN (DTC.Eref u) title
+                , html5Entity <$> authors
+                , html5ify <$> maybeToList date
+                , html5Entity <$> maybeToList editor
+                , html5Serie <$> series
+                ]
+               where
+               html5Serie DTC.Serie{..} = do
+                       html5ify key
+                       html5ify MsgHTML5_Colon
+                       html5ify name
+               html5Entity DTC.Entity{url=mu, ..} =
+                       html5ify @DTC.Lines $
+                       case () of
+                        _ | not (Text.null email) -> TreeN (DTC.Eref $ DTC.URL $ "mailto:"<>email) $ pure $ Tree0 $ DTC.Plain name
+                        _ | Just u <- mu  -> TreeN (DTC.Eref u) $ pure $ Tree0 $ DTC.Plain name
+                        _ -> Tree0 $ DTC.Plain name
 instance Html5ify DTC.Reference where
-       html5ify ref@DTC.Reference{about} =
+       html5ify DTC.Reference{id=id_, ..} =
                H.tr $$ do
                        H.td ! HA.class_ "reference-key" $$
-                               html5ifyReference ref
-                       H.td ! HA.class_ "reference-content" $$
+                               html5ify @DTC.Lines $ TreeN DTC.Rref{anchor=Nothing, to=id_} Seq.empty
+                       H.td ! HA.class_ "reference-content" $$ do
                                html5ify about
+                               rrefs <- liftStateMarkup $ S.gets state_rrefs
+                               case Map.lookup id_ rrefs of
+                                Nothing -> pure ()
+                                Just anchs ->
+                                       H.span ! HA.class_ "reference-rrefs" $$
+                                               html5CommasDot $
+                                               (<$> List.reverse anchs) $ \DTC.Anchor{..} ->
+                                                       H.a ! HA.class_ "reference-rref"
+                                                           ! HA.href ("#rref."<>attrValue id_<>"."<>attrValue count) $$
+                                                               html5ify $ DTC.posAncestors section
 
-html5ifyReference :: DTC.Reference -> Html5
-html5ifyReference DTC.Reference{id=id_, ..} = do
-       let i = "reference."<>attrValue id_
-       "["::Html5
-       H.a ! HA.id i ! HA.href ("#"<>i) $$
-               html5ify id_
-       "]"
+html5CommasDot :: [Html5] -> Html5
+html5CommasDot [] = pure ()
+html5CommasDot hs = do
+       sequence_ $ List.intersperse ", " hs
+       "."
 
 html5CommonAttrs :: DTC.CommonAttrs -> Html5 -> Html5
 html5CommonAttrs DTC.CommonAttrs{id=id_, ..} =
@@ -539,6 +609,12 @@ instance Plainify DTC.PosPath where
                        )
                 )
                 ("","")
+instance Html5ify Int where
+       html5ify = html5ify . show
+instance Html5ify DTC.Nat where
+       html5ify (DTC.Nat n) = html5ify n
+instance Html5ify DTC.Nat1 where
+       html5ify (DTC.Nat1 n) = html5ify n
 
 -- * Type 'MsgHtml5'
 data MsgHtml5
@@ -546,6 +622,7 @@ data MsgHtml5
  |   MsgHTML5_Colon
  |   MsgHTML5_QuoteOpen
  |   MsgHTML5_QuoteClose
+ |   MsgHTML5_Date DTC.Date
  deriving (Show)
 instance Html5ify MsgHtml5 where
        html5ify msg = do
@@ -557,9 +634,57 @@ instance LocalizeIn FR Html5 MsgHtml5 where
         MsgHTML5_Colon -> " :"
         MsgHTML5_QuoteOpen -> "« "
         MsgHTML5_QuoteClose -> " »"
+        MsgHTML5_Date DTC.Date{..} ->
+               sequence_ $
+               List.intersperse " " $
+               concat
+                [ maybe [] (pure . html5ify) day
+                , case month of
+                        Nothing -> []
+                        Just (DTC.Nat1 m) ->
+                               case m of
+                                1  -> pure "janvier"
+                                2  -> pure "février"
+                                3  -> pure "mars"
+                                4  -> pure "avril"
+                                5  -> pure "mai"
+                                6  -> pure "juin"
+                                7  -> pure "juillet"
+                                8  -> pure "août"
+                                9  -> pure "septembre"
+                                10 -> pure "octobre"
+                                11 -> pure "novembre"
+                                12 -> pure "décembre"
+                                _  -> []
+                , [html5ify year]
+                ]
 instance LocalizeIn EN Html5 MsgHtml5 where
        localizeIn _ = \case
         MsgHTML5_Table_of_Contents -> "Summary"
         MsgHTML5_Colon -> ":"
         MsgHTML5_QuoteOpen  -> "“"
         MsgHTML5_QuoteClose -> "”"
+        MsgHTML5_Date DTC.Date{..} ->
+               sequence_ $
+               List.intersperse " " $
+               concat
+                [ maybe [] (pure . html5ify) day
+                , case month of
+                        Nothing -> []
+                        Just (DTC.Nat1 m) ->
+                               case m of
+                                1  -> pure "January"
+                                2  -> pure "February"
+                                3  -> pure "March"
+                                4  -> pure "April"
+                                5  -> pure "May"
+                                6  -> pure "June"
+                                7  -> pure "July"
+                                8  -> pure "August"
+                                9  -> pure "September"
+                                10 -> pure "October"
+                                11 -> pure "November"
+                                12 -> pure "December"
+                                _  -> []
+                , [html5ify year]
+                ]
index 3d530c60f6e6845c5bd34323d419c6541bb6a93b..76b10cd167e4b80a1bacf2f2078aa0c64285f8bc 100644 (file)
@@ -71,12 +71,6 @@ xmlBodyValue = \case
                        XML.ul $
                                forM_ types $
                                        XML.li . xmlText
-        DTC.Figure{..} ->
-               xmlCommonAttrs attrs $
-               XML.figure
-                ! XA.type_ (attrValue type_) $ do
-                       xmlTitle title
-                       xmlBlocks blocks
         DTC.Index{..} ->
                xmlCommonAttrs attrs $
                XML.index $ do
@@ -86,13 +80,22 @@ xmlBodyValue = \case
                                                xmlText $
                                                Text.unlines $
                                                plainifyWords <$> aliases
+        DTC.Figure{..} ->
+               xmlCommonAttrs attrs $
+               XML.figure
+                ! XA.type_ (attrValue type_) $ do
+                       xmlTitle title
+                       xmlBlocks blocks
+        DTC.References{..} ->
+               xmlCommonAttrs attrs $
+               XML.references $ forM_ refs $ xmlReference
         DTC.Block v -> xmlBlock v
 
 xmlAbout :: DTC.About -> XML
 xmlAbout DTC.About{..} = do
        forM_ titles   $ xmlTitle
-       forM_ authors  $ xmlAuthor
-       forM_ editor   $ xmlEditor
+       forM_ authors  $ xmlEntity
+       forM_ editor   $ xmlEntity
        forM_ date     $ xmlDate
        whenMayText version xmlVersion
        forM_ keywords $ xmlKeyword
@@ -125,10 +128,11 @@ xmlLink DTC.Link{..} =
         !?? mayAttr XA.href href
         $ xmlPara para
 
-xmlAddress :: DTC.Address -> XML
-xmlAddress DTC.Address{..} =
-       XML.address
-        !?? mayAttr XA.street street
+xmlEntity :: DTC.Entity -> XML
+xmlEntity DTC.Entity{..} =
+       XML.entity
+        !?? mayAttr XA.name    name
+        !?? mayAttr XA.street  street
         !?? mayAttr XA.zipcode zipcode
         !?? mayAttr XA.city    city
         !?? mayAttr XA.region  region
@@ -137,18 +141,6 @@ xmlAddress DTC.Address{..} =
         !?? mayAttr XA.tel     tel
         !?? mayAttr XA.fax     fax
 
-xmlAuthor :: DTC.Entity -> XML
-xmlAuthor DTC.Entity{..} =
-       XML.author
-        !?? mayAttr XA.name name
-        $ xmlAddress address
-
-xmlEditor :: DTC.Entity -> XML
-xmlEditor DTC.Entity{..} =
-       XML.editor
-        !?? mayAttr XA.name name
-        $ xmlAddress address
-
 xmlTitle :: DTC.Title -> XML
 xmlTitle (DTC.Title t) = XML.title $ xmlPara t
 
@@ -181,10 +173,6 @@ xmlBlock = \case
         DTC.UL{..} ->
                xmlCommonAttrs attrs $
                XML.ul $ forM_ items $ XML.li . xmlBlocks
-        DTC.RL{..} ->
-               xmlCommonAttrs attrs $
-               XML.rl $ forM_ refs $ xmlReference
-        -- DTC.Index -> XML.index
         DTC.Comment c ->
                XML.comment c
         DTC.Artwork{..} ->
@@ -215,7 +203,7 @@ xmlLine = \case
         DTC.Eref to  -> XML.eref ! XA.to (attrValue to) $ xmlPara ls
         DTC.Iref{..} -> XML.iref ! XA.term (attrValue $ plainifyWords term) $ xmlPara ls
         DTC.Ref  to  -> XML.ref  ! XA.to (attrValue to) $ xmlPara ls
-        DTC.Rref to  -> XML.rref ! XA.to (attrValue to) $ xmlPara ls
+        DTC.Rref{..} -> XML.rref ! XA.to (attrValue to) $ xmlPara ls
 
 xmlReference :: DTC.Reference -> XML
 xmlReference DTC.Reference{..} =
index 064f028c741c36d4230403d9295cfc672456b4a1..989d388340e9ed7e664a2c0b03c828321862bd25 100644 (file)
@@ -49,7 +49,7 @@ readTCTs ::
 readTCTs inp txt = do
        tct <- P.runParser (p_Trees <* P.eof) inp txt
        (`traverse` tct) $ \tr ->
-               sequence $ (`TreeSeq.mapWithKey`tr) $ \key c@(Cell pos _posEnd t) ->
+               sequence $ (`TreeSeq.mapWithNode`tr) $ \key c@(Cell pos _posEnd t) ->
                        case key of
                         -- Verbatim Keys
                         Just (unCell -> KeyBar{})   -> Right $ tokens [TokenPlain <$> c]
index d9cc5bfdacfdc9d242820695f8e1e1770d81128e..201b6361b7255b389de55c8224db23a2d4f5634b 100644 (file)
@@ -239,11 +239,14 @@ p_Escape = P.char '\\' *> P.satisfy Char.isPrint
 
 p_Link :: Parser e s Text
 p_Link =
-       (\scheme addr -> Text.pack $ scheme <> "//" <> addr)
-        <$> P.option "" (P.try p_scheme)
-        <*  P.string "//"
-        <*> p_addr
+       P.try (P.char '<' *> p <* P.char '>') <|>
+       p
        where
+       p =
+               (\scheme addr -> Text.pack $ scheme <> "//" <> addr)
+                <$> P.option "" (P.try p_scheme)
+                <*  P.string "//"
+                <*> p_addr
        p_scheme =
                (<> ":")
                 <$> P.some (P.satisfy $ \c ->
index f36fbb01a51680fe45499e1f05289b4a08b29067..aaef1c2d3c88d4050467ceaf1b42117a267b4c8b 100644 (file)
@@ -112,7 +112,7 @@ xmlTCTs inh_orig = go inh_orig
                  | (rl,ts) <- spanlBrackets trees
                  , not (null rl) ->
                        (<| go inh ts) $
-                       TreeN (Cell bp ep "rl") $
+                       TreeN (Cell bp ep "references") $
                                rl >>= xmlTCT inh_orig
                
                 _ | (ul,ts) <- spanlItems (==KeyDash) trees
@@ -171,6 +171,7 @@ xmlTCT inh tr =
                         "about"     -> xmlTitle : xmlTitle : List.repeat xmlPara
                         "reference" -> xmlTitle : xmlTitle : List.repeat xmlPara
                         "author"    -> List.repeat xmlName
+                        "editor"    -> List.repeat xmlName
                         _           -> []
                 } in
                case () of
@@ -219,7 +220,7 @@ xmlKey inh (Cell bp ep key) attrs ts =
                com :: TL.Text
                com =
                        Write.text Write.config_text $
-                       TreeSeq.mapAlsoKey
+                       TreeSeq.mapAlsoNode
                         (cell1 . unCell)
                         (\_path -> fmap $ cell1 . unCell) <$> ts
         KeyLower n as -> TreeN (cell "artwork") $ xmlTCTs inh ts
@@ -253,8 +254,7 @@ xmlTokens tok = goTokens tok
                 TokenEscape c -> Seq.singleton $ Tree0 $ cell $ XmlText $ Text.singleton c
                 TokenLink lnk -> Seq.singleton $
                        TreeN (cell "eref") $
-                               xmlAttrs [cell ("to",lnk)] |>
-                               Tree0 (cell $ XmlText lnk)
+                               xmlAttrs [cell ("to",lnk)]
                 TokenPair PairBracket ts | to <- Write.textTokens ts
                                          , TL.all (\c -> Char.isAlphaNum c || Char.isSymbol c) to ->
                        Seq.singleton $
@@ -447,7 +447,7 @@ partitionAttributesChildren ts = (attrs,cs)
                        where
                        v = TL.toStrict $
                                Write.text Write.config_text{Write.config_text_escape = False} $
-                               TreeSeq.mapAlsoKey (cell1 . unCell) (\_path -> fmap $ cell1 . unCell) <$> a
+                               TreeSeq.mapAlsoNode (cell1 . unCell) (\_path -> fmap $ cell1 . unCell) <$> a
                 _ -> undefined
 
 elems :: Set Text
@@ -509,8 +509,8 @@ elems =
  , "q"
  , "ref"
  , "reference"
+ , "references"
  , "region"
- , "rl"
  , "rref"
  , "sc"
  , "section"
index 73f84f68244efee92dfd490a288001e133916338..45be9e3ff149847af3f9f797ba51a561ca2cb986 100644 (file)
@@ -97,13 +97,13 @@ predNat1 (Nat1 n) | n <= 1    = Nothing
 
 -- * Type 'Ident'
 newtype Ident = Ident { unIdent :: Text }
- deriving (Eq,Show,Default,IsString)
+ deriving (Eq,Ord,Show,Default,IsString)
 instance Default Text where
        def = ""
 
 -- * Type 'URL'
-newtype URL = URL Text
- deriving (Eq,Show,Default)
+newtype URL = URL { unURL :: Text }
+ deriving (Eq,Ord,Show,Default)
 instance Semigroup URL where
        _x <> y = y
 
index bfe361f9af8700a2c40cf15a15a1dba96228b03a..327efec5882113932c81016dbc942373c435435a 100644 (file)
@@ -41,8 +41,6 @@ about :: DTC -> DTC
 about = Parent "about" "<about" "</about>"
 alias :: DTC
 alias = Leaf "alias" "<alias" "/>" ()
-address :: DTC
-address = Leaf "address" "<address" "/>" ()
 artwork :: DTC -> DTC
 artwork = Parent "artwork" "<artwork" "</artwork>"
 author :: DTC -> DTC
@@ -69,6 +67,8 @@ editor :: DTC -> DTC
 editor = Parent "editor" "<editor" "</editor>"
 email :: DTC -> DTC
 email = Parent "email" "<email" "</email>"
+entity :: DTC
+entity = Leaf "entity" "<entity" "/>" ()
 eref :: DTC -> DTC
 eref (Empty a) = Leaf "eref" "<eref" "/>" a
 eref x = Parent "eref" "<eref" "</eref>" x
@@ -110,8 +110,8 @@ ref (Empty a) = Leaf "ref" "<ref" "/>" a
 ref x = Parent "ref" "<ref" "</ref>" x
 reference :: DTC -> DTC
 reference = Parent "reference" "<reference" "</reference>"
-rl :: DTC -> DTC
-rl = Parent "rl" "<rl" "</rl>"
+references :: DTC -> DTC
+references = Parent "references" "<references" "</references>"
 rref :: DTC -> DTC
 rref (Empty a) = Leaf "rref" "<rref" "/>" a
 rref x = Parent "rref" "<rref" "</rref>" x
index 1cb5e30a73cbb93ba4575634d2629ca961e99313..94233967050c8c44a4a184b7b47f8f6a61b68d23 100644 (file)
@@ -87,6 +87,8 @@ instance MayAttr Int where
 instance MayAttr [Char] where
        mayAttr _ "" = Nothing
        mayAttr a t  = Just (a $ fromString t)
+instance MayAttr AttributeValue where
+       mayAttr a = Just . a
 
 -- * Type 'StateMarkup'
 -- | Composing state and markups.
index f1b0ee6b446561b2b18bbeb3bc2fdb35da703071..332985ef4daad603815326e47cc8f9160e6f9404 100644 (file)
@@ -2,30 +2,35 @@
 {-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE OverloadedLists #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module Main where
 
-import Control.Monad (forM_)
+import Control.Monad (forM_, when)
 import Data.Bool
-import Data.Eq (Eq(..))
+import Data.Default.Class (Default(..))
 import Data.Either (Either(..))
+import Data.Eq (Eq(..))
 import Data.Function (($), (.))
 import Data.Functor ((<$>))
-import Data.Maybe (fromMaybe)
+import Data.Map.Strict (Map)
+import Data.Maybe (Maybe(..), fromMaybe)
 import Data.Monoid (Monoid(..))
 import Data.Semigroup (Semigroup(..))
+import Data.String (String)
+import GHC.Exts (IsList(..))
 import Options.Applicative as Opt
 import Prelude (error)
 import System.IO (IO, FilePath, hPrint, hPutStrLn, stderr, stdout)
 import qualified Data.ByteString as BS
 import qualified Data.Char as Char
-import qualified Data.Text.IO as Text
-import qualified Data.Text as Text
 import qualified Data.List as List
-import qualified Text.Blaze.Renderer.Utf8 as Blaze
-import qualified Text.Blaze.Utils as Blaze
 import qualified Data.Map.Strict as Map
+import qualified Data.Text as Text
+import qualified Data.Text.IO as Text
 import qualified System.Environment as Env
+import qualified Text.Blaze.Renderer.Utf8 as Blaze
+import qualified Text.Blaze.Utils as Blaze
 
 import Data.Locale
 
@@ -56,11 +61,11 @@ main = do
                 (locales @Langs)) .
                fromMaybe ""
                 <$> Env.lookupEnv "LANG"
-       cmd <- execParser $ p_Argv lang
+       cmd <- execParser $ pArgv lang
        mainWithCommand cmd
        where
-       p_Argv lang =
-               info (p_Command lang <**> helper) $ mconcat $
+       pArgv lang =
+               info (pCommand lang <**> helper) $ mconcat
                 [ fullDesc
                 , progDesc "document tool"
                 , header "hdoc - TCT and DTC command line tool"
@@ -82,16 +87,19 @@ mainWithCommand (CommandDTC ArgsDTC{..}) =
                case TCT.readTCTs input txt of
                 Left err -> error $ P.parseErrorPretty err
                 Right tct -> do
-                       hPutStrLn stderr "### TCT ###"
-                       hPrint stderr $ Tree.Pretty tct
+                       when (trace_TCT trace) $ do
+                               hPutStrLn stderr "### TCT ###"
+                               hPrint stderr $ Tree.Pretty tct
                        let xml = TCT.Write.XML.xmlDocument tct
-                       hPutStrLn stderr "### XML ###"
-                       hPrint stderr $ Tree.Pretty xml
+                       when (trace_XML trace) $ do
+                               hPutStrLn stderr "### XML ###"
+                               hPrint stderr $ Tree.Pretty xml
                        case DTC.Read.TCT.readDTC xml of
                         Left err -> error $ P.parseErrorPretty err
                         Right dtc -> do
-                               hPutStrLn stderr "### DTC ###"
-                               hPrint stderr dtc
+                               when (trace_DTC trace) $ do
+                                       hPutStrLn stderr "### DTC ###"
+                                       hPrint stderr dtc
                                case format of
                                 DtcFormatXML ->
                                        Blaze.prettyMarkupIO Blaze.DTC.indentTag BS.putStr $
@@ -103,26 +111,89 @@ mainWithCommand (CommandRNC ArgsRNC{}) =
        forM_ DTC.dtcRNC $ \w ->
                Text.hPutStrLn stdout $ RNC.renderWriter w
 
+-- * Options utils
+
+instance IsList (Opt.Mod f a) where
+       type Item (Opt.Mod f a) = Opt.Mod f a
+       fromList = mconcat
+       toList   = pure
+
+readMap :: Map String a -> ReadM a
+readMap m =
+       eitherReader $ \s ->
+               case Map.lookup s m of
+                Nothing -> Left $ "cannot parse value \"" <> s
+                        <> "\"\nexpecting one of: "
+                        <> (List.intercalate ", " $ Map.keys m)
+                Just a -> Right a
+
 -- * Type 'Command'
 data Command
  =   CommandTCT ArgsTCT
  |   CommandDTC ArgsDTC
  |   CommandRNC ArgsRNC
 
-p_Command :: Lang -> Parser Command
-p_Command lang =
-       subparser (
-               command "tct" $
-                       info (CommandTCT <$> p_ArgsTCT <**> helper) $
-                               progDesc "TCT (Texte Convivial Technique) rendition.") <|>
-       subparser (
-               command "dtc" $
-                       info (CommandDTC <$> p_ArgsDTC lang <**> helper) $
-                               progDesc "DTC (Document Technique Convivial) rendition.") <|>
-       subparser (
-               command "rnc" $
-                       info (CommandRNC <$> p_ArgsRNC <**> helper) $
-                               progDesc "RNC (RelaxNG Compact) schema.")
+pCommand :: Lang -> Parser Command
+pCommand lang =
+       hsubparser
+        [ metavar "tct"
+        , command "tct" $
+               info (CommandTCT <$> pArgsTCT) $
+                       progDesc "TCT (Texte Convivial Technique) rendition."
+        ] <|>
+       hsubparser
+        [ metavar "dtc"
+        , command "dtc" $
+               info (CommandDTC <$> pArgsDTC lang) $
+                       progDesc "DTC (Document Technique Convivial) rendition."
+        ] <|>
+       hsubparser
+        [ metavar "rnc"
+        , command "rnc" $
+               info (CommandRNC <$> pArgsRNC) $
+                       progDesc "RNC (RelaxNG Compact) schema."
+        ]
+
+-- * Type 'Trace'
+data Trace
+ =   Trace
+ {   trace_TCT :: Bool
+ ,   trace_XML :: Bool
+ ,   trace_DTC :: Bool
+ }
+instance Default Trace where
+       def = Trace
+        { trace_TCT = False
+        , trace_XML = False
+        , trace_DTC = False
+        }
+instance Semigroup Trace where
+       x <> y =
+               Trace
+                { trace_TCT = trace_TCT x || trace_TCT y
+                , trace_XML = trace_XML x || trace_XML y
+                , trace_DTC = trace_DTC x || trace_DTC y
+                }
+instance Monoid Trace where
+       mempty  = def
+       mappend = (<>)
+
+pTrace :: Parser Trace
+pTrace =
+       (mconcat <$>) $
+       many $
+       option
+        (readMap m)
+        [ long "trace"
+        , help $ "Print trace. (choices: "
+                <> (List.intercalate ", " $ Map.keys m) <> ")"
+        ]
+       where
+       m = Map.fromList
+        [ ("tct", def{trace_TCT=True})
+        , ("xml", def{trace_XML=True})
+        , ("dtc", def{trace_DTC=True})
+        ]
 
 -- ** Type 'ArgsTCT'
 data ArgsTCT
@@ -131,20 +202,22 @@ data ArgsTCT
  ,   format :: TctFormat
  }
 
-p_ArgsTCT :: Parser ArgsTCT
-p_ArgsTCT =
+pArgsTCT :: Parser ArgsTCT
+pArgsTCT =
        ArgsTCT
         <$> argument str (metavar "FILE")
-        <*> p_TctFormat
+        <*> pTctFormat
 
 -- *** Type 'TctFormat'
 data TctFormat
  =   TctFormatHTML5
 
-p_TctFormat :: Parser TctFormat
-p_TctFormat =
+pTctFormat :: Parser TctFormat
+pTctFormat =
        flag TctFormatHTML5 TctFormatHTML5
-        (long "html5" <> help "Render as HTML5.")
+        [ long "html5"
+        , help "Render as HTML5."
+        ]
 
 -- ** Type 'ArgsDTC'
 data ArgsDTC
@@ -152,43 +225,49 @@ data ArgsDTC
  {   input  :: FilePath
  ,   format :: DtcFormat
  ,   locale :: Lang
- -- ,   argsDTC_locale :: LocaleIn Langs
+ ,   trace  :: Trace
  }
-p_ArgsDTC :: Lang -> Parser ArgsDTC
-p_ArgsDTC lang =
+pArgsDTC :: Lang -> Parser ArgsDTC
+pArgsDTC lang =
        ArgsDTC
         <$> argument str (metavar "FILE")
-        <*> p_DtcFormat
-        <*> p_Locale lang
+        <*> pDtcFormat
+        <*> pLocale lang
+        <*> pTrace
 
-p_Locale :: Lang -> Parser (LocaleIn Langs)
-p_Locale lang =
+pLocale :: Lang -> Parser (LocaleIn Langs)
+pLocale lang =
        option
         (maybeReader $ \s -> Map.lookup (Text.pack s) $ locales @Langs)
-        ( long "lang"
-        <> help "Language."
-        <> showDefault
-        <> value lang
-        <> metavar "LOCALE")
+        [ long "lang"
+        , help "Language."
+        , showDefault
+        , value lang
+        , metavar "LOCALE"
+        ]
 
 -- *** Type 'DtcFormat'
 data DtcFormat
  =   DtcFormatHTML5
  |   DtcFormatXML
 
-p_DtcFormat :: Parser DtcFormat
-p_DtcFormat =
+pDtcFormat :: Parser DtcFormat
+pDtcFormat =
        flag DtcFormatHTML5 DtcFormatHTML5
-        (long "html5" <> help "Render as HTML5.") <|>
+        [ long "html5"
+        , help "Render as HTML5."
+        ] <|>
        flag DtcFormatHTML5 DtcFormatXML
-        (long "xml"   <> help "Render as XML.")
+        [ long "xml"
+        , help "Render as XML."
+        ]
 
 -- ** Type 'ArgsRNC'
 data ArgsRNC
  =   ArgsRNC
 
-p_ArgsRNC :: Parser ArgsRNC
-p_ArgsRNC = pure ArgsRNC
+pArgsRNC :: Parser ArgsRNC
+pArgsRNC = pure ArgsRNC
 
 
 {-
index 99843c73f1af18ec264d007a38de4edd892fe2b1..ecd142559a0549861d481133179fa43fffa1ae87 100644 (file)
@@ -170,6 +170,7 @@ Executable hdoc
     , bytestring
     , containers >= 0.5 && < 0.6
     , Decimal
+    , data-default-class
     , deepseq
     -- , directory
     , optparse-applicative