packages feed

wyvern-diagrams 0.4.1.0 → 0.4.2.0

raw patch · 9 files changed

+178/−73 lines, 9 filesdep −textdep −unordered-containersPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: text, unordered-containers

API changes (from Hackage documentation)

- Blocks: render :: [[Block]] -> Diagram B
- Blocks: render' :: [[Block]] -> Diagram B
+ Blocks: getAllIdentifiers :: Block -> [ID]
+ Blocks: getAllIdentifiers' :: [Block] -> [ID]
+ Blocks: renderDiagram :: [[Block]] -> Diagram B
+ Blocks: renderDiagram' :: [[Block]] -> Diagram B
+ Blocks: validateBlocks :: [[Block]] -> Either [[Block]] ([String], [ID])
+ Blocks: validateBlocks' :: [Block] -> Either [Block] ([String], [ID])
+ Blocks: validateSingleBlock :: Block -> [ID] -> (Bool, String)

Files

CHANGELOG.md view
@@ -1,4 +1,13 @@-## [0.4.1.0](https://github.com/PiotrJustyna/wyvern/tree/0.4.0.1) (2026-03-13)+## [0.4.2.0](https://github.com/PiotrJustyna/wyvern/tree/0.4.2.0) (2026-03-27)++Fixed bugs:++* [#63](https://github.com/PiotrJustyna/wyvern/issues/63) - clean up warnings+* [#66](https://github.com/PiotrJustyna/wyvern/issues/66) - remove unused dependency: unordered-containers+* [#67](https://github.com/PiotrJustyna/wyvern/issues/67) - connections overlapping+* [#68](https://github.com/PiotrJustyna/wyvern/issues/68) - gamma connection routing + validation++## [0.4.1.0](https://github.com/PiotrJustyna/wyvern/tree/0.4.1.0) (2026-03-13)  Fixed bug [#64](https://github.com/PiotrJustyna/wyvern/issues/64) - incorrect action token rendering. 
diagrams/temp.svg view
@@ -1,3 +1,3 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"-    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg font-size="1" viewBox="0.0 0.0 1920.0 1080.0" stroke="rgb(0,0,0)" xmlns="http://www.w3.org/2000/svg" width="1920.0000" stroke-opacity="1" height="1080.0000" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><defs></defs><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.36610394919274"><path d="M 960.0000,900.0000 v -720.0000 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.36610394919274"><path d="M 1824.0000,900.0000 h 0.0000 c 0.0000,-99.4113 -80.5887,-180.0000 -180.0000 -180.0000h -1368.0000 c -99.4113,-0.0000 -180.0000,80.5887 -180.0000 180.0000h 0.0000 c -0.0000,99.4113 80.5887,180.0000 180.0000 180.0000h 1368.0000 c 99.4113,0.0000 180.0000,-80.5887 180.0000 -180.0000Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="90.0px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.46441579677096"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,960.0000,900.0000)" stroke="none" dominant-baseline="middle" text-anchor="middle">end</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.36610394919274"><path d="M 1824.0000,180.0000 h 0.0000 c 0.0000,-99.4113 -80.5887,-180.0000 -180.0000 -180.0000h -1368.0000 c -99.4113,-0.0000 -180.0000,80.5887 -180.0000 180.0000h 0.0000 c -0.0000,99.4113 80.5887,180.0000 180.0000 180.0000h 1368.0000 c 99.4113,0.0000 180.0000,-80.5887 180.0000 -180.0000Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="90.0px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.46441579677096"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,960.0000,180.0000)" stroke="none" dominant-baseline="middle" text-anchor="middle">start</text></g></svg>+    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg font-size="1" viewBox="0.0 0.0 1920.0 1080.0" stroke="rgb(0,0,0)" xmlns="http://www.w3.org/2000/svg" width="1920.0000" stroke-opacity="1" height="1080.0000" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"><defs></defs><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1114.5316,477.7880 l -8.6203,4.9770 l 8.6203,4.9770 Z"/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 507.0968,721.6590 v 159.2627 h 746.5438 v -398.1567 h -139.4939 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1413.1491,79.6313 l -8.6203,4.9770 l 8.6203,4.9770 Z"/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1701.5668,323.5023 v 159.2627 h 159.2627 v -398.1567 h -448.0654 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,1030.2304 v 49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 199.6335,79.6313 l 8.6203,-4.9770 l -8.6203,-4.9770 Z"/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,1080.0000 h -149.3088 v -1005.3456 h 140.6884 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,74.6544 h 1194.4700 v 24.8848 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,223.9631 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,323.5023 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,532.5346 v -209.0323 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1522.3963,532.5346 h 0.0000 c 0.0000,-13.7435 -11.1413,-24.8848 -24.8848 -24.8848h -189.1244 c -13.7435,-0.0000 -24.8848,11.1413 -24.8848 24.8848h 0.0000 c -0.0000,13.7435 11.1413,24.8848 24.8848 24.8848h 189.1244 c 13.7435,0.0000 24.8848,-11.1413 24.8848 -24.8848Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,532.5346)" stroke="none" dominant-baseline="middle" text-anchor="middle">end</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1701.5668,423.0415 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,432.9954 v -9.9539 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1402.9493,423.0415 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1821.0138,447.9263 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1701.5668,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1522.3963,447.9263 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 1</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1537.3272,313.5484)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1383.0415,363.3180)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1293.4562,348.3871 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,323.5023)" stroke="none" dominant-baseline="middle" text-anchor="middle">question - headline 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1522.3963,248.8479 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,223.9631)" stroke="none" dominant-baseline="middle" text-anchor="middle">action - headline 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1283.5023,149.3088 v -49.7696 h 238.8940 v 49.7696 l -119.4470,9.9539 l -119.4470,-9.9539 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1402.9493,124.4240)" stroke="none" dominant-baseline="middle" text-anchor="middle">headline 2</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,124.4240 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,223.9631 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,622.1198 v -398.1567 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,721.6590 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,930.6912 v -209.0323 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,1030.2304 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 89.0323,1055.1152 v -49.7696 l 119.4470,-9.9539 l 119.4470,9.9539 v 49.7696 h -238.8940 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,1030.2304)" stroke="none" dominant-baseline="middle" text-anchor="middle">h2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,955.5760 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,930.6912)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 4</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 507.0968,821.1982 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,831.1521 v -9.9539 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,821.1982 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 626.5438,846.0829 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,507.0968,821.1982)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 3</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,846.0829 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,821.1982)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 2</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,342.8571,711.7051)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,188.5714,761.4747)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 98.9862,746.5438 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,721.6590)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 1</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,647.0046 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,622.1198)" stroke="none" dominant-baseline="middle" text-anchor="middle">action 1</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,572.3502 h 597.2350 v -49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,323.5023 v -99.5392 h -597.2350 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,522.5806 v -199.0783 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,323.5023 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,423.0415 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,572.3502 h 298.6175 v -49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1104.3318,522.5806 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,522.5806 h 0.0000 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 805.7143,522.5806 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 1223.7788,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,1104.3318,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 925.1613,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,805.7143,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,940.0922,413.0876)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,785.8065,462.8571)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 696.2212,447.9263 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,805.7143,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 0b</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 925.1613,348.3871 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,805.7143,323.5023)" stroke="none" dominant-baseline="middle" text-anchor="middle">action b</text></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,423.0415 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,572.3502 h 298.6175 v -49.7696 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 507.0968,522.5806 v -99.5392 h -298.6175 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,522.5806 h 0.0000 "/></g><g stroke-linejoin="miter" fill-opacity="0.0" fill="rgb(0,0,0)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 208.4793,522.5806 v -99.5392 "/></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 626.5438,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,507.0968,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,547.4654 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,522.5806)" stroke="none" dominant-baseline="middle" text-anchor="middle">unknown action</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,342.8571,413.0876)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,188.5714,462.8571)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 98.9862,447.9263 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,423.0415)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 0a</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,348.3871 l -0.0000,-49.7696 h -238.8940 l -0.0000,49.7696 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,323.5023)" stroke="none" dominant-baseline="middle" text-anchor="middle">action a</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,342.8571,214.0092)" stroke="none" dominant-baseline="middle" text-anchor="middle">no</text></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,188.5714,263.7788)" stroke="none" dominant-baseline="middle" text-anchor="middle">yes</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 98.9862,248.8479 l -9.9539,-24.8848 l 9.9539,-24.8848 h 218.9862 l 9.9539,24.8848 l -9.9539,24.8848 h -218.9862 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,223.9631)" stroke="none" dominant-baseline="middle" text-anchor="middle">question 0</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 89.0323,149.3088 v -49.7696 h 238.8940 v 49.7696 l -119.4470,9.9539 l -119.4470,-9.9539 Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,124.4240)" stroke="none" dominant-baseline="middle" text-anchor="middle">headline 1</text></g><g stroke-linejoin="miter" fill-opacity="1.0" fill="rgb(237,237,244)" stroke="rgb(160,194,222)" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="1.3949163792389583"><path d="M 327.9263,24.8848 h 0.0000 c 0.0000,-13.7435 -11.1413,-24.8848 -24.8848 -24.8848h -189.1244 c -13.7435,-0.0000 -24.8848,11.1413 -24.8848 24.8848h 0.0000 c -0.0000,13.7435 11.1413,24.8848 24.8848 24.8848h 189.1244 c 13.7435,0.0000 24.8848,-11.1413 24.8848 -24.8848Z"/></g><g stroke-linejoin="miter" fill-opacity="1.0" font-size="12.442396313364055px" fill="rgb(6,71,128)" stroke="rgb(0,0,0)" font-weight="300" font-family="helvetica" stroke-linecap="butt" stroke-miterlimit="10.0" stroke-opacity="1.0" stroke-width="5.579665516955833"><text transform="matrix(1.0000,0.0000,0.0000,1.0000,208.4793,24.8848)" stroke="none" dominant-baseline="middle" text-anchor="middle">start</text></g></svg>
diagrams/temp.txt view
@@ -1,9 +1,45 @@-"action 1"-"question 1"+h1 "headline 1" {-    123 456"action 2"+    0 "question 0"+    {+        0a "action a"+        0aq "question 0a"+        {+            0aqa1 "unknown action"+        }+        {+            0aqa2 "unknown action"+        }+    }+    {+        0b "action b"+        0bq "question 0b"+        {+            0bqa1 "unknown action"+        }+        {+            0bqa2 "unknown action"+        }+    }+    1 "action 1"+    q1 "question 1"+    {+        123 "action 2"+    }+    {+        "action 3" 0bqa2+    }+    4 "action 4"+    h2 }+h2 "headline 2" {-    "action 3"+    "action - headline 2"+    "question - headline 2"+    {+        "action 1"+    }+    {+        "action 2" h2+    } }-"action 4"
src/app/Main.hs view
@@ -1,6 +1,6 @@ module Main where -import Blocks (render)+import Blocks (renderDiagram, validateBlocks) import Constants (svgOptions) import Diagrams.Backend.SVG (renderSVG') import InputArguments (inputPath, outputPath, parseInput)@@ -8,29 +8,36 @@ import Options.Applicative (execParser, fullDesc, header, helper, info, (<**>)) import Parser (ParseResult (..), diagram) -main :: IO ()+main :: IO Int main = do   input <- execParser options   print input   fileContent <- readFile $ inputPath input -  -- lexer v1/v2-  -- let tokens = alexScanTokens fileContent--  -- putStrLn "tokens:"-  -- print tokens--  -- lexer v3   let lexingResult = runAlex fileContent lexAll    case lexingResult of-    Left lexingError -> do-      putStrLn $ "Wyvern failed with the following error: " <> lexingError-    Right tokens -> do-      -- print tokens-      case diagram tokens 1 of-        ParseOk d -> renderSVG' (outputPath input) svgOptions (Blocks.render d)-        ParseFail s -> error s+    Left lexingError ->+      do+        putStrLn $ "Wyvern failed with the following error: " <> lexingError+        return 1+    Right tokens ->+      do+        case diagram tokens 1 of+          ParseOk blocks -> do+            case validateBlocks blocks of+              Left validBlocks ->+                do+                  renderSVG' (outputPath input) svgOptions (Blocks.renderDiagram validBlocks)+                  return 0+              Right (errors, ids) ->+                do+                  putStrLn "Diagram validation failed with the following error(s):"+                  print errors+                  putStrLn "Available block identifiers to be used as gamma connections destinations:"+                  print ids+                  return 1+          ParseFail s -> error s   where     options =       info
src/lib/Blocks.hs view
@@ -1,14 +1,10 @@ module Blocks where -import Constants (defaultBoundingBoxHeight, defaultBoundingBoxWidth, heightRatio, widthRatio)-import Data.HashSet (HashSet, insert, member)-import Data.List (groupBy, sortBy, sortOn)+import Constants (defaultBoundingBoxHeight, defaultBoundingBoxWidth) import Data.Map (Map, empty, insert, lookup)-import Data.Ord (comparing) import Diagrams.Backend.SVG (B)-import Diagrams.Prelude (Diagram, Point (..), V2 (..), p2, position, r2, translate, (#))-import GHC.Float-import HelperDiagrams (renderConnection, renderGammaConnection, renderLowerBetaConnections, renderSideBetaConnection, renderText, renderUpperBetaConnections, wyvernAddress, wyvernHeadline, wyvernQuestion, wyvernRect, wyvernRoundedRect)+import Diagrams.Prelude (Diagram, Point (..), V2 (..), p2, position)+import HelperDiagrams (renderConnection, renderGammaConnection, renderLowerBetaConnections, renderSideBetaConnection, renderUpperBetaConnections, wyvernAddress, wyvernHeadline, wyvernQuestion, wyvernRect, wyvernRoundedRect) import ID  data Block@@ -25,7 +21,7 @@   foldl     ( \accu x ->         case x of-          Fork id content l r rId -> Fork id content (reverse' l) (reverse' r) rId : accu+          Fork i content l r rId -> Fork i content (reverse' l) (reverse' r) rId : accu           _ -> x : accu     )     []@@ -55,6 +51,17 @@ getIdentifier (Address i _) = i getIdentifier (Fork i _ _ _ _) = i +getAllIdentifiers' :: [Block] -> [ID]+getAllIdentifiers' = foldr (\singleBlock accu -> getAllIdentifiers singleBlock <> accu) []++getAllIdentifiers :: Block -> [ID]+getAllIdentifiers (Fork (Just i) _ l r _) = getAllIdentifiers' l <> getAllIdentifiers' r <> [i]+getAllIdentifiers (Fork Nothing _ l r _) = getAllIdentifiers' l <> getAllIdentifiers' r+getAllIdentifiers b =+  case getIdentifier b of+    Just i -> [i]+    Nothing -> []+ renderSingleBlock ::   Block ->   Point V2 Double ->@@ -62,16 +69,16 @@   [(Point V2 Double, Double, Double, ID)] ->   Double ->   (Diagram B, Map ID (Point V2 Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, Double)-renderSingleBlock fork@(Fork i c l r gCId) o@(P (V2 oX oY)) ds gCs globalMaxWidth =+renderSingleBlock (Fork _i c l r gCId) o@(P (V2 oX oY)) ds gCs globalMaxWidth =   let (gCW, gCH) = case gCId of         Nothing -> (0.0, 0.0)         Just _ -> (0.1, 0.1)-      (dQ, wQ, hQ) = (position [(o, wyvernQuestion c)], oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)+      (dQ, _wQ, hQ) = (position [(o, wyvernQuestion c)], oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)       lX = oX       lY = hQ       rX = maxWL       rY = hQ-      (dL, dsL, gCsL, wL, hL, maxWL, minHL) = renderSingleSkewer l (p2 (lX, lY)) ds gCs 0.0+      (dL, dsL, gCsL, _wL, _hL, maxWL, minHL) = renderSingleSkewer l (p2 (lX, lY)) ds gCs 0.0       (dR, dsR, gCsR, wR, hR, maxWR, minHR) = renderSingleSkewer r (p2 (rX, if null r then oY else rY)) dsL gCsL globalMaxWidth       newMaxW = maxWR + gCW       newMaxW' = max newMaxW globalMaxWidth@@ -96,11 +103,11 @@         newMaxW',         newMinH       )-renderSingleBlock StartTerminator o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernRoundedRect $ getContent StartTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)-renderSingleBlock EndTerminator o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernRoundedRect $ getContent EndTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)-renderSingleBlock (Headline _i c) o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernHeadline c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)-renderSingleBlock (Address _i c) o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernAddress c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)-renderSingleBlock b o@(P (V2 oX oY)) ds gCs abc = (position [(o, wyvernRect $ getContent b)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)+renderSingleBlock StartTerminator o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernRoundedRect $ getContent StartTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)+renderSingleBlock EndTerminator o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernRoundedRect $ getContent EndTerminator)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)+renderSingleBlock (Headline _i c) o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernHeadline c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)+renderSingleBlock (Address _i c) o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernAddress c)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)+renderSingleBlock b o@(P (V2 oX oY)) ds gCs _globalMaxWidth = (position [(o, wyvernRect $ getContent b)], ds, gCs, oX, oY, oX + defaultBoundingBoxWidth, oY - defaultBoundingBoxHeight)  renderSingleSkewer ::   [Block] ->@@ -109,19 +116,19 @@   [(Point V2 Double, Double, Double, ID)] ->   Double ->   (Diagram B, Map ID (Point V2 Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, Double)-renderSingleSkewer [] o@(P (V2 oX oY)) ds gCs globalWidth =+renderSingleSkewer [] (P (V2 oX oY)) ds gCs globalWidth =   let w = oX       minD = oY       localWidth = w + defaultBoundingBoxWidth       localWidth' = max globalWidth localWidth    in (mempty, ds, gCs, w, minD, localWidth', minD)-renderSingleSkewer [b] o@(P (V2 oX oY)) ds gCs globalWidth =+renderSingleSkewer [b] o@(P (V2 oX _oY)) ds gCs globalWidth =   let ds' = updateDestinations (getIdentifier b) o ds-      (d, ds'', gCs', w, h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth+      (d, ds'', gCs', _w, h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth    in (d, ds'', gCs', oX, h, maxW, minH) renderSingleSkewer (b : bs) o@(P (V2 oX oY)) ds gCs globalWidth =   let ds' = updateDestinations (getIdentifier b) o ds-      (d, ds'', gCs', w, h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth+      (d, ds'', gCs', _w, _h, maxW, minH) = renderSingleBlock b o ds' gCs globalWidth       (d', ds''', gCs'', w', h', maxW', minH') = renderSingleSkewer bs (p2 (oX, minH)) ds'' gCs' (maxW + 0.1)    in (d <> d' <> renderConnection [p2 (oX, minH), p2 (oX, oY)], ds''', gCs'', w', h', max maxW maxW', minH') @@ -136,26 +143,27 @@   [[Block]] ->   (Diagram B, Map ID (Point V2 Double), ([(Double, Double)], [(Double, Double, Double)], Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, [[Block]]) renderAllSkewers' rD ds bCs gCs w h maxH [] = (rD, ds, bCs, gCs, w, h, maxH, [])-renderAllSkewers' accuRD accuDs accuBCs@(uBCs, lBCs, minD) accuGCs accuW accuH accuMaxH [b] =-  let (rD, ds, gCs, w, h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW+renderAllSkewers' accuRD accuDs (uBCs, lBCs, minD) accuGCs accuW accuH _accuMaxH [b] =+  let (rD, ds, gCs, _w, _h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW    in renderAllSkewers' (accuRD <> rD) ds (uBCs, lBCs, min minD maxH) gCs maxW accuH (min minD maxH) []-renderAllSkewers' accuRD accuDs (uBCs, lBCs, minD) accuGCs accuW accuH accuMaxH (b : bs) =-  let (rD, ds, gCs, w, h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW+renderAllSkewers' accuRD accuDs (uBCs, lBCs, minD) accuGCs accuW accuH _accuMaxH (b : bs) =+  let (rD, ds, gCs, _w, h, maxW, maxH) = renderSingleSkewer b (p2 (accuW, accuH)) accuDs accuGCs accuW    in renderAllSkewers' (accuRD <> rD) ds ((accuW, maxW) : uBCs, (accuW, maxW, h) : lBCs, min minD maxH) gCs maxW accuH (min minD maxH) bs  renderAllSkewers :: [[Block]] -> (Diagram B, Map ID (Point V2 Double), ([(Double, Double)], [(Double, Double, Double)], Double), [(Point V2 Double, Double, Double, ID)], Double, Double, Double, [[Block]])+renderAllSkewers [] = error "no skewers provided" renderAllSkewers blocks@(b : bs) =   let manyBlocks = length blocks > 2-      (rD, ds, (uBCs, lBCs, minD), gCs, w, h, maxH, _) = renderAllSkewers' mempty Data.Map.empty ([], [], 0.0) [] 0.0 0.0 0.0 [b]+      (rD, ds, (uBCs, lBCs, minD), gCs, w, _h, maxH, _) = renderAllSkewers' mempty Data.Map.empty ([], [], 0.0) [] 0.0 0.0 0.0 [b]       uBCs' = if null bs then uBCs else (0.0, w) : uBCs       lBCs' = if null bs then lBCs else (0.0, w, maxH) : lBCs       (rD', ds', (uBCs'', lBCs'', minD'), gCs', w', h', maxH', _) = renderAllSkewers' rD ds (uBCs', lBCs', minD) gCs w (negate defaultBoundingBoxHeight) maxH bs    in (rD', ds', (uBCs'', lBCs'', minD'), gCs', w', h', if manyBlocks then maxH' else maxH, b : bs) -render' :: [[Block]] -> Diagram B-render' [] = mempty-render' bs =-  let (rD', ds', (uBCs, lBCs, minD), gCs', w', h', maxH', _) = renderAllSkewers bs+renderDiagram' :: [[Block]] -> Diagram B+renderDiagram' [] = mempty+renderDiagram' bs =+  let (rD', ds', (uBCs, lBCs, _minD), gCs', _w', _h', maxH', _) = renderAllSkewers bs       bCs = case length bs of         1 -> mempty         _ ->@@ -172,9 +180,49 @@         (rD' <> bCs)         gCs' -render :: [[Block]] -> Diagram B-render [] = mempty-render [b] = render' $ Blocks.reverse [(EndTerminator : b) <> [StartTerminator]]-render bs =-  let bs' = tail bs-   in render' . Blocks.reverse $ ((EndTerminator : head bs) : init bs') <> [last bs' <> [StartTerminator]]+renderDiagram :: [[Block]] -> Diagram B+renderDiagram [] = mempty+renderDiagram [b] = renderDiagram' $ Blocks.reverse [(EndTerminator : b) <> [StartTerminator]]+renderDiagram (b : bs) = renderDiagram' . Blocks.reverse $ ((EndTerminator : b) : init bs) <> [last bs <> [StartTerminator]]++validateSingleBlock :: Block -> [ID] -> (Bool, String)+validateSingleBlock (Fork (Just i) _ _ _ (Just gCId)) ids = if gCId == i || gCId `elem` ids then (True, "") else (False, "Gamma connection ID: " <> show gCId <> " does not exist in the collection of block identifiers.")+validateSingleBlock (Fork Nothing _ _ _ (Just gCId)) ids = if gCId `elem` ids then (True, "") else (False, "Gamma connection ID: " <> show gCId <> " does not exist in the collection of block identifiers.")+validateSingleBlock (Fork _ _ _ _ Nothing) _ = (True, "")+validateSingleBlock _ _ = (True, "")++validateBlocks' :: [Block] -> Either [Block] ([String], [ID])+validateBlocks' [] = Left []+validateBlocks' [b] = Left [b]+validateBlocks' bs =+  let (errors, ids) =+        foldr+          ( \singleBlock (accuErrors, accuIds) ->+              let (isValid, errorMessage) = validateSingleBlock singleBlock accuIds+               in (if isValid then accuErrors else errorMessage : accuErrors, getAllIdentifiers singleBlock <> accuIds)+          )+          ([], [])+          bs+   in case errors of+        [] -> Left bs+        _ -> Right (errors, ids)++validateBlocks :: [[Block]] -> Either [[Block]] ([String], [ID])+validateBlocks [] = Left []+validateBlocks (b : []) =+  case validateBlocks' b of+    Left b' -> Left [b']+    Right errors -> Right errors+validateBlocks bs =+    let validationResult@(allErrors, allIds) =+                                foldl+                                ( \accu@(accuErrors, accuIds) b ->+                                    case validateBlocks' b of+                                        Left _ -> accu+                                        Right (errors, ids) -> (errors <> accuErrors, ids <> accuIds)+                                )+                                ([], [])+                                bs+    in case allErrors of+        [] -> Left bs+        _ -> Right validationResult
src/lib/Constants.hs view
@@ -1,7 +1,6 @@ module Constants where  import Data.Colour.SRGB (sRGB)-import Data.Text (empty) import Diagrams.Backend.SVG   ( B,     Options (SVGOptions),@@ -50,7 +49,6 @@ svgOptions =   SVGOptions     { _size = mkSizeSpec $ V2 (Just 1920) (Just 1080),-      _idPrefix = empty,       _svgDefinitions = Nothing,       _svgAttributes = [],       _generateDoctype = True
src/lib/HelperDiagrams.hs view
@@ -128,12 +128,19 @@ renderConnection :: [Point V2 Double] -> Diagram B renderConnection coordinates = fromVertices coordinates # wyvernStyle +-- 2026-03-25 PJ:+-- ##############+-- TODO:++-- * we need a max x for the destination block++--   we only have the max x for the origin block renderGammaConnection :: Point V2 Double -> Point V2 Double -> Double -> Double -> Diagram B renderGammaConnection gO@(P (V2 gOX gOY)) gD@(P (V2 gDX gDY)) maxX minY =-  let gD'@(P (V2 gDX' gDY')) = p2 (gDX + (0.1 * sqrt 3.0 / 2.0) + 0.012, gDY + defaultBoundingBoxHeight * 0.5)+  let gD'@(P (V2 gDX' gDY')) = p2 (gDX + (0.1 * sqrt 3.0 / 2.0) + 0.012, gDY + defaultBoundingBoxHeight * 0.5 - 0.1)       gammaMidpoint1 = p2 (gOX, minY)-      gammaMidpoint2 = p2 (maxX - defaultBoundingBoxWidth * 0.5, minY)-      gammaMidpoint3 = p2 (maxX - defaultBoundingBoxWidth * 0.5, gDY')+      gammaMidpoint2 = p2 (if gDX > gOX then gDX + defaultBoundingBoxWidth * 0.5 else maxX - defaultBoundingBoxWidth * 0.5, minY)+      gammaMidpoint3 = p2 (if gDX > gOX then gDX + defaultBoundingBoxWidth * 0.5 else maxX - defaultBoundingBoxWidth * 0.5, gDY')       coordinates = [gO, gammaMidpoint1, gammaMidpoint2, gammaMidpoint3, gD']    in renderConnection coordinates <> position [(p2 (gDX' - 0.025, gDY'), rotateBy (1 / 4) $ triangle 0.1 # wyvernStyle)] @@ -145,7 +152,7 @@       p2 (uBCb, maxD + defaultBoundingBoxHeight * 0.5),       p2 (uBCb, maxD + defaultBoundingBoxHeight * heightRatio * 0.5)     ]-renderUpperBetaConnections (uBC@(uBCa, uBCb) : uBCs) maxD =+renderUpperBetaConnections ((uBCa, uBCb) : uBCs) maxD =   renderConnection     [ p2 (uBCa, maxD + defaultBoundingBoxHeight * 0.5),       p2 (uBCb, maxD + defaultBoundingBoxHeight * 0.5),@@ -154,7 +161,7 @@     <> renderUpperBetaConnections uBCs maxD  renderSideBetaConnection :: Point V2 Double -> Point V2 Double -> Diagram B-renderSideBetaConnection a@(P (V2 aX aY)) b@(P (V2 bX bY)) =+renderSideBetaConnection a@(P (V2 aX aY)) (P (V2 bX bY)) =   renderConnection     [ a,       p2 (aX - defaultBoundingBoxWidth * 0.5, aY),@@ -165,12 +172,12 @@  renderLowerBetaConnections' :: [(Double, Double, Double)] -> Double -> Diagram B renderLowerBetaConnections' [] _ = mempty-renderLowerBetaConnections' (lBC@(lBCa, lBCb, lBCc) : lBCs) minD =+renderLowerBetaConnections' ((lBCa, lBCb, lBCc) : lBCs) minD =   renderConnection [p2 (lBCa, lBCc + defaultBoundingBoxHeight), p2 (lBCa, minD), p2 (lBCb, minD)]     <> renderLowerBetaConnections' lBCs minD  renderLowerBetaConnections :: [(Double, Double, Double)] -> Double -> Diagram B renderLowerBetaConnections [] _ = mempty-renderLowerBetaConnections (lBC@(lBCa, lBCb, lBCc) : lBCs) minD =+renderLowerBetaConnections ((lBCa, _lBCb, lBCc) : lBCs) minD =   renderConnection [p2 (lBCa, lBCc + defaultBoundingBoxHeight), p2 (lBCa, minD)]     <> renderLowerBetaConnections' lBCs minD
src/lib/ID.hs view
@@ -2,7 +2,6 @@  newtype ID   = ID String-  deriving (Show)  instance Eq ID where   (==) (ID a) (ID b) = a == b@@ -15,3 +14,6 @@   (<=) (ID a) (ID b) = a <= b   min (ID a) (ID b) = ID $ min a b   max (ID a) (ID b) = ID $ max a b++instance Show ID where+  show (ID x) = show x
wyvern-diagrams.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.4 name:               wyvern-diagrams-version:            0.4.1.0+version:            0.4.2.0 synopsis:           Simple flowchart diagrams. Inspired by DRAKON. description:        Wyvern combines syntax and rendering engine                     for simple, DRAKON-like flowcharts.@@ -38,8 +38,6 @@                       base >= 4.19.2.0 && < 5,                       -- MIT                       colour >= 2.3.6 && < 3,-                      -- BSD-2-Clause-                      text >= 2.1.2 && < 3,                       -- BSD-3-Clause                       diagrams-lib >= 1.5.1 && < 2,                       -- BSD-3-Clause@@ -47,11 +45,11 @@                       -- BSD-3-Clause                       containers >= 0.7 && < 1,                       -- BSD-3-Clause+                      -- Used in Parser.                       MissingH >= 1.6.0 && < 2,                       -- BSD-3-Clause+                      -- Used in Lexer.                       array >= 0.5.8 && < 1,-                      -- BSD-3-Clause-                      unordered-containers >= 0.2.21 && < 1,                       -- BSD-3-Clause                       optparse-applicative >= 0.19.0 && < 1     default-language: Haskell2010