Cosmetic changes.
[doclang.git] / Language / DTC / Read / TCT.hs
index 24f1ff71262073940371821b2cfdbe446c6763bb..d947edadcdd138135c3ab2fad0c9ff234a6961a6 100644 (file)
@@ -2,7 +2,6 @@
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE ViewPatterns #-}
@@ -13,26 +12,29 @@ module Language.DTC.Read.TCT where
 import Control.Applicative (Applicative(..))
 import Control.Monad (Monad(..))
 import Data.Bool
+import Data.Default.Class (Default(..))
 import Data.Either (Either(..))
 import Data.Eq (Eq(..))
-import Data.Foldable (null, foldl')
+import Data.Foldable (Foldable(..))
 import Data.Function (($), (.), const, id)
 import Data.Functor ((<$>), (<$))
 import Data.Int (Int)
 import Data.List.NonEmpty (NonEmpty(..))
-import Data.Maybe (Maybe(..), fromMaybe)
-import Data.Monoid (Monoid(..))
+import Data.Maybe (Maybe(..), fromMaybe, maybe)
+import Data.Monoid (Monoid(..), First(..))
 import Data.Ord (Ord(..))
 import Data.Proxy (Proxy(..))
 import Data.Semigroup (Semigroup(..))
-import Data.Sequence (ViewL(..))
+import Data.Sequence (ViewL(..), (|>))
 import Data.String (String)
 import Data.Text (Text)
 import Data.Tuple (snd)
-import GHC.Exts (toList)
+import Prelude (Num(..))
 import Text.Read (readMaybe)
 import Text.Show (Show(..))
+import qualified Control.Monad.Trans.State as S
 import qualified Data.List as List
+import qualified Data.Map.Strict as Map
 import qualified Data.Sequence as Seq
 import qualified Data.Set as Set
 import qualified Data.Text as Text
@@ -40,15 +42,17 @@ import qualified Text.Megaparsec as P
 import qualified Text.Megaparsec.Perm as P
 
 import Language.TCT hiding (Parser)
-import Language.TCT.Write.XML (XML,XMLs,XmlLeaf(..))
-import Language.DTC.Document (Nat(..), Nat1(..))
+import Language.XML
 import qualified Language.DTC.Document as DTC
 import qualified Language.DTC.Sym as DTC
 import qualified Language.RNC.Sym as RNC
-import qualified Language.TCT.Write.XML as XML
+
+-- * Type 'State'
+type State = DTC.Pos
 
 -- * Type 'Parser'
-type Parser = P.Parsec Error XMLs
+-- type Parser = P.Parsec Error XMLs
+type Parser = S.StateT State (P.Parsec Error XMLs)
 
 instance RNC.Sym_Rule Parser where
        -- rule n p = P.dbg s p {-(p P.<?> s)-} where s = Text.unpack n
@@ -56,7 +60,7 @@ instance RNC.Sym_Rule Parser where
 instance RNC.Sym_RNC Parser where
        none = P.label "none" $ P.eof
        any  = P.label "any" $ p_satisfyMaybe $ const $ Just ()
-       anyElem p = P.dbg "anyElem" $ P.label "anyElem" $ do
+       anyElem p = P.label "anyElem" $ do
                (n,ts) <- P.token check $ Just expected
                parserXMLs (p n) ts
                where
@@ -67,7 +71,39 @@ instance RNC.Sym_RNC Parser where
                 , Set.singleton $ P.Tokens $ pure expected )
        element n p = do
                ts <- P.token check $ Just expected
-               parserXMLs p ts
+               xp <- S.get
+               let nameOrFigureName
+                       | n == "figure"
+                       -- NOTE: special case renaming the current DTC.Pos
+                       -- using the @type attribute to have positions like this:
+                       --   section1.Quote1
+                       --   section1.Example1
+                       --   section1.Quote2
+                       -- instead of:
+                       --   section1.figure1
+                       --   section1.figure2
+                       --   section1.figure3
+                       , Just ty <- getFirst $ (`foldMap` ts) $ \case
+                        Tree0 (unCell -> XmlAttr "type" ty) -> First $ Just ty
+                        _ -> First Nothing
+                       = xmlLocalName $ ty
+                       | otherwise = n
+               let anc name = maybe 1 (+1) $ Map.lookup name $ DTC.posPrecedingsSiblings xp
+               S.put xp
+                { DTC.posAncestors = DTC.posAncestors xp |> (n,anc n)
+                , DTC.posAncestorsWithFigureNames =
+                       DTC.posAncestorsWithFigureNames xp |>
+                       (nameOrFigureName,anc nameOrFigureName)
+                , DTC.posPrecedingsSiblings = mempty
+                }
+               parserXMLs p ts <* S.put xp
+                { DTC.posPrecedingsSiblings=
+                       (if n /= nameOrFigureName
+                       then Map.insertWith (\_new old -> old + 1) nameOrFigureName 1
+                       else id) $
+                       Map.insertWith (\_new old -> old + 1) n 1 $
+                       DTC.posPrecedingsSiblings xp
+                }
                where
                expected = TreeN (cell0 n) mempty
                check (TreeN (unCell -> e) ts) | e == n = Right ts
@@ -78,10 +114,10 @@ instance RNC.Sym_RNC Parser where
                v <- P.token check $ Just expected
                parserXMLs p v
                where
-               expected = Tree0 (cell0 $ XML.XmlAttr n "")
+               expected = Tree0 (cell0 $ XmlAttr n "")
                check (TreeN (unCell -> e) ts) | e == n = Right ts
-               check (Tree0 (Cell bp ep (XML.XmlAttr k v))) | k == n =
-                       Right $ Seq.singleton $ Tree0 $ Cell bp ep $ XML.XmlText v
+               check (Tree0 (Cell bp ep (XmlAttr k v))) | k == n =
+                       Right $ Seq.singleton $ Tree0 $ Cell bp ep $ XmlText v
                check t = Left
                 ( Just $ P.Tokens $ pure t
                 , Set.singleton $ P.Tokens $ pure expected )
@@ -95,13 +131,13 @@ instance RNC.Sym_RNC Parser where
                 EmptyL -> P.failure Nothing ex
                where
                ex = Set.singleton $ P.Tokens $ pure expected
-               expected = Tree0 (cell0 $ XML.XmlComment "")
+               expected = Tree0 (cell0 $ XmlComment "")
        text = do
                P.token check (Just expected)
                 <* fixPos
                where
-               expected = Tree0 (cell0 $ XML.XmlText "")
-               check (Tree0 (unCell -> XML.XmlText t)) = Right t
+               expected = Tree0 (cell0 $ XmlText "")
+               check (Tree0 (unCell -> XmlText t)) = Right t
                check t = Left
                 ( Just $ P.Tokens $ pure t
                 , Set.singleton $ P.Tokens $ pure expected )
@@ -136,20 +172,23 @@ instance RNC.Sym_Interleaved Parser where
        (<|?>) = (P.<|?>)
        f <$*> a = f P.<$?> ([],P.some a)
        f <|*> a = f P.<|?> ([],P.some a)
-instance DTC.Sym_DTC Parser
+instance DTC.Sym_DTC Parser where
+       position = S.get
 
 readDTC ::
  DTC.Sym_DTC Parser =>
  XMLs ->
  Either (P.ParseError (P.Token XMLs) Error) DTC.Document
-readDTC = parseXMLs (P.initialPos "") DTC.document
+readDTC = parseXMLs def (P.initialPos "") DTC.document
 
 parseXMLs ::
  DTC.Sym_DTC Parser =>
+ State ->
  P.SourcePos -> Parser a -> XMLs ->
  Either (P.ParseError (P.Token XMLs) Error) a
-parseXMLs pos p i =
-       snd $ P.runParser' (p <* RNC.none)
+parseXMLs st pos p i =
+       snd $
+       P.runParser' ((`S.evalStateT` st) $ p <* RNC.none)
         P.State
                 { P.stateInput = i
                 , P.statePos = pure $
@@ -161,13 +200,14 @@ parseXMLs pos p i =
                 , P.stateTokensProcessed = 0
                 }
 
--- | @parserXMLs pos p xs@ returns a 'Parser' parsing @xs@ with @p@.
+-- | @parserXMLs st pos p xs@ returns a 'Parser' parsing @xs@ with @p@ from state @st@.
 parserXMLs ::
  DTC.Sym_DTC Parser =>
  Parser a -> XMLs -> Parser a
 parserXMLs p xs = do
        pos <- P.getPosition
-       case parseXMLs pos p xs of
+       st <- S.get
+       case parseXMLs st pos p xs of
         Left (P.TrivialError (posErr:|_) un ex) -> do
                P.setPosition posErr
                P.failure un ex
@@ -204,7 +244,6 @@ sourcePos :: Pos -> Maybe P.SourcePos
 sourcePos (Pos l c) | l>0 && c>0 = Just $ P.SourcePos "" (P.mkPos l) (P.mkPos c)
 sourcePos _ = Nothing
 
--- ** Type 'XMLs'
 instance P.Stream XMLs where
        type Token  XMLs = XML
        type Tokens XMLs = XMLs