pro-abstract (empty) → 0.1.0.0
raw patch · 52 files changed
+2361/−0 lines, 52 filesdep +basedep +containersdep +deepseq
Dependencies added: base, containers, deepseq, hashable, hedgehog, neat-interpolation, optics-core, pro-abstract, text
Files
- LICENSE +373/−0
- library/pro-abstract-prelude/Containers.hs +87/−0
- library/pro-abstract-prelude/Prelude.hs +21/−0
- library/pro-abstract/ProAbstract.hs +253/−0
- library/pro-abstract/ProAbstract/Annotation.hs +9/−0
- library/pro-abstract/ProAbstract/Annotation/AnnotationFamily.hs +5/−0
- library/pro-abstract/ProAbstract/Annotation/HasAnnotation.hs +11/−0
- library/pro-abstract/ProAbstract/Annotation/HasManyAnnotations.hs +8/−0
- library/pro-abstract/ProAbstract/Classes.hs +40/−0
- library/pro-abstract/ProAbstract/Content.hs +9/−0
- library/pro-abstract/ProAbstract/Content/ContentFamily.hs +5/−0
- library/pro-abstract/ProAbstract/Content/ContentsFamily.hs +5/−0
- library/pro-abstract/ProAbstract/Content/HasContent.hs +10/−0
- library/pro-abstract/ProAbstract/Content/HasContents.hs +10/−0
- library/pro-abstract/ProAbstract/Datatypes.hs +28/−0
- library/pro-abstract/ProAbstract/Families.hs +12/−0
- library/pro-abstract/ProAbstract/Metadata.hs +9/−0
- library/pro-abstract/ProAbstract/Metadata/HasManyMetadata.hs +8/−0
- library/pro-abstract/ProAbstract/Metadata/HasMetadata.hs +13/−0
- library/pro-abstract/ProAbstract/Metadata/HasMetadataOptics.hs +23/−0
- library/pro-abstract/ProAbstract/Metadata/MetadataOptics.hs +21/−0
- library/pro-abstract/ProAbstract/Metadata/MetadataType.hs +20/−0
- library/pro-abstract/ProAbstract/Optics.hs +37/−0
- library/pro-abstract/ProAbstract/Structure.hs +43/−0
- library/pro-abstract/ProAbstract/Structure/Block.hs +237/−0
- library/pro-abstract/ProAbstract/Structure/BlockTag.hs +89/−0
- library/pro-abstract/ProAbstract/Structure/CanBePlain.hs +8/−0
- library/pro-abstract/ProAbstract/Structure/CanFork.hs +8/−0
- library/pro-abstract/ProAbstract/Structure/Document.hs +66/−0
- library/pro-abstract/ProAbstract/Structure/Fork.hs +5/−0
- library/pro-abstract/ProAbstract/Structure/Fragment.hs +23/−0
- library/pro-abstract/ProAbstract/Structure/HasManyParagraphs.hs +9/−0
- library/pro-abstract/ProAbstract/Structure/HasManyPlainBlocks.hs +9/−0
- library/pro-abstract/ProAbstract/Structure/HasManyPlainInlines.hs +9/−0
- library/pro-abstract/ProAbstract/Structure/Inline.hs +217/−0
- library/pro-abstract/ProAbstract/Structure/Paragraph.hs +50/−0
- library/pro-abstract/ProAbstract/Structure/Plain.hs +5/−0
- library/pro-abstract/ProAbstract/Structure/PlainBlock.hs +71/−0
- library/pro-abstract/ProAbstract/Tag.hs +14/−0
- library/pro-abstract/ProAbstract/Tag/HasManyTags.hs +33/−0
- library/pro-abstract/ProAbstract/Tag/HasTag.hs +14/−0
- library/pro-abstract/ProAbstract/Tag/HasTagOptics.hs +10/−0
- library/pro-abstract/ProAbstract/Tag/TagOptics.hs +6/−0
- library/pro-abstract/ProAbstract/Tag/TagType.hs +24/−0
- library/pro-abstract/ProAbstract/Tag/TaggedFamily.hs +5/−0
- library/pro-abstract/ProAbstract/Tagless.hs +8/−0
- library/pro-abstract/ProAbstract/Tagless/CanBeTagless.hs +56/−0
- library/pro-abstract/ProAbstract/Tagless/CanHaveTaglessContent.hs +49/−0
- library/pro-abstract/ProAbstract/Tagless/KindOfText.hs +9/−0
- library/pro-abstract/ProAbstract/Types.hs +27/−0
- pro-abstract.cabal +144/−0
- test-suite/test-pro-abstract/Main.hs +96/−0
+ LICENSE view
@@ -0,0 +1,373 @@+Mozilla Public License Version 2.0+==================================++1. Definitions+--------------++1.1. "Contributor"+ means each individual or legal entity that creates, contributes to+ the creation of, or owns Covered Software.++1.2. "Contributor Version"+ means the combination of the Contributions of others (if any) used+ by a Contributor and that particular Contributor's Contribution.++1.3. "Contribution"+ means Covered Software of a particular Contributor.++1.4. "Covered Software"+ means Source Code Form to which the initial Contributor has attached+ the notice in Exhibit A, the Executable Form of such Source Code+ Form, and Modifications of such Source Code Form, in each case+ including portions thereof.++1.5. "Incompatible With Secondary Licenses"+ means++ (a) that the initial Contributor has attached the notice described+ in Exhibit B to the Covered Software; or++ (b) that the Covered Software was made available under the terms of+ version 1.1 or earlier of the License, but not also under the+ terms of a Secondary License.++1.6. "Executable Form"+ means any form of the work other than Source Code Form.++1.7. "Larger Work"+ means a work that combines Covered Software with other material, in+ a separate file or files, that is not Covered Software.++1.8. "License"+ means this document.++1.9. "Licensable"+ means having the right to grant, to the maximum extent possible,+ whether at the time of the initial grant or subsequently, any and+ all of the rights conveyed by this License.++1.10. "Modifications"+ means any of the following:++ (a) any file in Source Code Form that results from an addition to,+ deletion from, or modification of the contents of Covered+ Software; or++ (b) any new file in Source Code Form that contains any Covered+ Software.++1.11. "Patent Claims" of a Contributor+ means any patent claim(s), including without limitation, method,+ process, and apparatus claims, in any patent Licensable by such+ Contributor that would be infringed, but for the grant of the+ License, by the making, using, selling, offering for sale, having+ made, import, or transfer of either its Contributions or its+ Contributor Version.++1.12. "Secondary License"+ means either the GNU General Public License, Version 2.0, the GNU+ Lesser General Public License, Version 2.1, the GNU Affero General+ Public License, Version 3.0, or any later versions of those+ licenses.++1.13. "Source Code Form"+ means the form of the work preferred for making modifications.++1.14. "You" (or "Your")+ means an individual or a legal entity exercising rights under this+ License. For legal entities, "You" includes any entity that+ controls, is controlled by, or is under common control with You. For+ purposes of this definition, "control" means (a) the power, direct+ or indirect, to cause the direction or management of such entity,+ whether by contract or otherwise, or (b) ownership of more than+ fifty percent (50%) of the outstanding shares or beneficial+ ownership of such entity.++2. License Grants and Conditions+--------------------------------++2.1. Grants++Each Contributor hereby grants You a world-wide, royalty-free,+non-exclusive license:++(a) under intellectual property rights (other than patent or trademark)+ Licensable by such Contributor to use, reproduce, make available,+ modify, display, perform, distribute, and otherwise exploit its+ Contributions, either on an unmodified basis, with Modifications, or+ as part of a Larger Work; and++(b) under Patent Claims of such Contributor to make, use, sell, offer+ for sale, have made, import, and otherwise transfer either its+ Contributions or its Contributor Version.++2.2. Effective Date++The licenses granted in Section 2.1 with respect to any Contribution+become effective for each Contribution on the date the Contributor first+distributes such Contribution.++2.3. Limitations on Grant Scope++The licenses granted in this Section 2 are the only rights granted under+this License. No additional rights or licenses will be implied from the+distribution or licensing of Covered Software under this License.+Notwithstanding Section 2.1(b) above, no patent license is granted by a+Contributor:++(a) for any code that a Contributor has removed from Covered Software;+ or++(b) for infringements caused by: (i) Your and any other third party's+ modifications of Covered Software, or (ii) the combination of its+ Contributions with other software (except as part of its Contributor+ Version); or++(c) under Patent Claims infringed by Covered Software in the absence of+ its Contributions.++This License does not grant any rights in the trademarks, service marks,+or logos of any Contributor (except as may be necessary to comply with+the notice requirements in Section 3.4).++2.4. Subsequent Licenses++No Contributor makes additional grants as a result of Your choice to+distribute the Covered Software under a subsequent version of this+License (see Section 10.2) or under the terms of a Secondary License (if+permitted under the terms of Section 3.3).++2.5. Representation++Each Contributor represents that the Contributor believes its+Contributions are its original creation(s) or it has sufficient rights+to grant the rights to its Contributions conveyed by this License.++2.6. Fair Use++This License is not intended to limit any rights You have under+applicable copyright doctrines of fair use, fair dealing, or other+equivalents.++2.7. Conditions++Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted+in Section 2.1.++3. Responsibilities+-------------------++3.1. Distribution of Source Form++All distribution of Covered Software in Source Code Form, including any+Modifications that You create or to which You contribute, must be under+the terms of this License. You must inform recipients that the Source+Code Form of the Covered Software is governed by the terms of this+License, and how they can obtain a copy of this License. You may not+attempt to alter or restrict the recipients' rights in the Source Code+Form.++3.2. Distribution of Executable Form++If You distribute Covered Software in Executable Form then:++(a) such Covered Software must also be made available in Source Code+ Form, as described in Section 3.1, and You must inform recipients of+ the Executable Form how they can obtain a copy of such Source Code+ Form by reasonable means in a timely manner, at a charge no more+ than the cost of distribution to the recipient; and++(b) You may distribute such Executable Form under the terms of this+ License, or sublicense it under different terms, provided that the+ license for the Executable Form does not attempt to limit or alter+ the recipients' rights in the Source Code Form under this License.++3.3. Distribution of a Larger Work++You may create and distribute a Larger Work under terms of Your choice,+provided that You also comply with the requirements of this License for+the Covered Software. If the Larger Work is a combination of Covered+Software with a work governed by one or more Secondary Licenses, and the+Covered Software is not Incompatible With Secondary Licenses, this+License permits You to additionally distribute such Covered Software+under the terms of such Secondary License(s), so that the recipient of+the Larger Work may, at their option, further distribute the Covered+Software under the terms of either this License or such Secondary+License(s).++3.4. Notices++You may not remove or alter the substance of any license notices+(including copyright notices, patent notices, disclaimers of warranty,+or limitations of liability) contained within the Source Code Form of+the Covered Software, except that You may alter any license notices to+the extent required to remedy known factual inaccuracies.++3.5. Application of Additional Terms++You may choose to offer, and to charge a fee for, warranty, support,+indemnity or liability obligations to one or more recipients of Covered+Software. However, You may do so only on Your own behalf, and not on+behalf of any Contributor. You must make it absolutely clear that any+such warranty, support, indemnity, or liability obligation is offered by+You alone, and You hereby agree to indemnify every Contributor for any+liability incurred by such Contributor as a result of warranty, support,+indemnity or liability terms You offer. You may include additional+disclaimers of warranty and limitations of liability specific to any+jurisdiction.++4. Inability to Comply Due to Statute or Regulation+---------------------------------------------------++If it is impossible for You to comply with any of the terms of this+License with respect to some or all of the Covered Software due to+statute, judicial order, or regulation then You must: (a) comply with+the terms of this License to the maximum extent possible; and (b)+describe the limitations and the code they affect. Such description must+be placed in a text file included with all distributions of the Covered+Software under this License. Except to the extent prohibited by statute+or regulation, such description must be sufficiently detailed for a+recipient of ordinary skill to be able to understand it.++5. Termination+--------------++5.1. The rights granted under this License will terminate automatically+if You fail to comply with any of its terms. However, if You become+compliant, then the rights granted under this License from a particular+Contributor are reinstated (a) provisionally, unless and until such+Contributor explicitly and finally terminates Your grants, and (b) on an+ongoing basis, if such Contributor fails to notify You of the+non-compliance by some reasonable means prior to 60 days after You have+come back into compliance. Moreover, Your grants from a particular+Contributor are reinstated on an ongoing basis if such Contributor+notifies You of the non-compliance by some reasonable means, this is the+first time You have received notice of non-compliance with this License+from such Contributor, and You become compliant prior to 30 days after+Your receipt of the notice.++5.2. If You initiate litigation against any entity by asserting a patent+infringement claim (excluding declaratory judgment actions,+counter-claims, and cross-claims) alleging that a Contributor Version+directly or indirectly infringes any patent, then the rights granted to+You by any and all Contributors for the Covered Software under Section+2.1 of this License shall terminate.++5.3. In the event of termination under Sections 5.1 or 5.2 above, all+end user license agreements (excluding distributors and resellers) which+have been validly granted by You or Your distributors under this License+prior to termination shall survive termination.++************************************************************************+* *+* 6. Disclaimer of Warranty *+* ------------------------- *+* *+* Covered Software is provided under this License on an "as is" *+* basis, without warranty of any kind, either expressed, implied, or *+* statutory, including, without limitation, warranties that the *+* Covered Software is free of defects, merchantable, fit for a *+* particular purpose or non-infringing. The entire risk as to the *+* quality and performance of the Covered Software is with You. *+* Should any Covered Software prove defective in any respect, You *+* (not any Contributor) assume the cost of any necessary servicing, *+* repair, or correction. This disclaimer of warranty constitutes an *+* essential part of this License. No use of any Covered Software is *+* authorized under this License except under this disclaimer. *+* *+************************************************************************++************************************************************************+* *+* 7. Limitation of Liability *+* -------------------------- *+* *+* Under no circumstances and under no legal theory, whether tort *+* (including negligence), contract, or otherwise, shall any *+* Contributor, or anyone who distributes Covered Software as *+* permitted above, be liable to You for any direct, indirect, *+* special, incidental, or consequential damages of any character *+* including, without limitation, damages for lost profits, loss of *+* goodwill, work stoppage, computer failure or malfunction, or any *+* and all other commercial damages or losses, even if such party *+* shall have been informed of the possibility of such damages. This *+* limitation of liability shall not apply to liability for death or *+* personal injury resulting from such party's negligence to the *+* extent applicable law prohibits such limitation. Some *+* jurisdictions do not allow the exclusion or limitation of *+* incidental or consequential damages, so this exclusion and *+* limitation may not apply to You. *+* *+************************************************************************++8. Litigation+-------------++Any litigation relating to this License may be brought only in the+courts of a jurisdiction where the defendant maintains its principal+place of business and such litigation shall be governed by laws of that+jurisdiction, without reference to its conflict-of-law provisions.+Nothing in this Section shall prevent a party's ability to bring+cross-claims or counter-claims.++9. Miscellaneous+----------------++This License represents the complete agreement concerning the subject+matter hereof. If any provision of this License is held to be+unenforceable, such provision shall be reformed only to the extent+necessary to make it enforceable. Any law or regulation which provides+that the language of a contract shall be construed against the drafter+shall not be used to construe this License against a Contributor.++10. Versions of the License+---------------------------++10.1. New Versions++Mozilla Foundation is the license steward. Except as provided in Section+10.3, no one other than the license steward has the right to modify or+publish new versions of this License. Each version will be given a+distinguishing version number.++10.2. Effect of New Versions++You may distribute the Covered Software under the terms of the version+of the License under which You originally received the Covered Software,+or under the terms of any subsequent version published by the license+steward.++10.3. Modified Versions++If you create software not governed by this License, and you want to+create a new license for such software, you may create and use a+modified version of this License if you rename the license and remove+any references to the name of the license steward (except to note that+such modified license differs from this License).++10.4. Distributing Source Code Form that is Incompatible With Secondary+Licenses++If You choose to distribute Source Code Form that is Incompatible With+Secondary Licenses under the terms of this version of the License, the+notice described in Exhibit B of this License must be attached.++Exhibit A - Source Code Form License Notice+-------------------------------------------++ This Source Code Form is subject to the terms of the Mozilla Public+ License, v. 2.0. If a copy of the MPL was not distributed with this+ file, You can obtain one at http://mozilla.org/MPL/2.0/.++If it is not possible or desirable to put the notice in a particular+file, then You may include the notice in a location (such as a LICENSE+file in a relevant directory) where a recipient would be likely to look+for such a notice.++You may add additional accurate notices of copyright ownership.++Exhibit B - "Incompatible With Secondary Licenses" Notice+---------------------------------------------------------++ This Source Code Form is "Incompatible With Secondary Licenses", as+ defined by the Mozilla Public License, v. 2.0.
+ library/pro-abstract-prelude/Containers.hs view
@@ -0,0 +1,87 @@+module Containers where++import BasePrelude (Applicative, Bool, Foldable, Maybe (..), Ord, Semigroup, maybe, pure, (.), (<*>), (<>))+import Data.Foldable (fold, toList)+import Data.Function (fix, id)+import Optics.Core (Prism', prism')++import Data.Sequence (Seq (..))+import qualified Data.Sequence as Seq++import Data.Map.Strict (Map)+import qualified Data.Map.Strict as Map++import Data.Set (Set)+import qualified Data.Set as Set++import qualified Data.Text as Text++mapLookup :: Ord k => k -> Map k a -> Maybe a+mapLookup = Map.lookup++mapDelete :: Ord k => k -> Map k a -> Map k a+mapDelete = Map.delete++mapInsert :: Ord k => k -> a -> Map k a -> Map k a+mapInsert = Map.insert++setMember :: Ord a => a -> Set a -> Bool+setMember = Set.member++setInsert :: Ord a => a -> Set a -> Set a+setInsert = Set.insert++setDelete :: Ord a => a -> Set a -> Set a+setDelete = Set.delete++seqWither :: Applicative f => (a -> f (Maybe b)) -> Seq a -> f (Seq b)+seqWither f = fix \r -> seqReduceR (pure Seq.Empty) \x xs -> pure seqConsMaybe <*> f x <*> r xs++seqReduceR :: b -> (a -> Seq a -> b) -> Seq a -> b+seqReduceR z f = \case{ Seq.Empty -> z; (Seq.:<|) x xs -> f x xs }++seqConsMaybe :: Maybe a -> Seq a -> Seq a+seqConsMaybe = maybe id (Seq.:<|)++seqFromMaybe :: Maybe a -> Seq a+seqFromMaybe = maybe Seq.empty Seq.singleton++seqSingleton :: Prism' (Seq a) a+seqSingleton = prism' Seq.singleton f+ where+ f = \case+ (x Seq.:<| Seq.Empty) -> Just x+ _ -> Nothing++seqAtMostOne :: Prism' (Seq a) (Maybe a)+seqAtMostOne = prism' (maybe Seq.empty Seq.singleton) f+ where+ f = \case+ Seq.Empty -> Just Nothing+ (x Seq.:<| Seq.Empty) -> Just (Just x)+ _ -> Nothing++seqToList :: Seq a -> [a]+seqToList = toList++seqConcat :: Seq (Seq a) -> Seq a+seqConcat = fold++textEmpty :: Text.Text+textEmpty = Text.empty++textConcat :: Foldable t => t Text.Text -> Text.Text+textConcat = Text.concat . toList++seqAppendAndConcat :: Semigroup a => Seq a -> Seq a -> Seq a+seqAppendAndConcat x Empty = x+seqAppendAndConcat Empty x = x+seqAppendAndConcat (xs :|> x) (y :<| ys) = xs <> Seq.singleton (x <> y) <> ys++seqAppendAndConcatWith :: (a -> a -> Maybe a) -> Seq a -> Seq a -> Seq a+seqAppendAndConcatWith _ x Empty = x+seqAppendAndConcatWith _ Empty x = x+seqAppendAndConcatWith f a@(xs :|> x) b@(y :<| ys) =+ case f x y of+ Nothing -> a <> b+ Just z -> xs <> Seq.singleton z <> ys
+ library/pro-abstract-prelude/Prelude.hs view
@@ -0,0 +1,21 @@+module Prelude (module X) where++import Control.DeepSeq as X (NFData)+import Data.Functor as X ((<&>))+import Data.Functor.Identity as X (Identity (Identity), runIdentity)+import Data.Hashable as X (Hashable)+import Data.Kind as X (Type)+import Data.Map as X (Map)+import Data.Maybe as X (fromMaybe, mapMaybe)+import Data.Sequence as X (Seq)+import Data.Set as X (Set)+import Data.Text as X (Text)+import GHC.Exts as X (IsList (..))+import GHC.Generics as X (Generic)++import Containers as X++import BasePrelude as X (Applicative, Bool, Either (..), Eq, Foldable, Functor, Maybe (..), Monad, Monoid (mempty), Ord, Semigroup (..), Show, Traversable, const, either, fmap, maybe, not, pure, traverse, ($), (.), (<$>), (<*>), (=<<), (>>=))++import Optics.Core as X (A_Fold, A_Getter, A_Lens, A_Traversal, AffineFold, AffineTraversal, AffineTraversal', An_AffineFold, An_AffineTraversal, An_Iso, Is, Iso, Iso', JoinKinds, Lens, Lens', NoIx, Optic, Optic', OpticKind, Prism', Traversal, Traversal', _Just, _Left, _Right, adjoin, afailing, afolding, atraversal, castOptic, coerced, equality, lens, matching, over, preview, prism', re, review, set, simple, to, traversalVL, traverseOf, traversed, view, (%), JoinKinds)+import Optics.Empty.Core as X (_Empty, pattern Empty)
+ library/pro-abstract/ProAbstract.hs view
@@ -0,0 +1,253 @@+{- |+Copyright: © 2020 James Alexander Feldman-Crough+ © 2022 Mission Valley Software LLC+License: MPL-2.0+++=== Document++/Document/ is the root of the tree.++- 'Document' = ('metadata' : 'Metadata') × ('content' : 'Blocks')+++=== Tagged nodes++/Tagged/ nodes are branch points within a document.++- 'Tag' = ('name' : 'Text') × ('metadata' : 'Metadata') × ('annotation' : 'Annotation')++- 'Tagged' x = ('tag' : 'Tag') × ('content' : x)++'Tagged' is a data family, where the type parameter corresponds to the type of content under the tag. There are three instances of this family:++- 'Tagged' 'Blocks'+- 'Tagged' 'PlainBlock'+- 'Tagged' 'Lines'++Optics:++- 'tag' targets the tag at a node; it is either a prism or an affine traversal, depending on the node type.+- The 'allTags' traversal targets every tag at and below a node.+- The 'allBlockTags' and 'allInlineTags' also target tags at or below a node, but are limited to tags at the block or inline level, respectively.+- Since a tag has metadata, all of the optics for targeting parts of metadata (e.g. 'atSetting' and 'hasProperty') are also available on 'Tag' and on 'Tagged' nodes.++Operations for altering tags and/or removing tagged nodes in bulk:++ - Pure: 'mapMaybeTags', 'mapMaybeBlockTags', 'mapMaybeInlineTags'+ - Monadic: 'witherTags', 'witherBlockTags', 'witherInlineTags'+++=== The Block level++/Block-level/ content is everything that appears below the document level and above the paragraph level.++- 'Block' = ('fork' : 'Tagged' 'Blocks') ∪ ('plain' : 'Tagged' 'PlainBlock') ∪ ('paragraph' : 'Paragraph')++There are three kinds of block:++- /Fork/ blocks contain more blocks.++ * 'Tagged' 'Blocks' = ('tag' : 'Tag') × ('contents' : 'Block')++- /Plain/ blocks contain text.++ * 'Tagged' 'PlainBlock' = ('tag' : 'Tag') × ('content' : 'PlainBlock')+ * 'PlainBlock' = ('contents' : 'Fragment') × ('annotation' : 'Annotation')++- /Paragraphs/ contain inline content.++ * 'Paragraph' = ('content' : 'Lines') × ('annotation' : 'Annotation')++Unenforced guideline: The 'Lines' of a 'Paragraph' should contain at least one 'Line'.+++=== BlockTag++A /BlockTag/ is a non-paragraph Block.++- 'BlockTag' = ('fork' : 'Tagged' 'Blocks') ∪ ('plain' : 'Tagged' 'PlainBlock')++The Block type can be described in terms of BlockTag as:++- 'Block' = ('blockTag' : 'BlockTag') ∪ ('paragraph' : 'Paragraph')++Example: @'blockTag' % 'Optics.Core.filtered' (\x -> 'Optics.Core.view' 'name' x == "h1")@ is an affine fold that targets blocks with a tag name of "h1".+++=== The Inline level++/Inline-level/ content is everything below the paragraph level.++Inline content is grouped into lines; we specify no particular semantics of line breaks but suggest that a typical consumer of 'Lines' will fold them together with a single space character interspersed between the lines.++- 'Inline' = ('fork' : 'Tagged' 'Lines') ∪ ('plain' : 'Fragment')++There are two kinds of inline:++- /Fork/ inlines contain more inlines.++ * 'Tagged' 'Lines' = ('tag' : 'Tag') × ('content' : 'Lines')+ * 'Lines' = ('contents' : 'Line')+ * 'Line' = ('content' : 'Seq' 'Inline') × ('annotation' : 'Annotation')++- /Plain/ inlines contain text.++Unenforced guideline: Each 'Line' should contain at least one 'Inline'.+++=== Fragments++/Fragments/ are all the little scraps of text that serve as the leaves of the document tree.++- 'Fragment' = ('content' : 'Text') × ('annotation' : 'Annotation')++A fragment may appear at the inline level as a plain 'Inline', or at the block level as a line of a 'PlainBlock'.++Unenforced guidelines: Fragment text should be non-empty, and it should not contain any line break characters.+++=== Metadata++Documents and tags both have /metadata/.++- 'Metadata' = ('properties' : 'Set' 'Text') × ('settings' : 'Map' 'Text' 'Text')++Optics:++- 'metadata' targets the metadata of a node; it is either a prism or an affine traversal, depending on the node type.+- 'atSetting' and 'hasProperty' target specific parts of metadata by name.+- The 'allMetadata' traversal targets every metadata at and under a node.+++=== Content++The /content/ of a node is whatever is nested directly under it in the document tree. The 'content' lens is overloaded via the 'Content' type family and 'HasContent' class.++The /contents/ of a node is the type of sequence element most directly nested under it. The 'contents' lens is via the 'Contents' type family and 'HasContents' class.++List of nodes and their content types:+++-----------------------+-----------------------+-----------------------++| __x__ | __Content x__ | __Contents x__ |++-----------------------+-----------------------+-----------------------++| 'Document' | 'Blocks' | 'Block' |++-----------------------+-----------------------+-----------------------++| 'Blocks' | — | 'Block' |++-----------------------+-----------------------+-----------------------++| 'Paragraph' | 'Lines' | 'Line' |++-----------------------+-----------------------+-----------------------++| 'Lines' | — | 'Line' |++-----------------------+-----------------------+-----------------------++| 'Line' | — | 'Inline' |++-----------------------+-----------------------+-----------------------++| 'PlainBlock' | — | 'Fragment' |++-----------------------+-----------------------+-----------------------++| 'Tagged' y | y | 'Contents' y |++-----------------------+-----------------------+-----------------------++| 'Fragment' | 'Text' | — |++-----------------------+-----------------------+-----------------------+++'HasContent' and 'HasContents' have type aliases 'HasContents'' and 'HasContents'' respectively for types that only support simple optics.+++=== Fork and plain++At both the block and inline level, a node may be a /fork/ that contains a sequence of more content at the same level, and a node may be /plain/ node that just contains text.++The 'fork' prism is overloaded via the 'Fork' type family and 'CanFork' class. List of nodes and their fork types:+++-----------------------+-----------------------++| __x__ | __Fork x__ |++-----------------------+-----------------------++| 'Block' | 'Tagged' 'Blocks' |++-----------------------+-----------------------++| 'Inline' | 'Tagged' 'Lines' |++-----------------------+-----------------------+++The 'plain' prism is overloaded via the 'Plain' type family and 'CanBePlain' class. List of nodes and their plain types:+++-----------------------+-----------------------++| __x__ | __Plain x__ |++-----------------------+-----------------------++| 'Block' | 'Tagged' 'PlainBlock' |++-----------------------+-----------------------++| 'Inline' | 'Fragment' |++-----------------------+-----------------------+++('Block' also has a third prism, 'paragraph', which is neither fork nor plain.)+++=== Annotation++An /annotation/ is attached to every 'Tag', 'PlainBlock', 'Paragraph', 'Line', and 'Fragment'. The 'Annotation' type may be anything, but its original purpose was to map each component of a document to the location where it appeared in a text file.++Optics:++- The 'annotation' lens targets a single annotation at a node+- The 'allAnnotations' traversal targets every annotation at and under a node.+++=== Modules++The ProAbstract module provides everything in the pro-abstract package. There are also some smaller collections of reëxports.++Organized by topic:++- "ProAbstract.Annotation"+- "ProAbstract.Content"+- "ProAbstract.Metadata"+- "ProAbstract.Structure"+- "ProAbstract.Tag"+- "ProAbstract.Tagless"++Organized by kind of thing:++- "ProAbstract.Types" — The essential types, exported abstractly. Includes type families and data families.+- "ProAbstract.Optics" — Lenses, prisms, traversals, etc. Many of these are class methods, but are exported here without their classes.+- "ProAbstract.Datatypes" — Datatypes including with their constructors and record fields+- "ProAbstract.Families" — Type families and data families.+- "ProAbstract.Classes" — Typeclasses, mostly for the polymorphic optics.++-}+module ProAbstract+ (+ {- * Document -} Document (..),++ {- * Blocks -} Block (..), Blocks (..),+ {- ** Paragraphs -} Paragraph (..), HasManyParagraphs (..),+ {- ** Tag blocks -} BlockTag (..), blockTag,++ {- * Lines -} Inline (..), Line (..), Lines (..),+ {- ** Plain text -} Fragment (..), PlainBlock (..),+ HasManyPlainInlines (..), HasManyPlainBlocks (..),++ {- * Tags -} Tag (..), Tagged (..), name, HasTag (..),+ {- ** Traversal -} HasManyTags (..), HasManyBlockTags (..),+ {- ** Withering -} HasWitherableTags (..),+ HasWitherableInlineTags (..), HasWitherableBlockTags (..),++ {- * Prisms -}+ {- ** Plain -} Plain, CanBePlain (..),+ {- ** Fork -} Fork, CanFork (..),+ {- ** Paragraph -} paragraph,++ {- * Metadata -} Metadata (..), HasMetadata (..), HasManyMetadata (..),+ {- ** Properties -} properties, hasProperty,+ {- ** Settings -} settings, atSetting,++ {- * Content -} Content, HasContent (..), HasContent',+ {- ** Contents -} Contents, HasContents (..), HasContents',++ {- * Annotation -} Annotation, HasAnnotation (..), HasAnnotation',+ HasManyAnnotations (..),++ {- * Tagless content -} CanBeTagless (..), CanHaveTaglessContent (..),+ KindOfText (..)++ ) where++import ProAbstract.Classes+import ProAbstract.Datatypes+import ProAbstract.Optics+import ProAbstract.Types
+ library/pro-abstract/ProAbstract/Annotation.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Annotation+ ( Annotation+ , HasAnnotation (..), HasAnnotation'+ , HasManyAnnotations (..)+ ) where++import ProAbstract.Annotation.AnnotationFamily+import ProAbstract.Annotation.HasAnnotation+import ProAbstract.Annotation.HasManyAnnotations
+ library/pro-abstract/ProAbstract/Annotation/AnnotationFamily.hs view
@@ -0,0 +1,5 @@+module ProAbstract.Annotation.AnnotationFamily+ ( Annotation+ ) where++type family Annotation x
+ library/pro-abstract/ProAbstract/Annotation/HasAnnotation.hs view
@@ -0,0 +1,11 @@+module ProAbstract.Annotation.HasAnnotation+ ( HasAnnotation (..)+ , HasAnnotation'+ ) where++import ProAbstract.Annotation.AnnotationFamily++class HasAnnotation x x' where+ annotation :: Lens x x' (Annotation x) (Annotation x')++type HasAnnotation' x = HasAnnotation x x
+ library/pro-abstract/ProAbstract/Annotation/HasManyAnnotations.hs view
@@ -0,0 +1,8 @@+module ProAbstract.Annotation.HasManyAnnotations+ ( HasManyAnnotations (..)+ ) where++import ProAbstract.Annotation.AnnotationFamily++class HasManyAnnotations x x' where+ allAnnotations :: Traversal x x' (Annotation x) (Annotation x')
+ library/pro-abstract/ProAbstract/Classes.hs view
@@ -0,0 +1,40 @@+module ProAbstract.Classes+ (+ -- * Block and inline prisms+ CanBePlain (..), CanFork (..)++ -- * Plaintext traversals+ , HasManyPlainBlocks (..), HasManyPlainInlines (..)++ -- * Annotation+ , HasAnnotation (..), HasAnnotation', HasManyAnnotations (..)++ -- * Content+ , HasContent (..), HasContent', HasContents (..), HasContents'++ -- * Metadata+ , HasMetadata (..), HasManyMetadata (..)++ -- * Tags+ , HasTag (..)++ -- ** Traversal+ , HasManyTags (..), HasManyBlockTags (..)++ -- ** Withering+ , HasWitherableTags (..), HasWitherableInlineTags (..), HasWitherableBlockTags (..)++ -- * Paragraphs+ , HasManyParagraphs (..)++ -- * Getting text from tagless content+ , CanBeTagless (..), CanHaveTaglessContent (..), KindOfText (..)++ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Metadata+import ProAbstract.Structure+import ProAbstract.Tag+import ProAbstract.Tagless
+ library/pro-abstract/ProAbstract/Content.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Content+ ( Content, HasContent (..), HasContent'+ , Contents, HasContents (..), HasContents'+ ) where++import ProAbstract.Content.ContentFamily+import ProAbstract.Content.ContentsFamily+import ProAbstract.Content.HasContent+import ProAbstract.Content.HasContents
+ library/pro-abstract/ProAbstract/Content/ContentFamily.hs view
@@ -0,0 +1,5 @@+module ProAbstract.Content.ContentFamily+ ( Content+ ) where++type family Content a
+ library/pro-abstract/ProAbstract/Content/ContentsFamily.hs view
@@ -0,0 +1,5 @@+module ProAbstract.Content.ContentsFamily+ ( Contents+ ) where++type family Contents a
+ library/pro-abstract/ProAbstract/Content/HasContent.hs view
@@ -0,0 +1,10 @@+module ProAbstract.Content.HasContent+ ( HasContent (..), HasContent'+ ) where++import ProAbstract.Content.ContentFamily++class HasContent x x' where+ content :: Lens x x' (Content x) (Content x')++type HasContent' x = HasContent x x
+ library/pro-abstract/ProAbstract/Content/HasContents.hs view
@@ -0,0 +1,10 @@+module ProAbstract.Content.HasContents+ ( HasContents (..), HasContents'+ ) where++import ProAbstract.Content.ContentsFamily++class HasContents x x' where+ contents :: Lens x x' (Seq (Contents x)) (Seq (Contents x'))++type HasContents' x = HasContents x x
+ library/pro-abstract/ProAbstract/Datatypes.hs view
@@ -0,0 +1,28 @@+module ProAbstract.Datatypes+ (+ -- * Document+ Document (..)++ -- * Blocks+ , Block (..), Blocks (..)++ -- * Lines+ , Inline (..), Line (..), Lines (..)++ -- * Tags and tagged things+ , Tag (..), Tagged (..), BlockTag (..)++ -- * Paragraph+ , Paragraph (..)++ -- * Plain text+ , Fragment (..), PlainBlock (..)++ -- * Metadata+ , Metadata (..)++ ) where++import ProAbstract.Metadata+import ProAbstract.Structure+import ProAbstract.Tag
+ library/pro-abstract/ProAbstract/Families.hs view
@@ -0,0 +1,12 @@+module ProAbstract.Families+ ( Annotation+ , Content+ , Contents+ , Fork+ , Plain+ , Tagged+ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Structure
+ library/pro-abstract/ProAbstract/Metadata.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Metadata+ ( Metadata (..), HasMetadata (..), HasManyMetadata (..)+ , properties, settings, hasProperty, atSetting+ ) where++import ProAbstract.Metadata.HasManyMetadata+import ProAbstract.Metadata.HasMetadata+import ProAbstract.Metadata.HasMetadataOptics+import ProAbstract.Metadata.MetadataType
+ library/pro-abstract/ProAbstract/Metadata/HasManyMetadata.hs view
@@ -0,0 +1,8 @@+module ProAbstract.Metadata.HasManyMetadata+ ( HasManyMetadata (..)+ ) where++import ProAbstract.Metadata.MetadataType++class HasManyMetadata x where+ allMetadata :: Traversal' x Metadata
+ library/pro-abstract/ProAbstract/Metadata/HasMetadata.hs view
@@ -0,0 +1,13 @@+module ProAbstract.Metadata.HasMetadata+ ( HasMetadata (..), Metadata+ ) where++import ProAbstract.Metadata.MetadataType (Metadata)++class HasMetadata x where+ type MetadataOpticKind x+ metadata :: Optic' (MetadataOpticKind x) NoIx x Metadata++instance HasMetadata Metadata where+ type MetadataOpticKind Metadata = An_Iso+ metadata = castOptic simple
+ library/pro-abstract/ProAbstract/Metadata/HasMetadataOptics.hs view
@@ -0,0 +1,23 @@+module ProAbstract.Metadata.HasMetadataOptics+ ( properties, settings, hasProperty, atSetting+ ) where++import ProAbstract.Metadata.HasMetadata++import qualified ProAbstract.Metadata.MetadataOptics as Meta++-- | Fetch all properties from items which contain metadata.+properties :: (HasMetadata m, JoinKinds (MetadataOpticKind m) A_Lens k) => Optic' k NoIx m (Set Text)+properties = metadata % Meta.properties++-- | Fetch all settings defined on items which contain metadata.+settings :: (HasMetadata m, JoinKinds (MetadataOpticKind m) A_Lens k) => Optic' k NoIx m (Map Text Text)+settings = metadata % Meta.settings++-- | Check if a property is attached to an item with metadata. Using this optic as a setter will add a property if set to 'True' and remove the property when set to 'False'.+hasProperty :: (HasMetadata m, JoinKinds (MetadataOpticKind m) A_Lens k) => Text -> Optic' k NoIx m Bool+hasProperty k = metadata % Meta.hasProperty k++-- | Select a setting from an item attached to metadata. Returns 'Nothing' if no value is set.+atSetting :: (HasMetadata m, JoinKinds (MetadataOpticKind m) A_Lens k) => Text -> Optic' k NoIx m (Maybe Text)+atSetting k = metadata % Meta.atSetting k
+ library/pro-abstract/ProAbstract/Metadata/MetadataOptics.hs view
@@ -0,0 +1,21 @@+module ProAbstract.Metadata.MetadataOptics+ ( properties, settings, hasProperty, atSetting+ ) where++import ProAbstract.Metadata.MetadataType++-- | Targets all properties from metadata.+properties :: Lens' Metadata (Set Text)+properties = lens metadataProperties (\m p -> m { metadataProperties = p })++-- | Targets all settings from metadata.+settings :: Lens' Metadata (Map Text Text)+settings = lens metadataSettings (\m s -> m { metadataSettings = s })++-- | Check if metadata includes a property. Using this optic as a setter will add a property if set to 'True' and remove the property when set to 'False'.+hasProperty :: Text -> Lens' Metadata Bool+hasProperty k = properties % lens (setMember k) (\s b -> (if b then setInsert else setDelete) k s)++-- | Targets a setting from metadata. Returns 'Nothing' if no value is set.+atSetting :: Text -> Lens' Metadata (Maybe Text)+atSetting k = settings % lens (mapLookup k) (\m x -> maybe (mapDelete k) (mapInsert k) x m)
+ library/pro-abstract/ProAbstract/Metadata/MetadataType.hs view
@@ -0,0 +1,20 @@+module ProAbstract.Metadata.MetadataType+ ( Metadata (..)+ ) where++{- | A set of properties and settings, associated with a document or tag.++The namespaces of properties and settings are distinct; a property can share a name with a setting without conflict.+-}+data Metadata = Metadata+ { metadataProperties :: Set Text -- ^ 'ProAbstract.properties'+ , metadataSettings :: Map Text Text -- ^ 'ProAbstract.settings'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (NFData, Hashable)++instance Monoid Metadata where+ mempty = Metadata mempty mempty++instance Semigroup Metadata where+ Metadata p1 s1 <> Metadata p2 s2 = Metadata (p1 <> p2) (s1 <> s2)
+ library/pro-abstract/ProAbstract/Optics.hs view
@@ -0,0 +1,37 @@+module ProAbstract.Optics+ (+ -- * Lenses+ content, contents, tag, name++ -- ** Annotation+ , annotation++ -- ** Metadata+ , metadata, atSetting, hasProperty, properties, settings++ -- * Prisms+ , fork, plain, paragraph, blockTag++ -- * Traversals+ , allParagraphs, allPlainBlocks, allPlainInlines++ -- ** Annotation+ , allAnnotations++ -- ** Tags+ , allTags, allInlineTags, allBlockTags++ -- ** Metadata+ , allMetadata++ -- * Affine folds+ , tagless, taglessContent, KindOfText (..)++ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Metadata+import ProAbstract.Structure+import ProAbstract.Tag+import ProAbstract.Tagless
+ library/pro-abstract/ProAbstract/Structure.hs view
@@ -0,0 +1,43 @@+module ProAbstract.Structure+ (+ -- * Document+ Document (..)++ -- * Blocks+ , Block (..), paragraph, Blocks (..), BlockTag (..), blockTag++ -- * Paragraph+ , Paragraph (..)++ -- * Inlines+ , Inline (..), Line (..), Lines (..)++ -- * Tagged+ , Tagged (..)++ -- * Text+ , PlainBlock (..), Fragment (..)++ -- * Plain and fork+ , CanBePlain (..), Plain, CanFork (..), Fork++ -- * Traversals+ , HasManyParagraphs (..), HasManyPlainBlocks (..), HasManyPlainInlines (..)++ ) where+++import ProAbstract.Structure.Block+import ProAbstract.Structure.BlockTag+import ProAbstract.Structure.CanBePlain+import ProAbstract.Structure.CanFork+import ProAbstract.Structure.Document+import ProAbstract.Structure.Fork+import ProAbstract.Structure.Fragment+import ProAbstract.Structure.HasManyParagraphs+import ProAbstract.Structure.HasManyPlainBlocks+import ProAbstract.Structure.HasManyPlainInlines+import ProAbstract.Structure.Inline+import ProAbstract.Structure.Paragraph+import ProAbstract.Structure.Plain+import ProAbstract.Structure.PlainBlock
+ library/pro-abstract/ProAbstract/Structure/Block.hs view
@@ -0,0 +1,237 @@+module ProAbstract.Structure.Block+ ( Block (..), paragraph, Blocks (..), Tagged (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Structure.Fork+import ProAbstract.Metadata+import ProAbstract.Structure.CanBePlain+import ProAbstract.Structure.CanFork+import ProAbstract.Structure.HasManyParagraphs+import ProAbstract.Structure.HasManyPlainBlocks+import ProAbstract.Structure.HasManyPlainInlines+import ProAbstract.Structure.Paragraph+import ProAbstract.Structure.Plain+import ProAbstract.Structure.PlainBlock+import ProAbstract.Tag+++-- ⭐ Block++data Block ann =+ BlockPlain (Tagged (PlainBlock ann)) -- ^ 'ProAbstract.plain'+ | BlockParagraph (Paragraph ann) -- ^ 'ProAbstract.paragraph'+ | BlockFork (Tagged (Blocks ann)) -- ^ 'ProAbstract.fork'+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Block ann) = ann++type instance Plain (Block ann) = Tagged (PlainBlock ann)++type instance Fork (Block ann) = Tagged (Blocks ann)++instance HasMetadata (Block ann) where+ type MetadataOpticKind (Block ann) = An_AffineTraversal+ metadata = tag % metadata++instance HasManyAnnotations (Block ann) (Block ann') where+ allAnnotations = traversalVL \f -> \case+ BlockPlain x -> BlockPlain <$> traverseOf allAnnotations f x+ BlockParagraph x -> BlockParagraph <$> traverseOf allAnnotations f x+ BlockFork x -> BlockFork <$> traverseOf allAnnotations f x++instance HasAnnotation (Block ann) (Block ann) where+ annotation = lens f g+ where+ f = \case+ BlockPlain x -> view annotation x+ BlockParagraph x -> view annotation x+ BlockFork x -> view annotation x+ g = \case+ BlockPlain x -> \a -> BlockPlain (set annotation a x)+ BlockParagraph x -> \a -> BlockParagraph (set annotation a x)+ BlockFork x -> \a -> BlockFork (set annotation a x)++instance HasManyPlainInlines (Block ann) where+ allPlainInlines = allParagraphs % allPlainInlines++instance HasManyParagraphs (Block ann) where+ allParagraphs = paragraph `adjoin` (fork % allParagraphs)++instance HasManyPlainBlocks (Block ann) where+ allPlainBlocks = plain `adjoin` (fork % allPlainBlocks)++instance HasTag (Block ann) where+ type TagOpticKind (Block ann) = An_AffineTraversal+ tag = atraversal f g+ where+ f = \case+ BlockPlain x -> Right (view tag x)+ BlockFork x -> Right (view tag x)+ x -> Left x+ g = \case+ BlockPlain x -> \a -> BlockPlain (set tag a x)+ BlockFork x -> \a -> BlockFork (set tag a x)+ x -> \_ -> x++instance HasManyTags (Block ann) where+ allTags = (fork % allTags) `adjoin` (paragraph % allTags) `adjoin` (plain % tag)+ allInlineTags = allParagraphs % allInlineTags++instance HasManyBlockTags (Block ann) where+ allBlockTags = (fork % allBlockTags) `adjoin` (plain % tag)++instance HasWitherableInlineTags (Block ann) where+ witherInlineTags f = traverseOf allParagraphs (witherInlineTags f)++instance HasManyMetadata (Block ann) where+ allMetadata = allTags % metadata++instance CanFork (Block ann) where+ fork = prism'+ BlockFork+ \case{ BlockFork t -> Just t; _ -> Nothing }++instance CanBePlain (Block ann) where+ plain = prism'+ BlockPlain+ \case{ BlockPlain t -> Just t; _ -> Nothing }++paragraph :: Prism' (Block ann) (Paragraph ann)+paragraph = prism'+ BlockParagraph+ \case{ BlockParagraph p -> Just p; _ -> Nothing }+++-- ⭐ Blocks++newtype Blocks ann =+ Blocks+ (Seq (Block ann)) -- ^ 'ProAbstract.content'+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)+ deriving newtype (Semigroup, Monoid)++type instance Contents (Blocks ann) = Block ann++instance HasContents (Blocks ann) (Blocks ann') where+ contents = castOptic coerced++instance IsList (Blocks ann) where+ type Item (Blocks ann) = Block ann+ toList (Blocks xs) = toList xs+ fromList xs = Blocks (fromList xs)++type instance Annotation (Blocks ann) = ann++instance HasManyAnnotations (Blocks ann) (Blocks ann') where+ allAnnotations = contents % traversed % allAnnotations++instance HasManyPlainInlines (Blocks ann) where+ allPlainInlines = contents % traversed % allPlainInlines++instance HasManyPlainBlocks (Blocks ann) where+ allPlainBlocks = contents % traversed % allPlainBlocks++instance HasManyTags (Blocks ann) where+ allTags = contents % traversed % allTags+ allInlineTags = contents % traversed % allInlineTags++instance HasManyBlockTags (Blocks ann) where+ allBlockTags = contents % traversed % allBlockTags++instance HasManyMetadata (Blocks ann) where+ allMetadata = allTags % metadata++instance HasManyParagraphs (Blocks ann) where+ allParagraphs = contents % traversed % allParagraphs++instance HasWitherableTags (Blocks ann) where+ witherTags f = traverseOf contents $ seqWither \case+ BlockParagraph x ->+ Just . BlockParagraph <$> traverseOf content (witherTags f) x+ BlockPlain x ->+ f (view tag x) >>= \case+ Nothing -> pure Nothing+ Just t -> pure . Just . BlockPlain . set tag t $ x+ BlockFork x ->+ f (view tag x) >>= \case+ Nothing -> pure Nothing+ Just t -> Just . BlockFork . set tag t <$> traverseOf content (witherTags f) x++instance HasWitherableBlockTags (Blocks ann) where+ witherBlockTags f = traverseOf contents $ seqWither \case+ BlockParagraph x -> pure $ Just $ BlockParagraph x+ BlockPlain x ->+ f (view tag x) >>= \case+ Nothing -> pure Nothing+ Just t -> pure . Just . BlockPlain . set tag t $ x+ BlockFork x ->+ f (view tag x) >>= \case+ Nothing -> pure Nothing+ Just t -> Just . BlockFork . set tag t <$> traverseOf content (witherBlockTags f) x++instance HasWitherableInlineTags (Blocks ann) where+ witherInlineTags f = traverseOf (contents % traversed) (witherInlineTags f)+++-- ⭐ Tagged Blocks++data instance Tagged (Blocks ann) =+ TaggedBlocks+ { blocksTag :: Tag ann -- ^ 'ProAbstract.tag'+ , taggedBlocks :: Blocks ann -- ^ 'ProAbstract.content'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Tagged (Blocks ann)) = ann++instance HasTag (Tagged (Blocks ann)) where+ type TagOpticKind (Tagged (Blocks ann)) = A_Lens+ tag = lens blocksTag \x a -> x{ blocksTag = a }++type instance Content (Tagged (Blocks ann)) = Blocks ann++type instance Contents (Tagged (Blocks ann)) = Block ann++instance HasManyAnnotations (Tagged (Blocks ann)) (Tagged (Blocks ann')) where+ allAnnotations = traversalVL \f (TaggedBlocks t b) -> TaggedBlocks+ <$> traverseOf annotation f t <*> traverseOf allAnnotations f b++instance HasAnnotation (Tagged (Blocks ann)) (Tagged (Blocks ann)) where+ annotation = tag % annotation++instance HasContent (Tagged (Blocks ann)) (Tagged (Blocks ann)) where+ content = lens taggedBlocks \x c -> x{ taggedBlocks = c }++instance HasContents (Tagged (Blocks ann)) (Tagged (Blocks ann)) where+ contents = content % contents++instance HasMetadata (Tagged (Blocks ann)) where+ type MetadataOpticKind (Tagged (Blocks ann)) = A_Lens+ metadata = tag % metadata++instance HasManyPlainInlines (Tagged (Blocks ann)) where+ allPlainInlines = content % allPlainInlines++instance HasManyTags (Tagged (Blocks ann)) where+ allTags = tag `adjoin` (content % allTags)+ allInlineTags = allParagraphs % allInlineTags++instance HasManyBlockTags (Tagged (Blocks ann)) where+ allBlockTags = tag `adjoin` (content % allBlockTags)++instance HasWitherableInlineTags (Tagged (Blocks ann)) where+ witherInlineTags f = traverseOf allParagraphs (witherInlineTags f)++instance HasManyMetadata (Tagged (Blocks ann)) where+ allMetadata = allTags % metadata++instance HasManyParagraphs (Tagged (Blocks ann)) where+ allParagraphs = content % allParagraphs++instance HasManyPlainBlocks (Tagged (Blocks ann)) where+ allPlainBlocks = content % allPlainBlocks
+ library/pro-abstract/ProAbstract/Structure/BlockTag.hs view
@@ -0,0 +1,89 @@+module ProAbstract.Structure.BlockTag+ ( BlockTag (..), blockTag+ ) where++import ProAbstract.Annotation+import ProAbstract.Metadata+import ProAbstract.Structure.Block+import ProAbstract.Structure.CanBePlain+import ProAbstract.Structure.CanFork+import ProAbstract.Structure.Fork+import ProAbstract.Structure.HasManyParagraphs+import ProAbstract.Structure.HasManyPlainBlocks+import ProAbstract.Structure.HasManyPlainInlines+import ProAbstract.Structure.Plain+import ProAbstract.Structure.PlainBlock+import ProAbstract.Tag++data BlockTag ann =+ BlockTagFork (Tagged (Blocks ann)) -- ^ 'ProAbstract.fork'+ | BlockTagPlain (Tagged (PlainBlock ann)) -- ^ 'ProAbstract.plain'++type instance Annotation (BlockTag ann) = ann++type instance Plain (BlockTag ann) = Tagged (PlainBlock ann)++type instance Fork (BlockTag ann) = Tagged (Blocks ann)++instance CanFork (BlockTag ann) where+ fork = prism' BlockTagFork \case{ BlockTagFork x -> Just x; _ -> Nothing }++instance CanBePlain (BlockTag ann) where+ plain = prism' BlockTagPlain \case{ BlockTagPlain x -> Just x; _ -> Nothing }++instance HasAnnotation (BlockTag ann) (BlockTag ann) where+ annotation = lens f g+ where+ f = \case+ BlockTagFork x -> view annotation x+ BlockTagPlain x -> view annotation x+ g = \case+ BlockTagFork x -> \a -> BlockTagFork $ set annotation a x+ BlockTagPlain x -> \a -> BlockTagPlain $ set annotation a x++instance HasManyAnnotations (BlockTag ann) (BlockTag ann') where+ allAnnotations = traversalVL \f -> \case+ BlockTagFork x -> BlockTagFork <$> traverseOf allAnnotations f x+ BlockTagPlain x -> BlockTagPlain <$> traverseOf allAnnotations f x++instance HasManyMetadata (BlockTag ann) where+ allMetadata = (fork % allMetadata) `adjoin` (plain % metadata)++instance HasManyParagraphs (BlockTag ann) where+ allParagraphs = fork % allParagraphs++instance HasManyPlainBlocks (BlockTag ann) where+ allPlainBlocks = (fork % allPlainBlocks) `adjoin` plain++instance HasManyPlainInlines (BlockTag ann) where+ allPlainInlines = fork % allPlainInlines++instance HasManyTags (BlockTag ann) where+ allTags = (fork % allTags) `adjoin` (plain % tag)+ allInlineTags = fork % allInlineTags++instance HasTag (BlockTag ann) where+ type TagOpticKind (BlockTag ann) = A_Lens+ tag = lens f g+ where+ f = \case+ BlockTagFork x -> view tag x+ BlockTagPlain x -> view tag x+ g = \case+ BlockTagFork x -> \a -> BlockTagFork (set tag a x)+ BlockTagPlain x -> \a -> BlockTagPlain (set tag a x)++instance HasMetadata (BlockTag ann) where+ type MetadataOpticKind (BlockTag ann) = A_Lens+ metadata = tag % metadata++blockTag :: Prism' (Block ann) (BlockTag ann)+blockTag = prism' f g+ where+ f = \case+ BlockTagFork x -> BlockFork x+ BlockTagPlain x -> BlockPlain x+ g = \case+ BlockFork x -> Just (BlockTagFork x)+ BlockPlain x -> Just (BlockTagPlain x)+ _ -> Nothing
+ library/pro-abstract/ProAbstract/Structure/CanBePlain.hs view
@@ -0,0 +1,8 @@+module ProAbstract.Structure.CanBePlain+ ( CanBePlain (..)+ ) where++import ProAbstract.Structure.Plain++class CanBePlain x where+ plain :: Prism' x (Plain x)
+ library/pro-abstract/ProAbstract/Structure/CanFork.hs view
@@ -0,0 +1,8 @@+module ProAbstract.Structure.CanFork+ ( CanFork (..)+ ) where++import ProAbstract.Structure.Fork++class CanFork x where+ fork :: Prism' x (Fork x)
+ library/pro-abstract/ProAbstract/Structure/Document.hs view
@@ -0,0 +1,66 @@+module ProAbstract.Structure.Document+ ( Document (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Metadata+import ProAbstract.Structure.Block+import ProAbstract.Structure.HasManyParagraphs+import ProAbstract.Structure.HasManyPlainBlocks+import ProAbstract.Structure.HasManyPlainInlines+import ProAbstract.Tag++data Document ann = Document+ { documentMetadata :: Metadata -- ^ 'ProAbstract.metadata'+ , documentContent :: Blocks ann -- ^ 'ProAbstract.content'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Document ann) = ann++type instance Content (Document ann) = Blocks ann++type instance Contents (Document ann) = Block ann++instance HasContent (Document ann) (Document ann') where+ content = lens documentContent (\d c -> d { documentContent = c })++instance HasContents (Document ann) (Document ann') where+ contents = content % contents++instance HasMetadata (Document ann) where+ type MetadataOpticKind (Document ann) = A_Lens+ metadata = lens documentMetadata (\d m -> d { documentMetadata = m })++instance HasManyPlainInlines (Document ann) where+ allPlainInlines = content % allPlainInlines++instance HasManyPlainBlocks (Document ann) where+ allPlainBlocks = content % allPlainBlocks++instance HasManyAnnotations (Document ann) (Document ann') where+ allAnnotations = content % allAnnotations++instance HasManyMetadata (Document ann) where+ allMetadata = metadata `adjoin` (content % allMetadata)++instance HasManyParagraphs (Document ann) where+ allParagraphs = content % allParagraphs++instance HasManyTags (Document ann) where+ allTags = content % allTags+ allInlineTags = content % allInlineTags++instance HasWitherableTags (Document ann) where+ witherTags f = traverseOf content (witherTags f)++instance HasManyBlockTags (Document ann) where+ allBlockTags = content % allBlockTags++instance HasWitherableBlockTags (Document ann) where+ witherBlockTags f = traverseOf content (witherBlockTags f)++instance HasWitherableInlineTags (Document ann) where+ witherInlineTags f = traverseOf content (witherInlineTags f)
+ library/pro-abstract/ProAbstract/Structure/Fork.hs view
@@ -0,0 +1,5 @@+module ProAbstract.Structure.Fork+ ( Fork+ ) where++type family Fork a
+ library/pro-abstract/ProAbstract/Structure/Fragment.hs view
@@ -0,0 +1,23 @@+module ProAbstract.Structure.Fragment+ ( Fragment (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Content++data Fragment ann = Fragment+ { fragmentText :: Text -- ^ 'ProAbstract.content'+ , fragmentAnnotation :: ann -- ^ 'ProAbstract.annotation'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Fragment ann) = ann++instance HasAnnotation (Fragment ann) (Fragment ann') where+ annotation = lens fragmentAnnotation \x a -> x { fragmentAnnotation = a }++type instance Content (Fragment ann) = Text++instance HasContent (Fragment ann) (Fragment ann) where+ content = lens fragmentText (\f t -> f { fragmentText = t })
+ library/pro-abstract/ProAbstract/Structure/HasManyParagraphs.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Structure.HasManyParagraphs+ ( HasManyParagraphs (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Structure.Paragraph++class HasManyParagraphs x where+ allParagraphs :: Traversal' x (Paragraph (Annotation x))
+ library/pro-abstract/ProAbstract/Structure/HasManyPlainBlocks.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Structure.HasManyPlainBlocks+ ( HasManyPlainBlocks (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Structure.PlainBlock++class HasManyPlainBlocks x where+ allPlainBlocks :: Traversal' x (Tagged (PlainBlock (Annotation x)))
+ library/pro-abstract/ProAbstract/Structure/HasManyPlainInlines.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Structure.HasManyPlainInlines+ ( HasManyPlainInlines (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Structure.Fragment++class HasManyPlainInlines x where+ allPlainInlines :: Traversal' x (Fragment (Annotation x))
+ library/pro-abstract/ProAbstract/Structure/Inline.hs view
@@ -0,0 +1,217 @@+module ProAbstract.Structure.Inline+ ( Inline (..), Line (..), Lines (..), Tagged (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Metadata+import ProAbstract.Structure.CanBePlain+import ProAbstract.Structure.CanFork+import ProAbstract.Structure.Fork+import ProAbstract.Structure.Fragment+import ProAbstract.Structure.HasManyPlainInlines+import ProAbstract.Structure.Plain+import ProAbstract.Tag+++-- ⭐ Inline++data Inline ann =+ InlineFork (Tagged (Lines ann)) -- ^ 'ProAbstract.fork'+ | InlinePlain (Fragment ann) -- ^ 'ProAbstract.plain'+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Inline ann) = ann++type instance Fork (Inline ann) = Tagged (Lines ann)++type instance Plain (Inline ann) = Fragment ann++instance HasMetadata (Inline ann) where+ type MetadataOpticKind (Inline ann) = An_AffineTraversal+ metadata = tag % metadata++instance HasManyAnnotations (Inline ann) (Inline ann') where+ allAnnotations = traversalVL \f -> \case+ InlinePlain x -> InlinePlain <$> traverseOf annotation f x+ InlineFork x -> InlineFork <$> traverseOf allAnnotations f x++instance HasAnnotation (Inline ann) (Inline ann) where+ annotation = lens f g+ where+ f = \case+ InlineFork x -> view annotation x+ InlinePlain x -> view annotation x+ g = \case+ InlineFork x -> \a -> InlineFork (set annotation a x)+ InlinePlain x -> \a -> InlinePlain (set annotation a x)++instance HasManyPlainInlines (Inline ann) where+ allPlainInlines = plain `adjoin` (fork % allPlainInlines)++instance HasTag (Inline ann) where+ type TagOpticKind (Inline ann) = An_AffineTraversal+ tag = atraversal f g+ where+ f = \case+ InlineFork x -> Right (view tag x)+ x -> Left x+ g = \case+ InlineFork x -> \a -> InlineFork (set tag a x)+ x -> \_ -> x++instance HasManyTags (Inline ann) where+ allTags = fork % allTags+ allInlineTags = allTags++instance HasManyMetadata (Inline ann) where+ allMetadata = fork % allMetadata++instance CanFork (Inline ann) where+ fork = prism' InlineFork \case{ InlineFork t -> Just t; _ -> Nothing }++instance CanBePlain (Inline ann) where+ plain = prism' InlinePlain \case{ InlinePlain t -> Just t; _ -> Nothing }+++-- ⭐ Line++data Line ann = Line+ { lineInlines :: Seq (Inline ann) -- ^ 'ProAbstract.contentsSeq'+ , lineAnnotation :: ann -- ^ 'ProAbstract.annotation'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++instance IsList (Line ()) where+ type Item (Line ()) = Inline ()+ toList (Line xs ()) = toList xs+ fromList xs = Line (fromList xs) ()++type instance Contents (Line ann) = Inline ann++instance HasContents (Line ann) (Line ann) where+ contents = lens lineInlines \x a -> x{ lineInlines = a }++type instance Annotation (Line ann) = ann++instance HasAnnotation (Line ann) (Line ann) where+ annotation = lens lineAnnotation \x a -> x{ lineAnnotation = a }++instance HasManyPlainInlines (Line ann) where+ allPlainInlines = contents % traversed % allPlainInlines++instance HasManyAnnotations (Line ann) (Line ann') where+ allAnnotations = traversalVL \f (Line xs a) ->+ Line <$> traverseOf (traversed % allAnnotations) f xs <*> f a++instance HasManyMetadata (Line ann) where+ allMetadata = contents % traversed % allMetadata++instance HasManyTags (Line ann) where+ allTags = contents % traversed % allTags+ allInlineTags = allTags++instance HasWitherableInlineTags (Line ann) where+ witherInlineTags = witherTags++instance HasWitherableTags (Line ann) where+ witherTags f = traverseOf contents $+ seqWither \case+ InlinePlain x -> pure . Just . InlinePlain $ x+ InlineFork x -> f (view tag x) >>= \case+ Nothing -> pure Nothing+ Just t -> Just . InlineFork . set tag t <$> traverseOf content (witherTags f) x+++-- ⭐ Lines++newtype Lines ann =+ Lines+ (Seq (Line ann)) -- ^ 'ProAbstract.contentsSeq'+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)+ deriving newtype (Semigroup, Monoid)++instance IsList (Lines ann) where+ type Item (Lines ann) = Line ann+ toList (Lines xs) = toList xs+ fromList xs = Lines (fromList xs)++type instance Contents (Lines ann) = Line ann++instance HasContents (Lines ann) (Lines ann') where+ contents = castOptic coerced++type instance Annotation (Lines ann) = ann++instance HasManyPlainInlines (Lines ann) where+ allPlainInlines = contents % traversed % allPlainInlines++instance HasManyAnnotations (Lines ann) (Lines ann') where+ allAnnotations = contents % traversed % allAnnotations++instance HasManyMetadata (Lines ann) where+ allMetadata = contents % traversed % allMetadata++instance HasManyTags (Lines ann) where+ allTags = contents % traversed % allTags+ allInlineTags = allTags++instance HasWitherableInlineTags (Lines ann) where+ witherInlineTags = witherTags++instance HasWitherableTags (Lines ann) where+ witherTags f = traverseOf (contents % traversed) (witherTags f)+++-- ⭐ Tagged Lines++data instance Tagged (Lines ann) =+ TaggedLines+ { linesTag :: Tag ann -- ^ 'ProAbstract.tag'+ , taggedLines :: Lines ann -- ^ 'ProAbstract.content'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Tagged (Lines ann)) = ann++instance HasTag (Tagged (Lines ann)) where+ type TagOpticKind (Tagged (Lines ann)) = A_Lens+ tag = lens linesTag \x a -> x{ linesTag = a }++type instance Content (Tagged (Lines ann)) = Lines ann++type instance Contents (Tagged (Lines ann)) = Line ann++instance HasManyAnnotations (Tagged (Lines ann)) (Tagged (Lines ann')) where+ allAnnotations = traversalVL \f (TaggedLines t b) -> TaggedLines+ <$> traverseOf annotation f t <*> traverseOf allAnnotations f b++instance HasAnnotation (Tagged (Lines ann)) (Tagged (Lines ann)) where+ annotation = tag % annotation++instance HasContent (Tagged (Lines ann)) (Tagged (Lines ann)) where+ content = lens taggedLines \x c -> x{ taggedLines = c }++instance HasContents (Tagged (Lines ann)) (Tagged (Lines ann)) where+ contents = content % contents++instance HasMetadata (Tagged (Lines ann)) where+ type MetadataOpticKind (Tagged (Lines ann)) = A_Lens+ metadata = tag % metadata++instance HasManyPlainInlines (Tagged (Lines ann)) where+ allPlainInlines = content % allPlainInlines++instance HasManyTags (Tagged (Lines ann)) where+ allTags = tag `adjoin` (content % allTags)+ allInlineTags = allTags++instance HasWitherableInlineTags (Tagged (Lines ann)) where+ witherInlineTags f = traverseOf content (witherInlineTags f)++instance HasManyMetadata (Tagged (Lines ann)) where+ allMetadata = allTags % metadata
+ library/pro-abstract/ProAbstract/Structure/Paragraph.hs view
@@ -0,0 +1,50 @@+module ProAbstract.Structure.Paragraph+ ( Paragraph (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Metadata+import ProAbstract.Structure.HasManyPlainInlines+import ProAbstract.Structure.Inline+import ProAbstract.Tag++-- | A collection of 'Lines'. A 'Paragraph' represents the border between block and inline contexts. All ancestors of a paragraph are block items or a document, and all children are inline items.+data Paragraph ann = Paragraph+ { paragraphContent :: Lines ann -- ^ 'ProAbstract.content'+ , paragraphAnnotation :: ann -- ^ 'ProAbstract.annotation'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Content (Paragraph ann) = Lines ann++type instance Contents (Paragraph ann) = Line ann++type instance Annotation (Paragraph ann) = ann++instance HasManyAnnotations (Paragraph ann) (Paragraph ann') where+ allAnnotations = traversalVL \f (Paragraph c a) ->+ Paragraph <$> traverseOf allAnnotations f c <*> f a++instance HasAnnotation (Paragraph ann) (Paragraph ann) where+ annotation = lens paragraphAnnotation \x a -> x{ paragraphAnnotation = a }++instance HasContent (Paragraph ann) (Paragraph ann) where+ content = lens paragraphContent (\t c -> t { paragraphContent = c })++instance HasContents (Paragraph ann) (Paragraph ann) where+ contents = content % contents++instance HasManyPlainInlines (Paragraph ann) where+ allPlainInlines = content % allPlainInlines++instance HasManyMetadata (Paragraph ann) where+ allMetadata = content % allMetadata++instance HasManyTags (Paragraph ann) where+ allTags = content % allTags+ allInlineTags = content % allInlineTags++instance HasWitherableInlineTags (Paragraph ann) where+ witherInlineTags f = traverseOf content (witherInlineTags f)
+ library/pro-abstract/ProAbstract/Structure/Plain.hs view
@@ -0,0 +1,5 @@+module ProAbstract.Structure.Plain+ ( Plain+ ) where++type family Plain a
+ library/pro-abstract/ProAbstract/Structure/PlainBlock.hs view
@@ -0,0 +1,71 @@+module ProAbstract.Structure.PlainBlock+ ( PlainBlock (..), Tagged (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Content+import ProAbstract.Metadata+import ProAbstract.Structure.Fragment+import ProAbstract.Tag+++-- ⭐ PlainBlock++data PlainBlock ann = PlainBlock+ { plainBlockLines :: Seq (Fragment ann) -- ^ 'ProAbstract.contentsSeq'+ , plainBlockAnnotation :: ann -- ^ 'ProAbstract.annotation'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Contents (PlainBlock ann) = Fragment ann++instance HasContents (PlainBlock ann) (PlainBlock ann) where+ contents = lens plainBlockLines \x a -> x{ plainBlockLines = a }++type instance Annotation (PlainBlock ann) = ann++instance HasAnnotation (PlainBlock ann) (PlainBlock ann) where+ annotation = lens plainBlockAnnotation \x a -> x { plainBlockAnnotation = a }++instance HasManyAnnotations (PlainBlock ann) (PlainBlock ann') where+ allAnnotations = traversalVL \f (PlainBlock t a) ->+ PlainBlock <$> traverseOf (traversed % annotation) f t <*> f a+++-- ⭐ Tagged PlainBlock++data instance Tagged (PlainBlock ann) =+ TaggedPlainBlock+ { plaintextTag :: Tag ann -- ^ 'ProAbstract.Tag'+ , taggedPlaintext :: PlainBlock ann -- ^ 'ProAbstract.content'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Tagged (PlainBlock ann)) = ann++instance HasTag (Tagged (PlainBlock ann)) where+ type TagOpticKind (Tagged (PlainBlock ann)) = A_Lens+ tag = lens plaintextTag \x a -> x{ plaintextTag = a }++type instance Content (Tagged (PlainBlock ann)) = PlainBlock ann++type instance Contents (Tagged (PlainBlock ann)) = Fragment ann++instance HasContents (Tagged (PlainBlock ann)) (Tagged (PlainBlock ann)) where+ contents = content % contents++instance HasManyAnnotations (Tagged (PlainBlock ann)) (Tagged (PlainBlock ann')) where+ allAnnotations = traversalVL \f (TaggedPlainBlock t b) -> TaggedPlainBlock+ <$> traverseOf annotation f t <*> traverseOf allAnnotations f b++instance HasAnnotation (Tagged (PlainBlock ann)) (Tagged (PlainBlock ann)) where+ annotation = tag % annotation++instance HasContent (Tagged (PlainBlock ann)) (Tagged (PlainBlock ann)) where+ content = lens taggedPlaintext \x c -> x{ taggedPlaintext = c }++instance HasMetadata (Tagged (PlainBlock ann)) where+ type MetadataOpticKind (Tagged (PlainBlock ann)) = A_Lens+ metadata = tag % metadata
+ library/pro-abstract/ProAbstract/Tag.hs view
@@ -0,0 +1,14 @@+module ProAbstract.Tag+ ( Tag (..), name+ , Tagged+ , HasTag (..)+ , HasManyTags (..), HasWitherableTags (..)+ , HasManyBlockTags (..), HasWitherableBlockTags (..)+ , HasWitherableInlineTags (..)+ ) where++import ProAbstract.Tag.HasManyTags+import ProAbstract.Tag.HasTag+import ProAbstract.Tag.HasTagOptics+import ProAbstract.Tag.TagType+import ProAbstract.Tag.TaggedFamily
+ library/pro-abstract/ProAbstract/Tag/HasManyTags.hs view
@@ -0,0 +1,33 @@+module ProAbstract.Tag.HasManyTags+ ( HasManyTags (..), HasWitherableTags (..)+ , HasManyBlockTags (..), HasWitherableBlockTags (..)+ , HasWitherableInlineTags (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Tag.TagType++class HasManyTags x where+ allTags :: Traversal' x (Tag (Annotation x))+ allInlineTags :: Traversal' x (Tag (Annotation x))++class HasWitherableTags x where+ witherTags :: Monad f => (Tag (Annotation x) -> f (Maybe (Tag (Annotation x)))) -> x -> f x++ mapMaybeTags :: (Tag (Annotation x) -> Maybe (Tag (Annotation x))) -> x -> x+ mapMaybeTags f = runIdentity . witherTags (Identity . f)++class HasManyTags x => HasManyBlockTags x where+ allBlockTags :: Traversal' x (Tag (Annotation x))++class HasManyBlockTags x => HasWitherableBlockTags x where+ witherBlockTags :: Monad f => (Tag (Annotation x) -> f (Maybe (Tag (Annotation x)))) -> x -> f x++ mapMaybeBlockTags :: (Tag (Annotation x) -> Maybe (Tag (Annotation x))) -> x -> x+ mapMaybeBlockTags f = runIdentity . witherBlockTags (Identity . f)++class HasManyTags x => HasWitherableInlineTags x where+ witherInlineTags :: Monad f => (Tag (Annotation x) -> f (Maybe (Tag (Annotation x)))) -> x -> f x++ mapMaybeInlineTags :: (Tag (Annotation x) -> Maybe (Tag (Annotation x))) -> x -> x+ mapMaybeInlineTags f = runIdentity . witherInlineTags (Identity . f)
+ library/pro-abstract/ProAbstract/Tag/HasTag.hs view
@@ -0,0 +1,14 @@+module ProAbstract.Tag.HasTag+ ( HasTag (..)+ ) where++import ProAbstract.Annotation+import ProAbstract.Tag.TagType++class HasTag x where+ type TagOpticKind x :: OpticKind+ tag :: Optic' (TagOpticKind x) NoIx x (Tag (Annotation x))++instance HasTag (Tag ann) where+ type TagOpticKind (Tag ann) = A_Lens+ tag = castOptic simple
+ library/pro-abstract/ProAbstract/Tag/HasTagOptics.hs view
@@ -0,0 +1,10 @@+module ProAbstract.Tag.HasTagOptics+ ( name+ ) where++import ProAbstract.Tag.HasTag++import qualified ProAbstract.Tag.TagOptics as Tag++name :: (HasTag x, JoinKinds (TagOpticKind x) A_Lens k) => Optic' k NoIx x Text+name = tag % Tag.name
+ library/pro-abstract/ProAbstract/Tag/TagOptics.hs view
@@ -0,0 +1,6 @@+module ProAbstract.Tag.TagOptics where++import ProAbstract.Tag.TagType++name :: Lens' (Tag ann) Text+name = lens tagName (\t n -> t { tagName = n })
+ library/pro-abstract/ProAbstract/Tag/TagType.hs view
@@ -0,0 +1,24 @@+module ProAbstract.Tag.TagType+ ( Tag (..)+ )+ where++import ProAbstract.Annotation+import ProAbstract.Metadata++data Tag ann = Tag+ { tagName :: Text -- ^ 'ProAbstract.name'+ , tagMetadata :: Metadata -- ^ 'ProAbstract.metadata'+ , tagAnnotation :: ann -- ^ 'ProAbstract.annotation'+ }+ deriving stock (Eq, Show, Generic)+ deriving anyclass (Hashable, NFData)++type instance Annotation (Tag ann) = ann++instance HasAnnotation (Tag ann) (Tag ann') where+ annotation = lens tagAnnotation \x a -> x{ tagAnnotation = a }++instance HasMetadata (Tag ann) where+ type MetadataOpticKind (Tag ann) = A_Lens+ metadata = lens tagMetadata (\d m -> d { tagMetadata = m })
+ library/pro-abstract/ProAbstract/Tag/TaggedFamily.hs view
@@ -0,0 +1,5 @@+module ProAbstract.Tag.TaggedFamily+ ( Tagged+ ) where++data family Tagged con
+ library/pro-abstract/ProAbstract/Tagless.hs view
@@ -0,0 +1,8 @@+module ProAbstract.Tagless+ ( CanBeTagless (..), CanHaveTaglessContent (..)+ , KindOfText (..)+ ) where++import ProAbstract.Tagless.CanBeTagless+import ProAbstract.Tagless.CanHaveTaglessContent+import ProAbstract.Tagless.KindOfText
+ library/pro-abstract/ProAbstract/Tagless/CanBeTagless.hs view
@@ -0,0 +1,56 @@+module ProAbstract.Tagless.CanBeTagless+ ( CanBeTagless (..)+ ) where++import ProAbstract.Content+import ProAbstract.Tagless.KindOfText+import ProAbstract.Structure++class CanBeTagless a where+ tagless :: KindOfText txt -> AffineFold a txt++instance CanBeTagless (Fragment ann) where+ tagless = liftLine $ castOptic content++instance CanBeTagless (Line ann) where+ tagless = liftLine $ contents % all (tagless TextLine) % to textConcat++instance CanBeTagless (Lines ann) where+ tagless = linesAre $ tagless TextLine++instance CanBeTagless (PlainBlock ann) where+ tagless = linesAre $ tagless TextLine++instance CanBeTagless (Paragraph ann) where+ tagless = linesAre $ tagless TextLine++-- | Only a 'plain' inline is considered to be plain text, because 'fork' inlines have a tags.+instance CanBeTagless (Inline ann) where+ tagless s = plain % tagless s++-- | Only a 'paragraph' inline is considered to be plain text, because 'fork' and 'plain' blocks have tags.+instance CanBeTagless (Block ann) where+ tagless s = paragraph % tagless s++instance CanBeTagless (Blocks ann) where+ tagless = \case+ TextParagraphs -> contents % all (tagless TextParagraphs) % to seqConcat+ s -> contents+ % seqAtMostOne -- For lines and stanza return types, there is not allowed to be more than one block+ % all @Maybe (tagless s) -- If there is a block, it has to be convertable to the desired text kind+ % to (fromMaybe (noText s)) -- If there are no blocks, return an empty line or stanza++noText :: KindOfText txt -> txt+noText = \case{ TextLine -> textEmpty; TextStanza -> Empty; TextParagraphs -> Empty }++all :: Traversable t => AffineFold a b -> AffineFold (t a) (t b)+all = afolding . traverse . preview++liftLine :: AffineFold a Text -> KindOfText txt -> AffineFold a txt+liftLine o = liftStanza o (o % re seqSingleton)++liftStanza :: AffineFold a Text -> AffineFold a (Seq Text) -> KindOfText txt -> AffineFold a txt+liftStanza o1 o2 = \case{ TextLine -> o1; TextStanza -> o2; TextParagraphs -> o2 % re seqSingleton }++linesAre :: HasContents' a => AffineFold (Contents a) Text -> KindOfText txt -> AffineFold a txt+linesAre o = liftStanza (contents % seqAtMostOne % all o % to (fromMaybe textEmpty)) (contents % all o)
+ library/pro-abstract/ProAbstract/Tagless/CanHaveTaglessContent.hs view
@@ -0,0 +1,49 @@+module ProAbstract.Tagless.CanHaveTaglessContent+ ( CanHaveTaglessContent (..)+ ) where++import ProAbstract.Content+import ProAbstract.Structure+import ProAbstract.Tagless.CanBeTagless+import ProAbstract.Tagless.KindOfText++class CanHaveTaglessContent a where+ taglessContent :: KindOfText t -> AffineFold a t++instance CanHaveTaglessContent (Block ann) where+ taglessContent s =+ (plain % taglessContent @(Tagged (PlainBlock ann)) s) `afailing`+ (fork % taglessContent @(Tagged (Blocks ann)) s) `afailing`+ (paragraph % tagless @(Paragraph ann) s)++instance CanHaveTaglessContent (BlockTag ann) where+ taglessContent s =+ (plain % taglessContent @(Tagged (PlainBlock ann)) s) `afailing`+ (fork % taglessContent @(Tagged (Blocks ann)) s)++instance CanHaveTaglessContent (Inline ann) where+ taglessContent s = (plain % tagless s) `afailing` (fork % taglessContent s)++instance CanHaveTaglessContent (Lines ann) where+ taglessContent = tagless++instance CanHaveTaglessContent (Blocks ann) where+ taglessContent = tagless++instance CanHaveTaglessContent (Line ann) where+ taglessContent = tagless++instance CanHaveTaglessContent (Fragment ann) where+ taglessContent = tagless++instance CanHaveTaglessContent (Tagged (Blocks ann)) where+ taglessContent s = content % tagless s++instance CanHaveTaglessContent (Tagged (PlainBlock ann)) where+ taglessContent s = content % tagless s++instance CanHaveTaglessContent (Tagged (Lines ann)) where+ taglessContent s = content % tagless s++instance CanHaveTaglessContent (Document ann) where+ taglessContent s = content % tagless s
+ library/pro-abstract/ProAbstract/Tagless/KindOfText.hs view
@@ -0,0 +1,9 @@+module ProAbstract.Tagless.KindOfText+ ( KindOfText (..)+ ) where++data KindOfText txt where+ TextLine :: KindOfText Text+ TextStanza :: KindOfText (Seq Text)+ TextParagraphs :: KindOfText (Seq (Seq Text))+
+ library/pro-abstract/ProAbstract/Types.hs view
@@ -0,0 +1,27 @@+module ProAbstract.Types+ ( Annotation+ , Block+ , Blocks+ , BlockTag+ , Content+ , Contents+ , Document+ , Fork+ , Fragment+ , Inline+ , Line+ , Lines+ , Map+ , Metadata+ , Paragraph+ , Plain+ , PlainBlock+ , Seq+ , Set+ , Tag+ , Tagged+ , Text+ ) where++import ProAbstract.Datatypes+import ProAbstract.Families
+ pro-abstract.cabal view
@@ -0,0 +1,144 @@+cabal-version: 3.0++name: pro-abstract+version: 0.1.0.0++category: Language+synopsis: Abstract syntax for writing documents+description:+ This package defines the abstract syntax only+ for a language for writing documents.++ Forked from part of the+ <https://hackage.haskell.org/package/prosidy prosidy>+ package.++license: MPL-2.0+license-file: LICENSE+maintainer: hello@typeclasses.com+author: Chris Martin, James Alexander Feldman-Crough+copyright:+ © 2020 James Alexander Feldman-Crough,+ © 2022 Mission Valley Software LLC++source-repository head+ type: git+ location: git://github.com/typeclasses/pro-abstract.git++common base+ default-language: Haskell2010+ ghc-options: -Wall+ default-extensions:+ BlockArguments+ ConstraintKinds+ DataKinds+ DeriveAnyClass+ DeriveGeneric+ DerivingStrategies+ FlexibleContexts+ FlexibleInstances+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ MultiParamTypeClasses+ PatternSynonyms+ ScopedTypeVariables+ TypeApplications+ TypeFamilies+ build-depends:+ base ^>= 4.13 || ^>= 4.14 || ^>= 4.15 || ^>= 4.16+ , containers ^>= 0.6+ , deepseq ^>= 1.4.4+ , hashable ^>= 1.3.4.0 || ^>= 1.4+ , optics-core ^>= 0.4+ , text ^>= 1.2.4++library+ import: base+ mixins: base hiding (Prelude)+ build-depends: pro-abstract-prelude+ hs-source-dirs: library/pro-abstract++ exposed-modules:+ ProAbstract+ , ProAbstract.Annotation+ , ProAbstract.Classes+ , ProAbstract.Content+ , ProAbstract.Datatypes+ , ProAbstract.Families+ , ProAbstract.Metadata+ , ProAbstract.Optics+ , ProAbstract.Structure+ , ProAbstract.Tag+ , ProAbstract.Tagless+ , ProAbstract.Types++ other-modules:+ , ProAbstract.Annotation.AnnotationFamily+ , ProAbstract.Annotation.HasAnnotation+ , ProAbstract.Annotation.HasManyAnnotations+ , ProAbstract.Content.ContentFamily+ , ProAbstract.Content.ContentsFamily+ , ProAbstract.Content.HasContent+ , ProAbstract.Content.HasContents+ , ProAbstract.Metadata.HasManyMetadata+ , ProAbstract.Metadata.HasMetadata+ , ProAbstract.Metadata.HasMetadataOptics+ , ProAbstract.Metadata.MetadataOptics+ , ProAbstract.Metadata.MetadataType+ , ProAbstract.Structure.Block+ , ProAbstract.Structure.BlockTag+ , ProAbstract.Structure.CanBePlain+ , ProAbstract.Structure.CanFork+ , ProAbstract.Structure.Document+ , ProAbstract.Structure.Fork+ , ProAbstract.Structure.Fragment+ , ProAbstract.Structure.HasManyParagraphs+ , ProAbstract.Structure.HasManyPlainBlocks+ , ProAbstract.Structure.HasManyPlainInlines+ , ProAbstract.Structure.Inline+ , ProAbstract.Structure.Paragraph+ , ProAbstract.Structure.Plain+ , ProAbstract.Structure.PlainBlock+ , ProAbstract.Tag.HasManyTags+ , ProAbstract.Tag.HasTag+ , ProAbstract.Tag.HasTagOptics+ , ProAbstract.Tag.TaggedFamily+ , ProAbstract.Tag.TagOptics+ , ProAbstract.Tag.TagType+ , ProAbstract.Tagless.CanBeTagless+ , ProAbstract.Tagless.CanHaveTaglessContent+ , ProAbstract.Tagless.KindOfText++library pro-abstract-prelude+ import: base+ hs-source-dirs: library/pro-abstract-prelude++ default-extensions:+ NoImplicitPrelude+ NoMonomorphismRestriction++ exposed-modules:+ Containers+ , Prelude++ mixins:+ base (Prelude as BasePrelude)+ , base hiding (Prelude)++test-suite test-pro-abstract+ import: base+ type: exitcode-stdio-1.0+ hs-source-dirs: test-suite/test-pro-abstract+ main-is: Main.hs++ default-extensions:+ OverloadedLists+ OverloadedStrings+ QuasiQuotes+ TemplateHaskell++ build-depends:+ pro-abstract+ , neat-interpolation ^>= 0.5+ , hedgehog ^>= 1.0 || ^>= 1.1
+ test-suite/test-pro-abstract/Main.hs view
@@ -0,0 +1,96 @@+module Main (main) where++import ProAbstract++import Optics.Core+import Prelude hiding (break)++import Control.Monad (when)+import Data.Text (Text)+import Hedgehog (Property, checkParallel, discover, property, withTests, (===))+import System.Exit (exitFailure)++main :: IO ()+main = checkParallel $$discover >>= \ok -> when (not ok) exitFailure++frag :: Text -> Fragment ()+frag x = Fragment{ fragmentText = x, fragmentAnnotation = () }++inlinePlain :: Text -> Inline ()+inlinePlain = InlinePlain . frag++inlineFork :: Lines () -> Inline ()+inlineFork x = InlineFork $ TaggedLines{ linesTag = Tag{ tagName = "x", tagMetadata = mempty, tagAnnotation = () }, taggedLines = x }++para :: Lines () -> Block ()+para x = BlockParagraph Paragraph{ paragraphAnnotation = (), paragraphContent = x }++btag :: Blocks () -> Block ()+btag x = BlockFork TaggedBlocks{ blocksTag = Tag{ tagName = "x", tagMetadata = mempty, tagAnnotation = () }, taggedBlocks = x }++tbtag :: Blocks () -> BlockTag ()+tbtag x = BlockTagFork TaggedBlocks{ blocksTag = Tag{ tagName = "x", tagMetadata = mempty, tagAnnotation = () }, taggedBlocks = x }++prop_ex1 :: Property+prop_ex1 = withTests 1 $ property $ do+ x <- pure $ inlinePlain "abc"+ preview (tagless TextStanza) x === Just ["abc"]++prop_ex2 :: Property+prop_ex2 = withTests 1 $ property $ do+ x <- pure $ InlineFork $+ TaggedLines+ { linesTag = Tag{ tagName = "x", tagMetadata = mempty, tagAnnotation = () }+ , taggedLines = [[inlinePlain "abc", inlinePlain "def"]]+ }+ preview (fork % content % (tagless TextStanza)) x === Just ["abcdef"]++prop_ex3 :: Property+prop_ex3 = withTests 1 $ property $ do+ x <- pure $ inlineFork [[inlinePlain "abc", inlinePlain "def"], [inlinePlain "ghi"]]+ preview (taglessContent TextStanza) x === Just ["abcdef", "ghi"]++prop_ex4 :: Property+prop_ex4 = withTests 1 $ property $ do+ x <- pure $ inlineFork [[inlinePlain "abc"]]+ preview (taglessContent TextStanza) x === Just ["abc"]++prop_ex5 :: Property+prop_ex5 = withTests 1 $ property $ do+ x <- pure $ inlineFork [[inlinePlain "abc", inlineFork []]]+ preview (taglessContent TextStanza) x === Nothing++prop_ex6 :: Property+prop_ex6 = withTests 1 $ property $ do+ x <- pure $ para [[inlinePlain "abc", inlineFork []]]+ preview (tagless TextStanza) x === Nothing++prop_ex7 :: Property+prop_ex7 = withTests 1 $ property $ do+ x <- pure $ para [[inlinePlain "abc", inlinePlain "def"]]+ preview (tagless TextStanza) x === Just ["abcdef"]++prop_ex8 :: Property+prop_ex8 = withTests 1 $ property $ do+ x <- pure $ btag [para [[inlinePlain "abc", inlinePlain "def"]]]+ preview (taglessContent TextStanza) x === Just ["abcdef"]++prop_ex9 :: Property+prop_ex9 = withTests 1 $ property $ do+ x <- pure $ ([para [[inlinePlain "abc", inlinePlain "def"]]] :: Blocks ())+ preview (tagless TextStanza) x === Just ["abcdef"]++prop_ex10 :: Property+prop_ex10 = withTests 1 $ property $ do+ x <- pure $ tbtag $ [para [[inlinePlain "abc"]]]+ preview (taglessContent TextStanza) x === Just ["abc"]++prop_ex11 :: Property+prop_ex11 = withTests 1 $ property $ do+ x <- pure $ tbtag $ [para [[inlinePlain "abc", inlinePlain "def"]]]+ preview (fork % content % (tagless TextStanza)) x === Just ["abcdef"]++prop_ex12 :: Property+prop_ex12 = withTests 1 $ property $ do+ x <- pure $ tbtag $ [para [[inlinePlain "abc", inlinePlain "def"], [inlinePlain "ghi"]]]+ preview (fork % content % (tagless TextStanza)) x === Just ["abcdef", "ghi"]