Add <URL> when print-only.
[doclang.git] / Language / TCT / Write / XML.hs
index a43772f427e9fcdbb657adbe903a39202ac472e3..2f6ab61d1366a2bbeb5176c547031b9f1b727f68 100644 (file)
@@ -13,6 +13,7 @@ import Data.Eq (Eq(..))
 import Data.Foldable (Foldable(..))
 import Data.Function (($), (.))
 import Data.Functor ((<$>), (<$), ($>))
+import Data.List.NonEmpty (NonEmpty(..))
 import Data.Maybe (Maybe(..))
 import Data.Monoid (Monoid(..))
 import Data.Ord (Ord(..))
@@ -27,7 +28,6 @@ import qualified Data.List as List
 import qualified Data.Sequence as Seq
 import qualified Data.Text.Lazy as TL
 import qualified Language.TCT.Write.Plain as Plain
-import qualified System.FilePath as FP
 
 -- import Language.TCT.Debug
 import Language.TCT.Utils
@@ -43,14 +43,14 @@ import Text.Blaze.XML ()
 --       (eg. about/title may have a title from the section before,
 --       hence outside of about).
 --       Still holding: @'cell_begin' < 'cell_end'@ and 'Cell' nesting.
-document :: Roots -> XMLs
-document doc =
+writeXML :: Roots -> XMLs
+writeXML doc =
        -- (`S.evalState` def) $
        case Seq.viewl doc of
         sec@(Tree (unCell -> NodeHeader HeaderSection{}) _body) :< foot ->
                let (titles, content) = partitionSection sec in
                case Seq.viewl titles of
-                (unTree -> Cell bt et _) :< _ ->
+                (unTree -> Cell st _) :< _ ->
                        xmlify def
                         { inh_titles = titles
                         , inh_figure = True
@@ -59,7 +59,7 @@ document doc =
                        where
                        contentWithAbout =
                                case Seq.findIndexL isAbout content of
-                                Nothing -> Tree (Cell bt et $ NodeHeader $ HeaderColon "about" "") mempty <| content
+                                Nothing -> Tree (Cell st $ NodeHeader $ HeaderColon "about" "") mempty <| content
                                 Just{} -> content
                        isAbout = \case
                         (unTree -> (unCell -> NodeHeader (HeaderColon "about" _wh))) -> True
@@ -71,16 +71,16 @@ partitionSection :: Root -> (Roots, Roots)
 partitionSection (Tree (unCell -> NodeHeader (HeaderSection lvlPar)) body) =
        case Seq.viewl body of
         EmptyL -> mempty
-        title@(unTree -> Cell _bt et NodePara) :< rest ->
+        title@(unTree -> Cell (Span{span_end=et}:|_) NodePara) :< rest ->
                let (subtitles, content) = spanlSubtitles et rest in
                (title <| (subtitles >>= subTrees), content)
                where
                spanlSubtitles ep ts =
                        case Seq.viewl ts of
-                        sub@(unTree -> Cell bs es (NodeHeader (HeaderSection lvlSub))) :< rs
+                        sub@(unTree -> Cell (Span{..}:|_) (NodeHeader (HeaderSection lvlSub))) :< rs
                                | lvlSub <= lvlPar
-                               , pos_line bs - pos_line ep <= 1 ->
-                               let (subs, ts') = spanlSubtitles es rs in
+                               , pos_line span_begin - pos_line ep <= 1 ->
+                               let (subs, ts') = spanlSubtitles span_end rs in
                                (sub <| subs, ts')
                         _ -> (mempty, ts)
         _ -> (mempty, body)
@@ -111,7 +111,7 @@ elementName :: Inh -> Root -> XML
 elementName inh (Tree c ts) = Tree (XmlElem "name" <$ c) $ xmlify inh ts
 
 attributeName :: Inh -> Root -> XML
-attributeName _inh (Tree c ts) = tree0 (XmlAttr "name" (Plain.document ts) <$ c)
+attributeName _inh (Tree c ts) = tree0 (XmlAttr "name" (Plain.writePlain ts) <$ c)
 
 -- * Class 'Xmlify'
 class Xmlify a where
@@ -120,7 +120,7 @@ instance Xmlify Roots where
        xmlify inh roots =
                case Seq.viewl roots of
                 EmptyL -> mempty
-                r@(Tree cr@(Cell _br _er nr) ts) :< rs ->
+                r@(Tree cr@(Cell _sr nr) ts) :< rs ->
                        case nr of
                        ----------------------
                         -- NOTE: HeaderColon becomes parent
@@ -159,16 +159,16 @@ instance Xmlify Roots where
                        ----------------------
                         -- NOTE: detect [some text](http://some.url) or [SomeRef]
                         NodePair PairParen
-                         | Tree (Cell bb eb (NodePair PairBracket)) bracket :< rs' <- Seq.viewl rs ->
+                         | Tree (Cell sb (NodePair PairBracket)) bracket :< rs' <- Seq.viewl rs ->
                                (<| xmlify inh rs') $
                                case bracket of
-                                (toList -> [unTree -> Cell bl el (NodeToken (TokenLink lnk))]) ->
+                                (toList -> [unTree -> Cell sl (NodeToken (TokenLink lnk))]) ->
                                        element "eref" $
-                                               xmlAttrs [Cell bl el ("to",lnk)] <>
+                                               xmlAttrs [Cell sl ("to",lnk)] <>
                                                xmlify inh ts
                                 _ ->
                                        element "rref" $
-                                               xmlAttrs [Cell bb eb ("to",Plain.document bracket)] <>
+                                               xmlAttrs [Cell sb ("to",Plain.writePlain bracket)] <>
                                                xmlify inh ts
                        ----------------------
                         -- NOTE: gather HeaderDash
@@ -196,25 +196,23 @@ instance Xmlify Roots where
                        ----------------------
                         NodePara | para:inh_para <- inh_para inh ->
                                para inh r <|
-                               -- para (() <$ cr) (xmlify inh ts) <|
                                xmlify inh{inh_para} rs
                        ----------------------
                         -- NOTE: context-free Root
                         _ ->
-                               xmlify inh r <>
+                               xmlify inh r `unionXml`
                                xmlify inh rs
                        where
                        element :: XmlName -> XMLs -> XML
                        element n = Tree (XmlElem n <$ cr)
 instance Xmlify Root where
-       xmlify inh tn@(Tree (Cell bn en nod) ts) =
+       xmlify inh tn@(Tree (Cell ss@(sn:|ssn) nod) ts) =
                case nod of
-                NodeGroup -> xmlify inh ts
                ----------------------
                 NodePara ->
                        case inh_para inh of
                         [] -> xmlify inh ts
-                        para:_ -> Seq.singleton $ para inh tn -- para (() <$ cn) $ xmlify inh ts
+                        para:_ -> Seq.singleton $ para inh tn
                ----------------------
                 NodeHeader hdr ->
                        case hdr of
@@ -252,13 +250,13 @@ instance Xmlify Root where
                                        element "about" $
                                                xmlify inh' (inh_titles inh) <>
                                                xmlAttrs attrs <>
-                                               xmlify inh' body
+                                               xmlify inh'{inh_figure=False} body
                                -- NOTE: in <figure> mode, unreserved elements become <figure>
                                 _ | inh_figure inh && n`List.notElem`elems || TL.null n ->
                                        Seq.singleton $
                                        element "figure" $
                                                -- xmlAttrs (setAttr (Cell en en ("type",n)) attrs) <>
-                                               xmlAttrs (attrs `defaultAttr` Cell bn bn ("type", n)) <>
+                                               xmlAttrs (attrs `defaultAttr` Cell (sn{span_end=span_begin sn}:|ssn) ("type", n)) <>
                                                case toList body of
                                                 [Tree0{}] -> xmlify inh'{inh_para = List.repeat elementPara} body
                                                 _         -> xmlify inh'{inh_para = elementTitle : List.repeat elementPara} body
@@ -282,17 +280,22 @@ instance Xmlify Root where
                                         _           -> []
                                 }
                        --
-                        HeaderBar n _wh ->
-                               Seq.singleton $
-                               element "artwork" $
-                                       xmlAttrs (Seq.singleton $ Cell bn bn ("type", n)) <>
-                                       xmlify inh{inh_para=[]} ts
+                        HeaderBar n wh ->
+                               if inh_figure inh && n`List.notElem`elems || TL.null n
+                               then
+                                       Seq.singleton $
+                                       element "artwork" $
+                                               xmlAttrs (Seq.singleton $ Cell (sn{span_end=span_end sn}:|ssn) ("type", n)) <>
+                                               xmlify inh{inh_para=[]} ts
+                               else
+                                       xmlify inh $
+                                               Tree (cell $ NodeHeader $ HeaderColon n wh) ts
                        --
                         HeaderGreat n _wh ->
                                Seq.singleton $
                                let (attrs,body) = partitionAttrs ts in
                                element "quote" $
-                                       xmlAttrs (attrs `defaultAttr` Cell bn bn ("type", n)) <>
+                                       xmlAttrs (attrs `defaultAttr` Cell (sn{span_end=span_end sn}:|ssn) ("type", n)) <>
                                        xmlify inh{inh_para=List.repeat elementPara} body
                        --
                         HeaderEqual n _wh ->
@@ -303,43 +306,30 @@ instance Xmlify Root where
                         HeaderDot n ->
                                Seq.singleton $
                                element "li" $
-                                       xmlAttrs (Seq.singleton $ Cell bn bn{pos_column=pos_column bn + int (TL.length n)} ("name", n)) <>
+                                       let span_end = (span_begin sn){pos_column=pos_column (span_begin sn) + int (TL.length n)} in
+                                       xmlAttrs (Seq.singleton $ Cell (sn{span_end}:|ssn) ("name", n)) <>
                                        xmlify inh ts
                        --
-                        HeaderDash     -> Seq.singleton $ element "li" $ xmlify inh ts
+                        HeaderDash -> Seq.singleton $ element "li" $ xmlify inh ts
                        --
-                        HeaderDashDash -> Seq.singleton $ Tree0 $ cell $ XmlComment $
-                                       -- debug1_ ("TS", ts) $
-                                       -- debug1_ ("RS", (S.evalState (Plain.rackUpLeft ts) Nothing)) $
-                                       Plain.document ts
-                                       -- Plain.text def $ S.evalState (Plain.rackUpLeft ts) Nothing
-                                       {-
-                                       TreeSeq.mapAlsoNode
-                                        (cell1 . unCell)
-                                        (\_k -> fmap $
-                                               TreeSeq.mapAlsoNode
-                                                (cell1 . unCell)
-                                                (\_k' -> cell1 . unCell)) <$> ts
-                                       -}
+                        HeaderDashDash ->
+                               Seq.singleton $ Tree0 $ cell $
+                                       XmlComment $ Plain.writePlain ts
                        --
                         HeaderBrackets ident ->
                                let (attrs,body) = partitionAttrs ts in
                                Seq.singleton $
                                element "reference" $
-                                       xmlAttrs (setAttr (Cell en en ("id",ident)) attrs) <>
+                                       xmlAttrs (setAttr (Cell (sn{span_end=span_end sn}:|ssn) ("id",ident)) attrs) <>
                                        xmlify inh'{inh_para = elementTitle : elementTitle : List.repeat elementPara} body
                                where
                                inh' = inh{inh_figure = False}
                        --
-                        HeaderDotSlash p ->
-                               Seq.singleton $
-                               element "include" $
-                                       xmlAttrs [cell ("href",TL.pack $ FP.replaceExtension p "dtc")] <>
-                                       xmlify inh ts
+                        HeaderDotSlash _file -> xmlify inh ts
                ----------------------
                 NodePair pair ->
                        case pair of
-                        PairBracket | to <- Plain.document ts
+                        PairBracket | to <- Plain.writePlain ts
                                     , TL.all (\c -> Char.isAlphaNum c || Char.isSymbol c) to ->
                                Seq.singleton $
                                element "rref" $
@@ -350,27 +340,24 @@ instance Xmlify Root where
                         PairFrenchquote ->
                                Seq.singleton $
                                element "q" $
-                                       xmlify inh ts
-                               {-
-                               case ts of
-                                (Seq.viewl -> Tree0 (Cell bl el (TokenPlain l)) :< ls) ->
-                                       case Seq.viewr ls of
-                                        m :> Tree0 (Cell br er (TokenPlain r)) ->
+                                       case ts of
+                                        (Seq.viewl -> Tree0 (Cell sl (NodeToken (TokenText l))) :< ls) ->
+                                               case Seq.viewr ls of
+                                                m :> Tree0 (Cell sr (NodeToken (TokenText r))) ->
+                                                       xmlify inh $
+                                                               Tree0 (Cell sl (NodeToken (TokenText (TL.dropWhile Char.isSpace l))))
+                                                                Seq.<|(m Seq.|>Tree0 (Cell sr (NodeToken (TokenText (TL.dropWhileEnd Char.isSpace r)))))
+                                                _ ->
+                                                       xmlify inh $
+                                                               Tree0 (Cell sl (NodeToken (TokenText (TL.dropAround Char.isSpace l)))) Seq.<| ls
+                                        (Seq.viewr -> rs :> Tree0 (Cell sr (NodeToken (TokenText r)))) ->
                                                xmlify inh $
-                                                       Tree0 (Cell bl el (TokenPlain (Text.dropWhile Char.isSpace l)))
-                                                        <|(m|>Tree0 (Cell br er (TokenPlain (Text.dropWhileEnd Char.isSpace r))))
-                                        _ ->
-                                               xmlify inh $
-                                                       Tree0 (Cell bl el (TokenPlain (Text.dropAround Char.isSpace l))) <| ls
-                                (Seq.viewr -> rs :> Tree0 (Cell br er (TokenPlain r))) ->
-                                       xmlify inh $
-                                               rs |> Tree0 (Cell br er (TokenPlain (Text.dropAround Char.isSpace r)))
-                                _ -> xmlify inh ts
-                               -}
+                                                       rs Seq.|> Tree0 (Cell sr (NodeToken (TokenText (TL.dropAround Char.isSpace r))))
+                                        _ -> xmlify inh ts
                         PairHash ->
                                Seq.singleton $
                                element "ref" $
-                                       xmlAttrs [cell ("to",Plain.document ts)]
+                                       xmlAttrs [cell ("to",Plain.writePlain ts)]
                         PairElem name attrs ->
                                Seq.singleton $
                                element (xmlLocalName name) $
@@ -378,13 +365,13 @@ instance Xmlify Root where
                                                cell (xmlLocalName elemAttr_name,elemAttr_value)) <$> attrs) <>
                                        xmlify inh ts
                         _ ->
-                               Seq.singleton (Tree0 $ Cell bn bn' $ XmlText open) `unionXml`
+                               Seq.singleton (Tree0 $ Cell (sn{span_end=bn'}:|ssn) $ XmlText open) `unionXml`
                                xmlify inh ts `unionXml`
-                               Seq.singleton (Tree0 $ Cell en' en $ XmlText close)
+                               Seq.singleton (Tree0 $ Cell (sn{span_begin=en'}:|ssn) $ XmlText close)
                                where
                                (open, close) = pairBorders pair ts
-                               bn' = bn{pos_column=pos_column bn + int (TL.length open)}
-                               en' = en{pos_column=pos_column bn - int (TL.length close)}
+                               bn' = (span_begin sn){pos_column=pos_column (span_begin sn) + int (TL.length open)}
+                               en' = (span_end   sn){pos_column=pos_column (span_end   sn) - int (TL.length close)}
                ----------------------
                 NodeText t -> Seq.singleton $ Tree0 $ cell $ XmlText t
                ----------------------
@@ -401,7 +388,7 @@ instance Xmlify Root where
                                xmlify inh ts
                where
                cell :: a -> Cell a
-               cell = Cell bn en
+               cell = Cell ss
                element :: XmlName -> XMLs -> XML
                element n = Tree (cell $ XmlElem n)
 instance Xmlify (Seq (Cell (XmlName,TL.Text))) where
@@ -425,6 +412,7 @@ elems =
  , "authors"
  , "bcp14"
  , "br"
+ , "break"
  , "call"
  , "city"
  , "code"
@@ -518,14 +506,14 @@ partitionAttrs ts = (attrs,cs)
         _ -> False
        attrs = attr <$> as
        attr = \case
-        Tree (Cell bp ep (NodeHeader (HeaderEqual n _wh))) a ->
-               Cell bp ep (xmlLocalName n, v)
+        Tree (Cell ssn (NodeHeader (HeaderEqual n _wh))) a ->
+               Cell ssn (xmlLocalName n, v)
                where
                v = Plain.text (Plain.setStart a def{Plain.state_escape = False}) a
         _ -> undefined
 
 getAttrId :: Root -> TL.Text
-getAttrId = Plain.document . Seq.singleton
+getAttrId = Plain.writePlain . Seq.singleton
 
 setAttr ::
  Cell (XmlName, TL.Text) ->
@@ -553,10 +541,10 @@ unionXml x y =
        case (Seq.viewr x, Seq.viewl y) of
         (xs :> x0, y0 :< ys) ->
                case (x0,y0) of
-                (  Tree0 (Cell bx ex (XmlText tx))
-                 , Tree0 (Cell by ey (XmlText ty)) ) ->
+                (  Tree0 (Cell ssx@(Span {span_file=fx}:|_sx) (XmlText tx))
+                 , Tree0 (Cell ssy@(Span {span_file=fy}:|_sy) (XmlText ty)) ) | fx == fy ->
                        xs `unionXml`
-                       Seq.singleton (Tree0 $ (XmlText <$>) $ Cell bx ex tx <> Cell by ey ty) `unionXml`
+                       Seq.singleton (Tree0 $ (XmlText <$>) $ Cell ssx tx <> Cell ssy ty) `unionXml`
                        ys
                 _ -> x <> y
         (Seq.EmptyR, _) -> y