Optimizing the links from the Glamorous Toolkit book for first time readers
Writing isolated pieces of documentation can be entertaining, but sometimes we want to enhance the findability of those pieces. Linking them with other pieces can be a good path to achieve this.
We actually had this very same problem when writing the Glamorous Toolkit book: We wanted to make it possible for people to start at the "Get started"
page and have the chance to reach as many pages as possible by following direct links.
To ease the finding of new linking opportunities, we can visualize the situation. We start by collecting all the pages from the book. We leave out the table of contents page because that one links everything.
database := LeDatabasesRegistry default currentLoadedDefaultLogicalDatabase databaseNamed: 'Glamorous Toolkit Book'. pages := database pages reject: [ :each | each title = 'Glamorous Toolkit Book' ].
We find the Get started
page:
getStartedPage := pages detect: [:each | each title = 'Get started'].
We collect the pages that are reachable from by traversing deeply all the outgoing links:
allReachedPages := getStartedPage deepCollectAsSet: [:each | each allChildOutgoingTextualLinks collect: [:x | x target ifNotNil: #page] ].
Then we take a quick look at the graph:
m := GtMondrian new. m nodes stencil: [ :each | BlShrinkingTextElement new text: each title asRopedText glamorousRegularFont; background: (Color white alpha: 0.5); constraintsDo: [:c | c horizontal exact: 70. c vertical fitContent ]; when: BlClickEvent do: [ :e | e currentTarget phlow spawnTool: each asPhlowTool ] ]; with: (allReachedPages). m edges stencil: [ BlLineElement new border: Color veryLightGray; toHead: (BlArrowheadSimpleArrow new border: Color veryLightGray); zIndex: -1 ]; connectToAll: [ :page | page allOutgoingTextualLinks collectAsSet: #target ]. m layout custom: (GtGraphHorizontalTreeLayout new levelDistance: 20). m

Ok, but a better view would be to see these pages in the context of the entire graph:
m := GtMondrian new. m nodes stencil: [ :each | | color size | color := (allReachedPages includes: each) ifTrue: [ Color red ] ifFalse: [ Color black ]. size := 5 @ 5. each = getStartedPage ifTrue: [ color := Color blue. size := 10 @ 10 ]. BlElement new background: color; size: size; when: BlClickEvent do: [ :e | e currentTarget phlow spawnTool: each asPhlowTool ] ]; with: pages. m edges stencil: [ BlLineElement new border: Color veryLightGray; toHead: (BlArrowheadSimpleArrow new border: Color veryLightGray); zIndex: -1 ]; connectToAll: [ :page | page allOutgoingTextualLinks collectAsSet: #target ]. m layout force nbIterations: 30; charge: -50. m
And we get this:

So, now we have an idea of the parts of the book that are not reachable. But would it not be better to show the pages as they are in the book table of contents instead of as a graph of links? Let's try.
First, we assemble the data structures. Here we traverse the table of contents page itself and get the links from each snippet.
tocPage := database pages detect: [ :each | each title = 'Glamorous Toolkit Book' ]. allTocSnippets := tocPage allChildrenBreadthFirst.
And then we put it together in a simple visualization of the snippets that uses allReachedPages
computed above to highlight the corresponding snippets:
m := GtMondrian new. m nodes stencil: [ :each | | title color | title := (each contentAsString removePrefix: '[[') removeSuffix: ']]'. color := Color gray alpha: 0.2. (allReachedPages anySatisfy: [ :aPage | aPage title = title ]) ifTrue: [ color := Color red alpha: 0.4 ]. title = 'Get started' ifTrue: [ color := Color blue alpha: 0.6 ]. BlShrinkingTextElement new constraintsDo: [:c |c horizontal exact: 300. c vertical fitContent]; background: color; text: title asRopedText glamorousRegularFont; when: BlClickEvent do: [:e | e consumed: true. e target phlow spawnObject: (each outgoingExplicitLinks anyOne target)] ]; with: allTocSnippets. m edges fromRightCenter; toLeftCenter; connectToAll: #children. m layout custom: (GtGraphHorizontalTreeLayout new levelDistance: 150). m
This now gives us a view that is closer to the mental model of a book.

The tree shows pages. But some pages are longer than others, and it can be useful sometimes to also show the size of pages.
To this end, we can count the words from the text representation of a page:
sizeCounter := [ :aPage | ((String cr join: (aPage allChildrenBreadthFirst collect: #contentAsString)) piecesCutWhere: [ :a :b | a isSeparator ]) size ]. maxSize := pages max: sizeCounter.
And then we enhance the visualization:
m := GtMondrian new. m nodes stencil: [ :each | | title color linkedPage | linkedPage := each outgoingExplicitLinks anyOne target. title := linkedPage title. color := Color gray alpha: 0.2. (allReachedPages anySatisfy: [ :aPage | aPage title = title ]) ifTrue: [ color := Color red alpha: 0.4 ]. title = 'Get started' ifTrue: [ color := Color blue alpha: 0.6 ]. BlShrinkingTextElement new constraintsDo: [ :c | c horizontal exact: (((sizeCounter value: linkedPage) / maxSize * 500) max: 30). c vertical fitContent ]; background: color; text: title asRopedText glamorousRegularFont; padding: (BlInsets all: 2); when: BlClickEvent do: [ :e | e consumed: true. e target phlow spawnObject: linkedPage ] ]; with: allTocSnippets. m edges fromRightCenter; toLeftCenter; connectToAll: #children. m layout custom: (GtGraphHorizontalTreeLayout new levelDistance: 100; layered). m

Of course, in a world of executable snippets, we can find other interesting measurements than words. For example, we can also consider the amount of snippets in a page.
sizeCounter := [ :aPage | aPage allChildrenBreadthFirst size ]. maxSize := pages max: snippetsCounter.
We used these visualizations actively while working on the Glamorous Toolkit book. We've done it from inside the environment in which the book is delivered. And you can even find this page as a case study in the book itself.