packages feed

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 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"]