git.iko.soy/typeable/xml-lens
on 56dfdeb help sign in
.github/workflows/haskell.ymldeleted−37
since splitsnapshots
unifiedsplit
@@ -1,37 +0,0 @@
1−name: Haskell CI
2−
3−on: [push, pull_request]
4−
5−jobs:
6− build:
7−
8− runs-on: ubuntu-latest
9− strategy:
10− matrix:
11− ghc: [ '8.8.4', '8.10.7', '9.0.1', '9.2.2' ]
12− steps:
13− - uses: actions/checkout@v3
14− - uses: haskell/actions/setup@v1
15− with:
16− ghc-version: ${{ matrix.ghc }}
17− cabal-version: '3.4'
18−
19− - name: cabal Cache
20− uses: actions/cache@v1
21− env:
22− cache-name: cache-cabal
23− with:
24− path: ~/.cabal
25− key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/cabal.project') }}
26− restore-keys: |
27− ${{ runner.os }}-build-${{ env.cache-name }}-
28− ${{ runner.os }}-build-
29− ${{ runner.os }}-
30− - name: Install dependencies
31− run: |
32− cabal update
33− cabal build --only-dependencies --enable-tests --enable-benchmarks all
34− - name: Build
35− run: cabal build --enable-tests --enable-benchmarks all
36− - name: Run tests
37− run: cabal test --enable-tests --enable-benchmarks all
.gitignore−1
@@ -1,4 +1,3 @@
1−dist-newstyle
2#################
1#################
3## Eclipse
2## Eclipse
4#################
3#################
CHANGELOG.mddeleted−10
@@ -1,10 +0,0 @@
1−## 0.3.1
2−
3−* Supported GHC 9
4−
5−## 0.3 (2021/01)
6−
7−* Deprecated `el`
8−* Removed `./` and `entire`
9−
10−
README.md+6−40
@@ -6,45 +6,11 @@ Lenses and traversals for [xml-conduit](http://hackage.haskell.org/package/xml-c
6Example
6Example
7========
7========
8
8
9−```haskell
10−> doc <- Text.XML.readFile def "examples/books.xml"
9+> doc <- Text.XML.readFile def "examples\\books.xml"
11
10
12−> doc ^.. root . named "books" ... named "book" . attributeIs "category" "Textbooks" ... named "title" . text
11+> doc ^.. root . el "books" ./ el "book" ./ el "title" . text
13−["Learn You a Haskell for Great Good!","Programming in Haskell","Real World Haskell"]
12+["Haskell 98 language and libraries: the Revised Report","Learn You a Haskell for Great Good!","Programming in Haskell","Real World Haskell","The Fun of Program
14−
15−> lengthOf ?? doc $ root . named "books" ... named "book"
16−7
17−
18−> doc ^? root . named "books" ... attributeIs "category" "Joke" ... named "title" . text
19−Just "Functional Ikamusume"
13+ming","Types and Programming Languages","Functional Ikamusume"]
20−
21−> doc & root . named "books" ... named "book" ... named "pages" . text <>~ " pages" & renderLBS def & BL.putStrLn
22−```
23
14
24−```xml
15+> doc ^.. root . el "books" ./ el "book" . attributeIs "category" "Textbooks" ./ el "title" . text
25−<?xml version="1.0" encoding="ISO-8859-1"?>
26−<books>
27−<book category="Language and library definition">
28− <title>Haskell 98 language and libraries: the Revised Report</title>
29− <author year="2003">Simon Peyton Jones</author>
30− <pages>272 pages</pages>
31− <price>£45.00</price>
32−</book>
33−<book category="Textbooks">
34− <title>Learn You a Haskell for Great Good!</title>
16+["Learn You a Haskell for Great Good!","Programming in Haskell","Real World Haskell"]
35− <author year="2011">Miran Lipovaca</author>
36− <pages>360 pages</pages>
37−</book>
38−<book category="Textbooks">
39− <title>Programming in Haskell</title>
40− <author year="2007">Graham Hutton</author>
41− <pages>200 pages</pages>
42−</book>
43−…
44−```
45−
46−Tips
47−----
48−
49−* Use [cosmos](http://hackage.haskell.org/package/lens-4.19.2/docs/Control-Lens-Plated.html) to traverse over all children
50−* You can do or-composition of traversals with [failing](http://hackage.haskell.org/package/lens-4.19.2/docs/Control-Lens-Traversal.html#v:failing)
Text/XML/Lens.hs+21−94
@@ -1,107 +1,76 @@
1−{-# LANGUAGE Rank2Types, FlexibleContexts #-}
1+{-# LANGUAGE Rank2Types #-}
2−{-# OPTIONS_GHC -fno-warn-orphans #-}
3-----------------------------------------------------------------------------
2-----------------------------------------------------------------------------
4-- |
3-- |
5-- Module : Text.XML.Lens
4-- Module : Text.XML.Lens
6−-- Copyright : (C) 2015 Fumiaki Kinoshita
5+-- Copyright : (C) 2013 Fumiaki Kinoshita
7-- License : BSD-style (see the file LICENSE)
6-- License : BSD-style (see the file LICENSE)
8--
7--
9-- Maintainer : Fumiaki Kinoshita <fumiexcel@gmail.com>
8-- Maintainer : Fumiaki Kinoshita <fumiexcel@gmail.com>
10−-- Stability : provisional
9+-- Stability : experimental
11-- Portability : non-portable
10-- Portability : non-portable
12--
11--
13----------------------------------------------------------------------------
12----------------------------------------------------------------------------
14module Text.XML.Lens (
13module Text.XML.Lens (
15− -- * Lenses, traversals for 'Element'
14+ -- * Useful traversals inspired by XPath
16− Element(..)
17− , (...)
15+ (./)
18− -- ** Names
19− , name
20− , localName
21 , el
16 , el
22− , ell
23− , named
24− -- ** Attributes
25 , attributeIs
17 , attributeIs
26 , attributeSatisfies
18 , attributeSatisfies
27− , attributeSatisfies'
28− , withoutAttribute
29− , attr
30− , attribute
31− , attrs
32− -- ** Contents
33 , text
19 , text
34 , comment
20 , comment
35− -- ** Children
21+ -- * Lenses, traversals for 'Element'
22+ , name
23+ , attrs
36 , nodes
24 , nodes
25+ , attr
26+ , attribute
37 -- * Prisms for 'Node'
27 -- * Prisms for 'Node'
38− , Node(..)
39 , _Element
28 , _Element
40 , _Content
29 , _Content
41 , AsInstruction(..)
30 , AsInstruction(..)
42 , AsComment(..)
31 , AsComment(..)
43 -- * Lenses for 'Document'
32 -- * Lenses for 'Document'
44− , Document(..)
45 , root
33 , root
46 , prologue
34 , prologue
47 , epilogue
35 , epilogue
48 , doctype
36 , doctype
49 -- * Lenses for 'Name'
37 -- * Lenses for 'Name'
50− , Name(..)
51 , _nameLocalName
38 , _nameLocalName
52 , _nameNamespace
39 , _nameNamespace
53 , _namePrefix
40 , _namePrefix
54− -- * Lenses for 'Instruction'
55− , Instruction(..)
56− , _instructionTarget
57− , _instructionData
58 ) where
41 ) where
59import Text.XML
42import Text.XML
60import Control.Lens
43import Control.Lens
61import Data.Text (Text)
44import Data.Text (Text)
62import Data.Map (Map)
45import Data.Map (Map)
63−import qualified Data.CaseInsensitive as CI
46+import Control.Applicative
64−import Data.Maybe (isNothing)
47+
48+infixr 9 ./
65
49
66prologue :: Lens' Document Prologue
50prologue :: Lens' Document Prologue
67prologue f doc = fmap (\p -> doc { documentPrologue = p} ) $ f $ documentPrologue doc
51prologue f doc = fmap (\p -> doc { documentPrologue = p} ) $ f $ documentPrologue doc
68−{-# INLINE prologue #-}
69
52
70−-- | The root element of the document.
71root :: Lens' Document Element
53root :: Lens' Document Element
72root f doc = fmap (\p -> doc { documentRoot = p} ) $ f $ documentRoot doc
54root f doc = fmap (\p -> doc { documentRoot = p} ) $ f $ documentRoot doc
73−{-# INLINE root #-}
74
55
75epilogue :: Lens' Document [Miscellaneous]
56epilogue :: Lens' Document [Miscellaneous]
76epilogue f doc = fmap (\p -> doc { documentEpilogue = p} ) $ f $ documentEpilogue doc
57epilogue f doc = fmap (\p -> doc { documentEpilogue = p} ) $ f $ documentEpilogue doc
77−{-# INLINE epilogue #-}
78
58
79doctype :: Lens' Prologue (Maybe Doctype)
59doctype :: Lens' Prologue (Maybe Doctype)
80doctype f doc = fmap (\p -> doc { prologueDoctype = p} ) $ f $ prologueDoctype doc
60doctype f doc = fmap (\p -> doc { prologueDoctype = p} ) $ f $ prologueDoctype doc
81−{-# INLINE doctype #-}
82
61
83class AsInstruction t where
62class AsInstruction t where
84 _Instruction :: Prism' t Instruction
63 _Instruction :: Prism' t Instruction
85
64
86−_instructionTarget :: Lens' Instruction Text
87−_instructionTarget f (Instruction t d) = f t <&> \t' -> Instruction t' d
88−{-# INLINE _instructionTarget #-}
89−
90−_instructionData :: Lens' Instruction Text
91−_instructionData f (Instruction t d) = f d <&> \d' -> Instruction t d'
92−{-# INLINE _instructionData #-}
93−
94instance AsInstruction Node where
65instance AsInstruction Node where
95 _Instruction = prism' NodeInstruction $ \s -> case s of
66 _Instruction = prism' NodeInstruction $ \s -> case s of
96 NodeInstruction e -> Just e
67 NodeInstruction e -> Just e
97 _ -> Nothing
68 _ -> Nothing
98− {-# INLINE _Instruction #-}
99
69
100instance AsInstruction Miscellaneous where
70instance AsInstruction Miscellaneous where
101 _Instruction = prism' MiscInstruction $ \s -> case s of
71 _Instruction = prism' MiscInstruction $ \s -> case s of
102 MiscInstruction e -> Just e
72 MiscInstruction e -> Just e
103 _ -> Nothing
73 _ -> Nothing
104− {-# INLINE _Instruction #-}
105
74
106class AsComment t where
75class AsComment t where
107 _Comment :: Prism' t Text
76 _Comment :: Prism' t Text
@@ -110,107 +79,65 @@ instance AsComment Node where
110 _Comment = prism' NodeComment $ \s -> case s of
79 _Comment = prism' NodeComment $ \s -> case s of
111 NodeComment e -> Just e
80 NodeComment e -> Just e
112 _ -> Nothing
81 _ -> Nothing
113− {-# INLINE _Comment #-}
114
82
115instance AsComment Miscellaneous where
83instance AsComment Miscellaneous where
116 _Comment = prism' MiscComment $ \s -> case s of
84 _Comment = prism' MiscComment $ \s -> case s of
117 MiscComment e -> Just e
85 MiscComment e -> Just e
118 _ -> Nothing
86 _ -> Nothing
119− {-# INLINE _Comment #-}
120
87
121_nameLocalName :: Lens' Name Text
88_nameLocalName :: Lens' Name Text
122−_nameLocalName f n = f (nameLocalName n) <&> \x -> n { nameLocalName = x }
89+_nameLocalName f n = fmap (\x -> n { nameLocalName = x }) $ f $ nameLocalName n
123−{-# INLINE _nameLocalName #-}
124
90
125_nameNamespace :: Lens' Name (Maybe Text)
91_nameNamespace :: Lens' Name (Maybe Text)
126−_nameNamespace f n = f (nameNamespace n) <&> \x -> n { nameNamespace = x }
92+_nameNamespace f n = fmap (\x -> n { nameNamespace = x }) $ f $ nameNamespace n
127−{-# INLINE _nameNamespace #-}
128
93
129_namePrefix :: Lens' Name (Maybe Text)
94_namePrefix :: Lens' Name (Maybe Text)
130−_namePrefix f n = f (namePrefix n) <&> \x -> n { namePrefix = x }
95+_namePrefix f n = fmap (\x -> n { namePrefix = x }) $ f $ namePrefix n
131−{-# INLINE _namePrefix #-}
132
96
133_Element :: Prism' Node Element
97_Element :: Prism' Node Element
134_Element = prism' NodeElement $ \s -> case s of
98_Element = prism' NodeElement $ \s -> case s of
135 NodeElement e -> Just e
99 NodeElement e -> Just e
136 _ -> Nothing
100 _ -> Nothing
137−{-# INLINE _Element #-}
138
101
139_Content :: Prism' Node Text
102_Content :: Prism' Node Text
140_Content = prism' NodeContent $ \s -> case s of
103_Content = prism' NodeContent $ \s -> case s of
141 NodeContent e -> Just e
104 NodeContent e -> Just e
142 _ -> Nothing
105 _ -> Nothing
143−{-# INLINE _Content #-}
144
106
145name :: Lens' Element Name
107name :: Lens' Element Name
146−name f e = f (elementName e) <&> \x -> e { elementName = x }
108+name f e = fmap (\x -> e { elementName = x }) $ f $ elementName e
147−{-# INLINE name #-}
148−
149−localName :: Lens' Element Text
150−localName = name . _nameLocalName
151−{-# INLINE localName #-}
152
109
153attrs :: Lens' Element (Map Name Text)
110attrs :: Lens' Element (Map Name Text)
154attrs f e = fmap (\x -> e { elementAttributes = x }) $ f $ elementAttributes e
111attrs f e = fmap (\x -> e { elementAttributes = x }) $ f $ elementAttributes e
155−{-# INLINE attrs #-}
156
112
157nodes :: Lens' Element [Node]
113nodes :: Lens' Element [Node]
158nodes f e = fmap (\x -> e { elementNodes = x }) $ f $ elementNodes e
114nodes f e = fmap (\x -> e { elementNodes = x }) $ f $ elementNodes e
159−{-# INLINE nodes #-}
160
115
161attr :: Name -> Traversal' Element Text
116attr :: Name -> Traversal' Element Text
162attr n = attrs . ix n
117attr n = attrs . ix n
163−{-# INLINE attr #-}
164
118
165attribute :: Name -> Lens' Element (Maybe Text)
119attribute :: Name -> Lens' Element (Maybe Text)
166attribute n = attrs . at n
120attribute n = attrs . at n
167−{-# INLINE attribute #-}
168−
169−-- | Traverse elements which has the specified *local* name (case-insensitive).
170−named :: CI.CI Text -> Traversal' Element Element
171−named n f s
172− | CI.mk (nameLocalName (elementName s)) == n = f s
173− | otherwise = pure s
174−{-# INLINE named #-}
175−
176−-- | Old name for 'named'
177−ell :: Text -> Traversal' Element Element
178−ell n = named $ CI.mk n
179
121
180−-- | Traverse elements which has the specified name.
181el :: Name -> Traversal' Element Element
122el :: Name -> Traversal' Element Element
182el n f s
123el n f s
183 | elementName s == n = f s
124 | elementName s == n = f s
184 | otherwise = pure s
125 | otherwise = pure s
185−{-# DEPRECATED el "Use named instead" #-}
186
126
187attributeSatisfies :: Name -> (Text -> Bool) -> Traversal' Element Element
127attributeSatisfies :: Name -> (Text -> Bool) -> Traversal' Element Element
188−attributeSatisfies n p = attributeSatisfies' n (maybe False p)
128+attributeSatisfies n p = plate . filtered (maybe False p . preview (attrs . ix n))
189−{-# INLINE attributeSatisfies #-}
190−
191−attributeSatisfies' :: Name -> (Maybe Text -> Bool) -> Traversal' Element Element
192−attributeSatisfies' n p = filtered (p . preview (attrs . ix n))
193−{-# INLINE attributeSatisfies' #-}
194−
195−withoutAttribute :: Name -> Traversal' Element Element
196−withoutAttribute n = attributeSatisfies' n isNothing
197−{-# INLINE withoutAttribute #-}
198
129
199attributeIs :: Name -> Text -> Traversal' Element Element
130attributeIs :: Name -> Text -> Traversal' Element Element
200attributeIs n v = attributeSatisfies n (==v)
131attributeIs n v = attributeSatisfies n (==v)
201−{-# INLINE attributeIs #-}
202
132
203−-- | Traverse all contents of the element.
204text :: Traversal' Element Text
133text :: Traversal' Element Text
205text = nodes . traverse . _Content
134text = nodes . traverse . _Content
206−{-# INLINE text #-}
207
135
208−-- | Traverse all comments of the element.
209comment :: Traversal' Element Text
136comment :: Traversal' Element Text
210comment = nodes . traverse . _Comment
137comment = nodes . traverse . _Comment
211−{-# INLINE comment #-}
212
138
213−-- | 'plate' traverses over its sub-elements.
214instance Plated Element where
139instance Plated Element where
215 plate = nodes . traverse . _Element
140 plate = nodes . traverse . _Element
141+
142+(./) :: Plated a => Traversal s t a a -> Traversal a a u v -> Traversal s t u v
216− {-# INLINE plate #-}
143+l ./ m = l . plate . m
cabal.projectdeleted−1
@@ -1 +0,0 @@
1−packages: ./
examples/books.xmldeleted−38
@@ -1,38 +0,0 @@
1−<?xml version="1.0" encoding="ISO-8859-1"?>
2−<books>
3−<book category="Language and library definition">
4− <title>Haskell 98 language and libraries: the Revised Report</title>
5− <author year="2003">Simon Peyton Jones</author>
6− <pages>272</pages>
7− <price>£45.00</price>
8−</book>
9−<book category="Textbooks">
10− <title>Learn You a Haskell for Great Good!</title>
11− <author year="2011">Miran Lipovaca</author>
12− <pages>360</pages>
13−</book>
14−<book category="Textbooks">
15− <title>Programming in Haskell</title>
16− <author year="2007">Graham Hutton</author>
17− <pages>200</pages>
18−</book>
19−<book category="Textbooks">
20− <title>Real World Haskell</title>
21− <author year="2008">Bryan O'Sullivan, Don Stewart, and John Goerzen</author>
22− <pages>700</pages>
23−</book>
24−<book category="TextBooks">
25− <title>The Fun of Programming</title>
26− <author year="2002">Jeremy Gibbons and Oege de Moor</author>
27− <pages>288</pages>
28−</book>
29−<book category="Foundations">
30− <title>Types and Programming Languages</title>
31− <author year="2002">Benjamin C. Pierce</author>
32− <pages>645</pages>
33−</book>
34−<book category="Joke">
35− <title>Functional Ikamusume</title>
36− <author>Team "Referential Transparent Sea Keepers"</author>
37−</book>
38−</books>
stack.yamldeleted−4
@@ -1,4 +0,0 @@
1−resolver: lts-21.3
2−
3−packages:
4−- .
xml-lens.cabal+10−18
@@ -1,20 +1,16 @@
1−cabal-version: 2.4
2name: xml-lens
1name: xml-lens
3−version: 0.3.1
2+version: 0.1
4−synopsis: Lenses, traversals, and prisms for xml-conduit
3+synopsis: Lenses, traversals, prisms for xml-conduit
5−description: This package provides DOM selectors based on lenses and prisms. See README.md for examples
4+description:
6homepage: https://github.com/fumieval/xml-lens
5homepage: https://github.com/fumieval/xml-lens
7−bug-reports: https://github.com/fumieval/xml-lens/issues
8−license: BSD-3-Clause
6+license: BSD3
9license-file: LICENSE
7license-file: LICENSE
10author: Fumiaki Kinoshita
8author: Fumiaki Kinoshita
11maintainer: Fumiaki Kinoshita <fumiexcel@gmail.com>
9maintainer: Fumiaki Kinoshita <fumiexcel@gmail.com>
12−copyright: Copyright (C) 2021 Fumiaki Kinoshita
10+copyright: Copyright (C) 2013 Fumiaki Kinoshita
13−category: XML
11+category: Control
14build-type: Simple
12build-type: Simple
15−extra-source-files:
13+cabal-version: >=1.10
16− README.md
17− CHANGELOG.md
18
14
19source-repository head
15source-repository head
20 type: git
16 type: git
@@ -22,11 +18,7 @@ source-repository head
22
18
23library
19library
24 default-language: Haskell2010
20 default-language: Haskell2010
25− ghc-options: -Wall
21+ ghc-options: -Wall -O
26 exposed-modules: Text.XML.Lens
22 exposed-modules: Text.XML.Lens
23+ -- other-modules:
27− build-depends: base ==4.*
24+ build-depends: base ==4.*, lens >= 3.8 && < 4.2, containers >= 0.4.0 && < 0.6, text == 0.11.*, xml-conduit >= 1.1
28− , lens >= 4.0 && < 5.4
29− , containers >= 0.4.0 && < 0.7
30− , text >= 0.7 && < 1.3 || >= 2 && < 2.2
31− , xml-conduit >= 1.1 && < 1.10
32− , case-insensitive