diff --git a/dotparse.cabal b/dotparse.cabal
--- a/dotparse.cabal
+++ b/dotparse.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: dotparse
-version: 0.1.2.2
+version: 0.1.2.3
 license: BSD-3-Clause
 license-file: LICENSE
 copyright: Tony Day (c) 2020
@@ -11,83 +11,102 @@
 bug-reports: https://github.com/tonyday567/dotparse/issues
 synopsis: dot language parsing and printing.
 description:
-    This package provides parsing and printing of the dot language.
+  This package provides parsing and printing of the dot language.
 
-    == Usage
+  == Usage
 
-    >>> :set -XOverloadedLabels
-    >>> :set -XOverloadedStrings
-    >>> import DotParse
-    >>> import Chart
-    >>> import Data.Text (pack)
-    >>> import DotParse.Examples (exInt)
-    >>> ex <- processGraph exInt
-    >>> writeChartOptions "other/exga.svg" (graphToChart ex)
+  >>> :set -XOverloadedLabels
+  >>> :set -XOverloadedStrings
+  >>> import DotParse
+  >>> import Chart
+  >>> import Data.Text (pack)
+  >>> import DotParse.Examples (exInt)
+  >>> ex <- processGraph exInt
+  >>> writeChartOptions "other/exga.svg" (graphToChart ex)
 
-    ![usage example](docs/other/exga.svg)
+  ![usage example](docs/other/exga.svg)
 
 build-type: Simple
 tested-with:
-    , GHC == 9.10.1
-    , GHC == 9.12.2
-    , GHC == 9.6.7
-    , GHC == 9.8.4
+  ghc ==9.6.7
+  ghc ==9.8.4
+  ghc ==9.10.1
+  ghc ==9.12.2
+
 extra-doc-files:
-    ChangeLog.md
-    other/*.svg
-    readme.md
+  ChangeLog.md
+  other/*.svg
+  readme.md
 
 source-repository head
-    type: git
-    location: https://github.com/tonyday567/dotparse
+  type: git
+  location: https://github.com/tonyday567/dotparse
 
 common ghc-options-stanza
-    ghc-options:
-        -Wall
-        -Wcompat
-        -Widentities
-        -Wincomplete-record-updates
-        -Wincomplete-uni-patterns
-        -Wpartial-fields
-        -Wredundant-constraints
+  ghc-options:
+    -Wall
+    -Wcompat
+    -Widentities
+    -Wincomplete-record-updates
+    -Wincomplete-uni-patterns
+    -Wpartial-fields
+    -Wredundant-constraints
 
-common ghc2021-stanza
-    default-language: GHC2021
+common ghc2024-additions
+  default-extensions:
+    DataKinds
+    DerivingStrategies
+    DisambiguateRecordFields
+    ExplicitNamespaces
+    GADTs
+    LambdaCase
+    MonoLocalBinds
+    RoleAnnotations
 
+common ghc2024-stanza
+  if impl(ghc >=9.10)
+    default-language:
+      GHC2024
+  else
+    import: ghc2024-additions
+    default-language:
+      GHC2021
+
 library
-    import: ghc-options-stanza
-    import: ghc2021-stanza
-    hs-source-dirs: src
-    build-depends:
-        , algebraic-graphs   >=0.6 && <0.8
-        , base               >=4.14 && <5
-        , bytestring         >=0.11.3 && <0.13
-        , chart-svg          >=0.6 && <0.9
-        , containers         >=0.6 && <0.9
-        , flatparse          >=0.3.5 && <0.6
-        , numhask-space      >=0.10 && <0.14
-        , optics-core        >=0.4 && <0.5
-        , process-extras     >=0.7.4 && <0.8
-        , string-interpolate >=0.3 && <0.4
-        , template-haskell   >=2.16 && <2.24
-        , text               >=1.2 && <2.2
-        , these              >=1.1 && <1.3
-    exposed-modules:
-        DotParse
-        DotParse.Examples
-        DotParse.Examples.AST
-        DotParse.Examples.NumHask
-        DotParse.FlatParse
-        DotParse.FlatParse.TH
-        DotParse.Types
+  import: ghc-options-stanza
+  import: ghc2024-stanza
+  hs-source-dirs: src
+  build-depends:
+    algebraic-graphs >=0.6 && <0.8,
+    base >=4.14 && <5,
+    bytestring >=0.11.3 && <0.13,
+    chart-svg >=0.6 && <0.9,
+    containers >=0.6 && <0.9,
+    flatparse >=0.3.5 && <0.6,
+    numhask-space >=0.10 && <0.14,
+    optics-core >=0.4 && <0.5,
+    process-extras >=0.7.4 && <0.8,
+    string-interpolate >=0.3 && <0.4,
+    template-haskell >=2.16 && <2.24,
+    text >=1.2 && <2.2,
+    these >=1.1 && <1.3,
 
+  exposed-modules:
+    DotParse
+    DotParse.Examples
+    DotParse.Examples.AST
+    DotParse.Examples.NumHask
+    DotParse.FlatParse
+    DotParse.FlatParse.TH
+    DotParse.Types
+
 test-suite doctests
-    import: ghc2021-stanza
-    main-is: doctests.hs
-    hs-source-dirs: test
-    build-depends:
-        , base             >=4.14 && <5
-        , doctest-parallel >=0.3 && <0.4
-        , dotparse
-    ghc-options: -threaded
-    type: exitcode-stdio-1.0
+  import: ghc2024-stanza
+  main-is: doctests.hs
+  hs-source-dirs: test
+  build-depends:
+    base >=4.14 && <5,
+    doctest-parallel >=0.3 && <0.5,
+
+  ghc-options: -threaded
+  type: exitcode-stdio-1.0
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -1,29 +1,6 @@
-
-# Table of Contents
-
-1.  [Introduction](#orgf187caa)
-    1.  [Reference](#org9cbd848)
-    2.  [Similar projects](#orgdec9e8f)
-    3.  [development wish list](#org97f432e)
-2.  [process pipelines](#orgd1d85da)
-    1.  [algebraic-graphs](#orgfab6886)
-    2.  [dotparse Graph](#orgb18c248)
-    3.  [dotPrint](#org3454fc8)
-    4.  [processDotWith](#org32b8f10)
-    5.  [processDot](#org73a9a3b)
-    6.  [processGraph](#org15407d1)
-    7.  [graphToChartWith](#orgf541717)
-3.  [Development](#org7bb46ff)
-    1.  [imports](#org2f672d9)
-    2.  [testAll](#orgee189c9)
-    3.  [numhask](#org176b014)
-4.  [chart-svg AST](#org223882c)
-
-[![img](https://img.shields.io/hackage/v/dotparse.svg)](https://hackage.haskell.org/package/dotparse) [![img](https://github.com/tonyday567/dotparse/workflows/haskell-ci/badge.svg)](https://github.com/tonyday567/chart-svg/actions?query=workflow%3Ahaskell-ci)
+[![img](https://img.shields.io/hackage/v/dotparse.svg)](https://hackage.haskell.org/package/dotparse) [![img](https://github.com/tonyday567/dotparse/actions/workflows/haskell-ci.yml/badge.svg)](https://github.com/tonyday567/dotparse/actions/workflows/haskell-ci.yml)
 
 
-<a id="orgf187caa"></a>
-
 # Introduction
 
 Parsing and printing for the dot language of graphviz.
@@ -37,8 +14,6 @@
 -   Uses [flatparse](https://hackage.haskell.org/package/flatparse) for speedy parsing.
 
 
-<a id="org9cbd848"></a>
-
 ## Reference
 
 Graphviz documentation:
@@ -58,8 +33,6 @@
 <https://renenyffenegger.ch/notes/tools/Graphviz/attributes/label/HTML-like/index>
 
 
-<a id="orgdec9e8f"></a>
-
 ## Similar projects
 
 The [graphviz](https://hackage.haskell.org/package/graphviz) library aims for comprehensive typing of graphviz attributes and syntax. As a result, it is quite large and somewhat incomplete. In contrast, dotparse parsing is simpler, more robust and faster. It is also somewhat tied to fgl and I wanted to try a different graph library.
@@ -67,8 +40,6 @@
 [dotgen](https://hackage.haskell.org/package/dotgen) is a dot graph printer but not a parser. It supports a monadic style of printing. Specifically, it supports generation of unique names if that is an important feature of the problem domain.
 
 
-<a id="org97f432e"></a>
-
 ## development wish list
 
 Target [calligraphy](https://hackage.haskell.org/package/calligraphy) for enhanced source code visualization.
@@ -82,13 +53,9 @@
 Steal design ideas from [jordan](https://hackage.haskell.org/package/jordan).
 
 
-<a id="orgd1d85da"></a>
-
 # process pipelines
 
 
-<a id="orgfab6886"></a>
-
 ## algebraic-graphs
 
 Starting with a Graph from algebraic-graphs:
@@ -110,8 +77,6 @@
     Overlay (Connect (Vertex 0) (Vertex 1)) (Overlay (Connect (Vertex 1) (Vertex 2)) (Overlay (Connect (Vertex 2) (Vertex 3)) (Overlay (Connect (Vertex 3) (Vertex 4)) (Overlay (Connect (Vertex 4) (Vertex 5)) (Overlay (Connect (Vertex 5) (Vertex 0)) (Overlay (Connect (Vertex 0) (Vertex 6)) (Overlay (Connect (Vertex 0) (Vertex 12)) (Overlay (Connect (Vertex 1) (Vertex 7)) (Overlay (Connect (Vertex 1) (Vertex 13)) (Overlay (Connect (Vertex 2) (Vertex 8)) (Overlay (Connect (Vertex 2) (Vertex 14)) (Overlay (Connect (Vertex 3) (Vertex 9)) (Overlay (Connect (Vertex 3) (Vertex 15)) (Overlay (Connect (Vertex 4) (Vertex 10)) (Overlay (Connect (Vertex 4) (Vertex 16)) (Overlay (Connect (Vertex 5) (Vertex 11)) (Overlay (Connect (Vertex 5) (Vertex 17)) (Overlay (Connect (Vertex 2) (Vertex 18)) (Overlay (Connect (Vertex 2) (Vertex 19)) (Overlay (Connect (Vertex 15) (Vertex 18)) (Overlay (Connect (Vertex 15) (Vertex 19)) (Overlay (Connect (Vertex 18) (Vertex 3)) (Connect (Vertex 19) (Vertex 3))))))))))))))))))))))))
 
 
-<a id="orgb18c248"></a>
-
 ## dotparse Graph
 
 Convert to a dotparse Graph
@@ -119,8 +84,6 @@
     exGraph = defaultGraph & addStatements (toStatements Directed (Char8.pack . show <$> exAGraph))
 
 
-<a id="org3454fc8"></a>
-
 ## dotPrint
 
 Encode graph as a ByteString (prior to processing via graphviz)
@@ -178,8 +141,6 @@
         }
 
 
-<a id="org32b8f10"></a>
-
 ## processDotWith
 
 Directly create an SVG from the dotparse Graph
@@ -189,8 +150,6 @@
 ![img](other/exdirect.svg)
 
 
-<a id="org73a9a3b"></a>
-
 ## processDot
 
 ByteString of the processed Graph
@@ -198,8 +157,6 @@
     BS.putStr =<< processDot Directed (dotPrint defaultDotConfig exInt)
 
 
-<a id="org15407d1"></a>
-
 ## processGraph
 
 Graph augmented by graphviz
@@ -210,8 +167,6 @@
     exGraphAugmented :: Graph
 
 
-<a id="orgf541717"></a>
-
 ## graphToChartWith
 
 SVG production via chart-svg
@@ -222,13 +177,9 @@
 ![img](other/exga.svg)
 
 
-<a id="org7bb46ff"></a>
-
 # Development
 
 
-<a id="org2f672d9"></a>
-
 ## imports
 
     :reload
@@ -258,8 +209,6 @@
     "ok"
 
 
-<a id="orgee189c9"></a>
-
 ## testAll
 
 Round-trip test
@@ -284,15 +233,11 @@
     ex15
 
 
-<a id="org176b014"></a>
-
 ## numhask
 
     g <- processGraph (dotGraphNH Directed)
     writeChartOptions "other/nh12.svg" (graphToChartWith (defaultChartConfig & set #chartVshift (-4) & set #textSize 12) toLinkNH g)
 
-
-<a id="org223882c"></a>
 
 # chart-svg AST
 
