" Pillar ASText delegates the text behavior into a pillar AST . " Class { #name : #GrafoscopioPillarASText, #superclass : #GrafoscopioAbstractText, #instVars : [ 'ast', 'stringDecorator', 'lastNode' ], #category : 'Grafoscopio-Pillar' } { #category : #'as yet unclassified' } GrafoscopioPillarASText class >> openExample [ ^ self new ast: self pillarExample; yourself ] { #category : #'as yet unclassified' } GrafoscopioPillarASText class >> pillarExample [ ^ PRPillarParser parse: '!!我是三條 About Pillar !! Pillar is a system to manage documents (books, presentations, and web sites). From a common format, it is able to generate documents in multiple formats (html, markdown, latex, AsciiDoc). It is composed of several modules such as importers, transformers, document model and outputers. This book describes Pillar in its current version 7.0. Pillar is currently developed and masintained by Stéphane Ducasse and Guillermo Polito. The original author of Pillar was Damien Cassou. Many people have also contributed to Pillar: Ben Coman, Guillermo Polito, Lukas Renggli (original author of the PierCMS from which a first version of Pillar has been extracted), Benjamin van Ryseghem, Cyril Ferlicot-Delbecque, Thibault Arloing, Yann Dubois, Quentin Ducasse and Asbathou Sama Biyalou. Special thanks to Asbathou Sama Biyalou! This book adapts, extends, and clarifies the chapter explaining Pillar in the ''Enterprise Pharo: a Web Perspective'' book. Pillar was sponsored by *ESUG>http://www.esug.org*. !!!Introduction Pillar (hosted at *http://github.com/pillar-markup*) is a markup language and associated tools to write and generate documentation, books (such as this one), web sites, and slide-based presentations. The Pillar screenshot in Figure *@voyageDocExample* shows the HTML version of chapter Voyage. +An example Pillar output>file://figures/voyageDocExample-small.png|label=voyageDocExample|width=60+ Pillar has many features, helpful tools, and documentation: - simple markup syntax with references, tables, pictures, captions, syntax-highlighted code blocks; - export documents to HTML, LaTeX, Markdown, AsciiDoc, ePuB and Pillar itself, and presentations to Beamer and Deck.js; %- customization of the export through a dedicated STON configuration file (see chapter Missing Chapter *@cha:ston*) and Mustache templates (see chapter *@templating*). - many tests with good coverage (94% with more than a 2100 executed tests), which are regularly run by a *continuous integration job>https://ci.inria.fr/pharo-contribution/job/Pillar* - a command-line interface and dedicated plugins for several text editors: *Emacs>https://github.com/pillar-markup/pillar-mode*, *Vim>https://github.com/cdlm/vim-pillar*, *TextMate>https://github.com/Uko/Pillar.tmbundle*, and *Atom>https://github.com/Uko/language-pillar* - a cheat sheet (see Chapter *@chacheat*). !!!Pillar users @pillarUSERS This book was written in Pillar itself. If you want to see how Pillar is used, have a look at its source code (*http://github.com/SquareBracketAssociates/Booklet-PublishingAPillarBooklet*), or check the following other real-world projects: - the Updated Pharo by Example book (*https://github.com/SquareBracketAssociates/UpdatedPharoByExample*), - the Pharo MOOC - Massive open online course (*https://github.com/SquareBracketAssociates/PharoMooc*, - Any of the Pharo booklets (*https://github.com/SquareBracketAssociates/Booklet-XXXX*, - the PillarHub open-access shared blog (*http://pillarhub.pharocloud.com*). !!! Pillar future features Pillar 70 saw some major refactorings and cleaning: it does not rely on Grease and Magritte anymore. Its architecture is a lot cleaner. Still some issues are missing. Here is a little list of features that we are working on or will soon: - Incremental recompilation. Since we remove the use of make (so that Windows users can use Pillar) we should introduce a way to avoid to recompile complete book when just one chapter changed. - Markdown syntax. - Release of Ecstatic. Pillar supports the deployment of web sites named Ecstatic and we are working on a second version of Ecstatic. - Better table support. !!! Conclusion Pillar is still in active development: maintainers keep improving its implementation. The current version of Pillar is Pillar 70. This booklet only documents Pillar 70. This booklet will be synchronised with future enhancements.' ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> allRangesOfSubstring: aString [ ^ { } ] { #category : #removing } GrafoscopioPillarASText >> allSegmentsOfLinesCollect: aBlock [ | return chunk | return := OrderedCollection new. chunk := OrderedCollection new. " This method puts together many different nodes togehter into one line. Each line finishes with a breakline. The last one maybe not ." self allTextNodesDo: [ :node | chunk add: node. node isLineBreak ifTrue: [ return add: (aBlock value: chunk first textStart value: chunk last textStop). chunk removeAll ] ]. chunk ifNotEmpty: [ return add: (aBlock value: chunk first textStart value: chunk last textStop) ]. ^ return ] { #category : #removing } GrafoscopioPillarASText >> allSegmentsOfLinesDo: aBlock [ | chunk | chunk := OrderedCollection new. " This method puts together many different nodes togehter into one line. Each line finishes with a breakline. The last one maybe not ." self allTextNodesDo: [ :node | chunk add: node. node isLineBreak ifTrue: [ aBlock value: chunk first textStart value: chunk last textStop. chunk removeAll ] ]. chunk ifNotEmpty: [ aBlock value: chunk first textStart value: chunk last textStop ] ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> allTextNodesDo: aBlock [ ^ self allTextNodesFrom: ast do: aBlock ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> allTextNodesFrom: aNode do: aBlock [ ^ aNode hasChildren ifFalse: [ aNode isTextOrLineBreak ifTrue: [ aBlock value: aNode ] ] ifTrue: [ aNode children do: [ :n | self allTextNodesFrom: n do: aBlock ] ] ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> ast: aPRDocument [ ast := aPRDocument. aPRDocument accept: GrafoscopioPillarTextAnnotator new. ast start: aPRDocument children first start. ast stop: aPRDocument children last stop. stringDecorator := GrafoscopioPillarASTextStringDecorator new text: self; yourself ] { #category : #accessing } GrafoscopioPillarASText >> at: anInteger [ | node | (anInteger > (self size +1 ) or: [ anInteger < 1 ]) ifTrue: [ ^ self errorSubscriptBounds: anInteger ]. node := self detectAstNodeFor: anInteger in: ast. ^ node text at: anInteger - node textStart +1 ] { #category : #copying } GrafoscopioPillarASText >> copyFrom: from to: to [ ^ (ast textStart = from and: [ ast textStop = (to + 1) ]) ifTrue: [ self ] ifFalse: [ GrafoscopioPillarASTextStringProjectionDecorator new text: self; from: from; to: to; yourself ] ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> detectAstNodeFor: anInteger in: aNode [ (lastNode isNotNil and: [ anInteger between: lastNode textStart and: lastNode textStop ]) ifTrue: [ ^ lastNode ]. (anInteger between: aNode textStart and: aNode textStop) ifFalse: [ self error: 'Cannot find a node for ' , anInteger asString ]. ^ aNode hasChildren ifTrue: [ aNode children detect: [ :c | anInteger between: c textStart and: c textStop ] ifFound: [ :n | self detectAstNodeFor: anInteger in: n ] ifNone: [ self error: 'whut?' ] ] ifFalse: [ lastNode := aNode ] ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> detectAstNodesBetween: from and: to in: aNode [ | children childrenStream currentNode | aNode hasChildren ifFalse: [ ^ {aNode} ]. childrenStream := aNode children readStream. children := OrderedCollection new. [ childrenStream atEnd not and: [ (currentNode :=childrenStream next) textStart <= to ] ] whileTrue:[ ((currentNode textStart >= from) or: [ currentNode textStop >= from ]) ifTrue: [ children addAll: (self detectAstNodesBetween: from and: to in: currentNode ) . ]. ]. ^ children. ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> extractStringFrom: aPosition to: anOtherPosition [ | from to nodes preffix suffix | nodes := self detectAstNodesBetween: aPosition and: anOtherPosition in: ast. from := (aPosition - nodes first textStart +1 ) . nodes size = 1 ifTrue: [ ^ nodes first text copyFrom: from to: from + anOtherPosition - aPosition . ]. to := nodes last textStop - anOtherPosition + 1. preffix := nodes first text copyFrom: from to: nodes first textSize. suffix := nodes last text copyFrom: 1 to: to. ^ String streamContents: [ :str | str nextPutAll: preffix. (nodes copyFrom: 2 to: nodes size) inject: str into: [ :stream :each | stream nextPutAll: each text. stream ]. str nextPutAll: suffix ] ] { #category : #'as yet unclassified' } GrafoscopioPillarASText >> removeAttribute: att from: start to: stop [ ] { #category : #editing } GrafoscopioPillarASText >> replaceFrom: start to: stop with: aCollection [ " Here we should be managing insertion and adding of text. " self assert: aCollection isEmpty. ] { #category : #accessing } GrafoscopioPillarASText >> runs [ ^ RunArray new: self size withAll: (Array with: (TextFontChange fontNumber: 1)) ] { #category : #accessing } GrafoscopioPillarASText >> size [ ^ ast textSize ] { #category : #accessing } GrafoscopioPillarASText >> string [ ^ stringDecorator ]