empty log message

This commit is contained in:
SantiagoBragagnolo 2020-04-12 01:00:53 +00:00
parent 5bff95c6fa
commit e1df08eae6
26 changed files with 666 additions and 325 deletions

View File

@ -0,0 +1,135 @@
Class {
#name : #GrafoscopioAttributeBranchVisitor,
#superclass : #Object,
#instVars : [
'attributes',
'level',
'listLevel',
'index',
'text',
'styler'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioAttributeBranchVisitor >> analyzeBranch: aBranch at: anIndex [
index := anIndex.
self halt.
^ [ aBranch
inject: OrderedCollection new
into: [ :attrs :node |
node accept: self.
attrs addAll: (attributes at: node).
attrs ] ]
ensure: [ index := 0 ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> attributes [
^ attributes
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> index: anIndex [
index := anIndex
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> initialize [
attributes := Dictionary new.
styler := GrafoscopioPillarStyler defaultStyler.
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> text: aGrafoscopioPillarASText [
text := aGrafoscopioPillarASText
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitCodeblock: aPRCodeblock [
attributes
at: aPRCodeblock
ifAbsentPut: [ styler attributesForCodeBlock: aPRCodeblock ].
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitCommentedLine: aPRCommentedLine [
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitDocument: aPRDocument [
attributes at: aPRDocument ifAbsentPut: [ styler attributesForDocument: aPRDocument ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitExternalLink: aPRExternalLink [
attributes
at: aPRExternalLink
ifAbsentPut: [ styler attributesForExternalLink: aPRExternalLink ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitFigure: aPRFigure [
attributes at: aPRFigure ifAbsentPut: [ styler attributesForFigure: aPRFigure ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitFormatText: aGrafoscopioFormatTextNode [
attributes
at: aGrafoscopioFormatTextNode
ifAbsentPut: [ styler attributesForFormatText: aGrafoscopioFormatTextNode ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitHeader: aPRHeader [
attributes
at: aPRHeader
ifAbsentPut: [ styler attributesForHeader: aPRHeader ].
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitInternalLink: aPRInternalLink [
attributes
at: aPRInternalLink
ifAbsentPut: [ styler attributesForInternalLink: aPRInternalLink ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitLineBreak: aPRLineBreak [
attributes
at: aPRLineBreak
ifAbsentPut: [ styler attributesForLineBreak: aPRLineBreak ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitListItem: aPRListItem [
attributes
at: aPRListItem
ifAbsentPut: [ styler attributesForListItem: aPRListItem at: index ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitParagraph: aPRParagraph [
attributes
at: aPRParagraph
ifAbsentPut: [ styler attributesForParagraph: aPRParagraph ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitText: aPRText [
attributes
at: aPRText
ifAbsentPut: [ styler attributesForText: aPRText ]
]
{ #category : #'as yet unclassified' }
GrafoscopioAttributeBranchVisitor >> visitUnorderedList: aPRUnorderedList [
attributes
at: aPRUnorderedList
ifAbsentPut: [ styler attributesForUnorderedList: aPRUnorderedList ]
]

View File

@ -1,108 +0,0 @@
Class {
#name : #GrafoscopioFlatAttributeVisitor,
#superclass : #Object,
#instVars : [
'attributes',
'level',
'listLevel',
'index'
],
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> attributes [
^ attributes
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> index: anIndex [
index := anIndex
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> initialize [
super initialize.
level := 0
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitCommentedLine: aPRCommentedLine [
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitDocument: aPRDocument [
attributes := OrderedCollection new.
listLevel := 0
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitExternalLink: aPRExternalLink [
attributes
add: (TextColor new color: (Color fromHexString: '03A9F4'));
add: TextEmphasis underlined;
add:
(TextAction new
actOnClickBlock: [ self inform: 'Should be going to ' , aPRExternalLink reference ])
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitFigure: aPRFigure [
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitHeader: aPRHeader [
level := level + 1.
attributes
add:
(TextFontReference
toFont:
(LogicalFont
familyName: 'Source Code Pro'
pointSize: ((20 - (level * 5)) max: 10)))
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitInternalLink: aPRInternalLink [
self visitExternalLink: aPRInternalLink
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitLineBreak: aPRLineBreak [
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitListItem: aPRListItem [
aPRListItem textStart = index
ifTrue: [
attributes
add: (TextIndent tabs: 2);
add:
(TextAnchor new
anchoredMorph: (self iconNamed: #menuPin);
yourself) ]
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitParagraph: aPRParagraph [
"attributes
add:
(TextFontReference
toFont:
(LogicalFont
familyName: 'Source Code Pro'
pointSize: 10))"
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitText: aPRText [
]
{ #category : #'as yet unclassified' }
GrafoscopioFlatAttributeVisitor >> visitUnorderedList: aPRUnorderedList [
listLevel := listLevel + 1 .
]

View File

@ -1,20 +1,14 @@
Class {
#name : #GrafoscopioFmtAnchorAsBody,
#superclass : #GrafoscopioFmtUrlAsBody,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorAsBody >> applyOn: aString from: textStart to: textStop [
^ model anchor
]
{ #category : #'target resize' }
GrafoscopioFmtAnchorAsBody >> leftSize [
^ model anchor size - 1
]
{ #category : #'target resize' }
GrafoscopioFmtAnchorAsBody >> rightSize [
^ 0
GrafoscopioFmtAnchorAsBody >> beInstalledIn: anExternalLink [
anExternalLink children isEmpty ifFalse: [ ^ self ].
self
installTextNodeAtRightWithValue: anExternalLink anchor asString
in: anExternalLink
]

View File

@ -1,22 +1,10 @@
Class {
#name : #GrafoscopioFmtAnchorOnTheLeft,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft >> applyOn: aString from: textStart to: textStop [
^ textStart = model textStart
ifTrue: [ (Character value: 1) asString , aString ]
ifFalse: [ aString ]
]
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft >> leftSize [
^ 1
]
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft >> rightSize [
^ 0
GrafoscopioFmtAnchorOnTheLeft >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: (Character value: 1) asString in: aNode
]

View File

@ -0,0 +1,13 @@
Class {
#name : #GrafoscopioFmtAnchorOnTheLeft2,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtAnchorOnTheLeft2 >> beInstalledIn: aNode [
aNode language originalName = 'pharo-image'
ifTrue: [
aNode propertyAt: #text put: aNode text.
aNode text: (Character value: 1) asString ]
]

View File

@ -1,22 +1,10 @@
Class {
#name : #GrafoscopioFmtBeginningLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtBeginningLinebreak >> applyOn: aString from: textStart to: textStop [
^ textStart = model textStart
ifTrue: [ OSPlatform current lineEnding , aString ]
ifFalse: [ aString ]
]
{ #category : #'target resize' }
GrafoscopioFmtBeginningLinebreak >> leftSize [
^ OSPlatform current lineEnding size
]
{ #category : #'target resize' }
GrafoscopioFmtBeginningLinebreak >> rightSize [
^ 0
GrafoscopioFmtBeginningLinebreak >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: OSPlatform current lineEnding in: aNode
]

View File

@ -1,27 +1,11 @@
Class {
#name : #GrafoscopioFmtDoubleLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtDoubleLinebreak >> applyOn: aString from: textStart to: textStop [
| return |
return := textStart = (model textStart)
ifTrue: [ OSPlatform current lineEnding , aString ]
ifFalse: [ aString ].
return := textStop = model textStop
ifTrue: [ return , OSPlatform current lineEnding ]
ifFalse: [ aString ].
^ return
]
{ #category : #'target resize' }
GrafoscopioFmtDoubleLinebreak >> leftSize [
^ OSPlatform current lineEnding size
]
{ #category : #'target resize' }
GrafoscopioFmtDoubleLinebreak >> rightSize [
^ OSPlatform current lineEnding size
GrafoscopioFmtDoubleLinebreak >> beInstalledIn: aNode [
self installTextNodeAtLeftWithValue: OSPlatform current lineEnding in: aNode.
self installTextNodeAtRightWithValue: OSPlatform current lineEnding in: aNode
]

View File

@ -1,24 +1,12 @@
Class {
#name : #GrafoscopioFmtEndingLinebreak,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> applyOn: aString from: textStart to: textStop [
^ textStop = model textStop
ifTrue: [ aString , OSPlatform current lineEnding ]
ifFalse: [ aString ]
]
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> leftSize [
^ 0
]
{ #category : #'target resize' }
GrafoscopioFmtEndingLinebreak >> rightSize [
^ OSPlatform current lineEnding size
GrafoscopioFmtEndingLinebreak >> beInstalledIn: aNode [
self installTextNodeAtRightWithValue: OSPlatform current lineEnding in: aNode
]
{ #category : #'target resize' }

View File

@ -1,22 +1,12 @@
Class {
#name : #GrafoscopioFmtEndingSpace,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtEndingSpace >> applyOn: aString from: textStart to: textStop [
^ textStop = model textStop
ifTrue: [ aString , ' ' ]
ifFalse: [ aString ]
]
{ #category : #'target resize' }
GrafoscopioFmtEndingSpace >> leftSize [
^ 0
]
{ #category : #'target resize' }
GrafoscopioFmtEndingSpace >> rightSize [
^ 1
GrafoscopioFmtEndingSpace >> beInstalledIn: aNode [
self
installTextNodeAtRightWithValue: String space
in: aNode
]

View File

@ -1,28 +1,14 @@
Class {
#name : #GrafoscopioFmtUrlAsBody,
#superclass : #GrafoscopioFormat,
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #'target resize' }
GrafoscopioFmtUrlAsBody >> applyOn: aString from: textStart to: textStop [
^ model reference
]
{ #category : #'target resize' }
GrafoscopioFmtUrlAsBody >> beInstalledIn: anExternalLink [
anExternalLink children isEmpty ifFalse: [ ^ self ].
anExternalLink children: {(PRText new text: ' '; yourself)}.
super beInstalledIn: anExternalLink.
]
{ #category : #'target resize' }
GrafoscopioFmtUrlAsBody >> leftSize [
^ model reference size - 1
]
{ #category : #'target resize' }
GrafoscopioFmtUrlAsBody >> rightSize [
^ 0
self
installTextNodeAtRightWithValue: anExternalLink reference asString
in: anExternalLink
]

View File

@ -1,13 +1,10 @@
Class {
#name : #GrafoscopioFormat,
#superclass : #Object,
#instVars : [
'model'
],
#classInstVars : [
'instance'
],
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #accessing }
@ -15,33 +12,32 @@ GrafoscopioFormat class >> instance [
^ instance ifNil: [ instance := self new ]
]
{ #category : #'target resize' }
GrafoscopioFormat >> applyOn: aString from: textStart to: textStop [
self subclassResponsibility
]
{ #category : #'target resize' }
GrafoscopioFormat >> beInstalledIn: aNode [
aNode installFormat: (self copy model: aNode; yourself )
self subclassResponsibility .
]
{ #category : #'target resize' }
GrafoscopioFormat >> leftSize [
^ self subclassResponsibility
]
{ #category : #'as yet unclassified' }
GrafoscopioFormat >> model: aPRHeader [
model := aPRHeader
GrafoscopioFormat >> installTextNodeAtLeftWithValue: aString in: aNode [
| newTextChild |
newTextChild := self newTextChildFor: aString in: aNode.
aNode children: {newTextChild} , aNode children
]
{ #category : #'target resize' }
GrafoscopioFormat >> rightSize [
^ self subclassResponsibility
GrafoscopioFormat >> installTextNodeAtRightWithValue: aString in: aNode [
aNode
children:
aNode children, {(GrafoscopioFormatTextNode new
text: aString;
yourself)}
]
{ #category : #'target resize' }
GrafoscopioFormat >> size [
^ self leftSize + self rightSize
GrafoscopioFormat >> newTextChildFor: aString in: aNode [
^ GrafoscopioFormatTextNode new
text: aString;
parent: aNode;
yourself
]

View File

@ -0,0 +1,16 @@
Class {
#name : #GrafoscopioFormatTextNode,
#superclass : #PRText,
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #visiting }
GrafoscopioFormatTextNode >> accept: aVisitor [
aVisitor visitFormatText: self
]
{ #category : #visiting }
GrafoscopioFormatTextNode >> printOn: aStream [
super printOn: aStream.
aStream nextPutAll: ' format text: '; print: self text
]

View File

@ -13,6 +13,20 @@ Class {
#category : #'Grafoscopio-Pillar'
}
{ #category : #'as yet unclassified' }
GrafoscopioPillarASText class >> now [
| pillarAst text presenter |
pillarAst := GrafoscopioPillarASText pillarExample .
text := GrafoscopioPillarASText new.
text ast: pillarAst.
presenter := SpTextPresenter new text: text ; yourself .
presenter autoAccept: true.
presenter whenTextChangedDo: [ : v | presenter violentForceRecompose ].
presenter openWithSpec.
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASText class >> openExample [
^ self new
@ -26,6 +40,199 @@ GrafoscopioPillarASText class >> pillarExample [
parse:
'!!About Pillar
[[[label=script1|caption=My script that works|language=pharo-image
PolymorphSystemSettings pharoLogoForm
]]]
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.
!!About Pillar
[[[label=script1|caption=My script that works|language=pharo-image
PolymorphSystemSettings pharoLogoForm
]]]
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.
!!About Pillar
[[[label=script1|caption=My script that works|language=pharo-image
PolymorphSystemSettings pharoLogoForm
]]]
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.
!!About Pillar
[[[label=script1|caption=My script that works|language=pharo-image
PolymorphSystemSettings pharoLogoForm
]]]
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.
@ -99,14 +306,11 @@ GrafoscopioPillarASText >> ast: aPRDocument [
{ #category : #accessing }
GrafoscopioPillarASText >> at: anInteger [
| node |
(anInteger > (self size +1 ) or: [ anInteger < 1 ])
ifTrue: [ ^ self errorSubscriptBounds: anInteger ].
node := self detectAstNodeFor: anInteger in: ast.
^ node formattedText at: anInteger - node textStart +1
^ node text at: anInteger - node textStart +1
]
{ #category : #'as yet unclassified' }
@ -191,6 +395,11 @@ GrafoscopioPillarASText >> detectFullBranchFor: anInteger in: aNode [
ifFalse: [ {aNode} ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASText >> errorSubscriptBounds: aSomedthing [
self halt.
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASText >> extractStringFrom: aPosition to: anOtherPosition [
| from to nodes preffix suffix |
@ -201,8 +410,8 @@ GrafoscopioPillarASText >> extractStringFrom: aPosition to: anOtherPosition [
].
to := nodes last textStop - anOtherPosition.
preffix := nodes first formattedText copyFrom: from to: nodes first textSize.
suffix := nodes last formattedText copyFrom: 1 to: to.
preffix := nodes first text copyFrom: from to: nodes first textSize.
suffix := nodes last text copyFrom: 1 to: to.
^ String
streamContents: [ :str |
str nextPutAll: preffix.
@ -233,9 +442,9 @@ GrafoscopioPillarASText >> rangeOf: aTextURL startingAt: anInteger [
{ #category : #'as yet unclassified' }
GrafoscopioPillarASText >> reannotate: aPRText [
| current previous size parents |
| current previous parents |
aPRText textStop: aPRText textStart + aPRText formattedText size.
aPRText textStop: aPRText textStart + aPRText text size.
parents := Set new.
parents add: aPRText parent.
current := aPRText next.
@ -243,10 +452,9 @@ GrafoscopioPillarASText >> reannotate: aPRText [
previous := aPRText.
[ current isNotNil ]
whileTrue: [
size := current textSize.
whileTrue: [
current textStart: previous textStop.
current textStop: current textStart + size.
current textStop: current textStart + current text size.
previous := current.
current := current next.
self ].
@ -263,22 +471,19 @@ GrafoscopioPillarASText >> removeAttribute: att from: start to: stop [
{ #category : #editing }
GrafoscopioPillarASText >> replaceFrom: start to: stop with: aCollection [
| nodes realStart realStop newText node |
aCollection ifEmpty: [ ^ self ].
((stop - start )> 1 and:[ aCollection isEmpty ]) ifTrue: [ ^self ].
nodes := self detectAstNodesBetween: start and: stop in: ast.
self assert: nodes size = 1.
self assert: nodes size <= 1.
node := nodes first.
realStart := (start - (node textStart + node leftFormatSize) )+ 1 .
realStop := stop - (node textStart + node rightFormatSize) + 1 .
newText := (node text copyReplaceFrom: realStart to: realStop with: aCollection).
realStart := (start - (node textStart) )+ 1 .
realStop := stop - (node textStart ) + 1 .
newText := (node text copyReplaceFrom: realStart to: realStop with: aCollection).
node isText ifTrue: [
node text: newText
] ifFalse: [
(newText beginsWith: node text) ifTrue: [
nodes := self detectAstNodesBetween: start - 1 and: start -1 in: ast.
nodes first text: nodes first text , (newText copyFrom: node text size to: newText size ).
] ifFalse: [
nodes first next text: (newText copyFrom: 1 to: newText size - node textSize) , nodes first text.
]
node := self detectAstNodeFor: node textStart - 1.
node text: node text, aCollection.
nodes := { node }.
].
self reannotate: nodes first.

View File

@ -22,6 +22,22 @@ GrafoscopioPillarASTextStringDecorator >> copyFrom: one to: two [
^ text copyFrom: one to: two
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> indexOf: aCharacter startingAt: anInteger ifAbsent: aBlockClosure [
| current index |
current := text detectAstNodeFor: anInteger.
index := current text
indexOf: aCharacter
startingAt: anInteger - current textStart + 1.
current := current next.
[ current isNotNil ]
whileTrue: [ index := current text indexOf: aCharacter.
index = 0
ifTrue: [ current := current next ]
ifFalse: [ ^ current textStart + index ] ].
^ aBlockClosure value
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringDecorator >> isByteString [
^ false

View File

@ -14,6 +14,11 @@ GrafoscopioPillarASTextStringProjectionDecorator >> allRangesOfSubstring: aStrin
^ { }
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> asText [
^ self string asText
]
{ #category : #accessing }
GrafoscopioPillarASTextStringProjectionDecorator >> at: anInteger [
^ self cached at: anInteger
@ -48,6 +53,11 @@ GrafoscopioPillarASTextStringProjectionDecorator >> size [
^ to - from
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> string [
^ text extractStringFrom: from to: to
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarASTextStringProjectionDecorator >> to: anInteger [
to := anInteger

View File

@ -4,33 +4,40 @@ Class {
#instVars : [
'ast',
'lastBranch',
'lastAttributes'
'lastAttributes',
'visitor'
],
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioPillarRuns >> ast: anAst [
ast := anAst
ast := anAst.
visitor := GrafoscopioAttributeBranchVisitor new.
visitor text: ast
]
{ #category : #'basic api' }
GrafoscopioPillarRuns >> at: anIndex [
| newBranch |
anIndex > ast size
ifTrue: [ ^ Array empty ].
newBranch := ast detectFullBranchFor: anIndex.
newBranch = lastBranch
ifTrue: [ .^ lastAttributes ].
lastBranch := newBranch.
^ lastAttributes := self calculateAttributesForBranch: lastBranch at: anIndex
ifTrue: [ ^ lastAttributes ].
lastAttributes := self
calculateAttributesForBranch: newBranch
at: anIndex.
lastBranch := (newBranch
anySatisfy: [ :n | n isMemberOf: PRCodeblock ])
ifTrue: [ nil ]
ifFalse: [ newBranch ].
^ lastAttributes
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> calculateAttributesForBranch: aCollection at: anIndex [
| visitor |
visitor := GrafoscopioFlatAttributeVisitor new.
visitor index: anIndex.
aCollection do: [ :n | n accept: visitor ].
^ visitor attributes
^ visitor analyzeBranch: aCollection at: anIndex.
]
{ #category : #'basic api' }
@ -56,11 +63,14 @@ GrafoscopioPillarRuns >> reset [
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarRuns >> runLengthFor: anInteger [
GrafoscopioPillarRuns >> runLengthFor: anInteger [
| node |
anInteger > ast size ifTrue: [ ^0 ].
node := (ast detectAstNodeFor: anInteger).
^ node textStop - anInteger.
anInteger > ast size
ifTrue: [ ^ 0 ].
node := ast detectAstNodeFor: anInteger.
^ (node isKindOf: PRCodeblock)
ifTrue: [ 1 ]
ifFalse: [ node textStop - anInteger ]
]
{ #category : #'as yet unclassified' }

View File

@ -0,0 +1,108 @@
Class {
#name : #GrafoscopioPillarStyler,
#superclass : #Object,
#instVars : [
'pharoStyler'
],
#category : #'Grafoscopio-Pillar-Style'
}
{ #category : #accessing }
GrafoscopioPillarStyler class >> defaultStyler [
^ self new
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForCodeBlock: aDocument [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForCodeBlock: aPRCodeblock at: index [
self halt.
aPRCodeblock language originalName = 'pharo-image'
ifTrue: [ ^ {(TextAnchor new
anchoredMorph: (self class compiler evaluate: (aPRCodeblock propertyAt: #text)))} ].
aPRCodeblock language originalName = 'pharo'
ifTrue: [ | runs |
runs := (self pharoStyler
privateStyle: aPRCodeblock text asText , '.') runs.
^ runs at: index - aPRCodeblock textStart ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForDocument: aDocument [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForExternalLink: aPRExternalLink [
^ {(TextColor new color: (Color fromHexString: '03A9F4')).
TextEmphasis underlined.
(TextAction new
actOnClickBlock: [ self inform: 'Should be going to ' , aPRExternalLink reference ])}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForFigure: aPRFigure [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForFormatText: aGrafoscopioFormatTextNode [
^ self attributesForText: aGrafoscopioFormatTextNode
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForHeader: aPRHeader [
^ {(TextFontReference
toFont:
(LogicalFont
familyName: 'Source Code Pro'
pointSize: (20 - (aPRHeader level * 5) max: 10)))}
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForInternalLink: aPRInternalLink [
^ self attributesForExternalLink: aPRInternalLink
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForLineBreak: aPRLineBreak [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForListItem: aPRListItem at: index [
^ (aPRListItem text at: index - aPRListItem textStart + 1) = Character home
ifTrue: [ {(TextIndent tabs: aPRListItem level).
(TextAnchor new
anchoredMorph: (self iconNamed: #menuPin);
yourself)} ]
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForParagraph: aParagraph [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForText: aText [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> attributesForUnorderedList: aList [
^ self default
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> default [
^ Array empty
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarStyler >> pharoStyler [
^ pharoStyler
ifNil: [ pharoStyler := SHRBTextStyler new isForWorkspace: true; yourself]
]

View File

@ -36,7 +36,13 @@ GrafoscopioPillarTextAnnotator >> visitDocument: aDoc [
lastStop := 1 .
aDoc accept: formatter.
super visitDocument: aDoc.
]
{ #category : #'as yet unclassified' }
GrafoscopioPillarTextAnnotator >> visitFormatText: aGrafoscopioFormatTextNode [
" for the annotator, a format text is a much as regular text"
self visitText: aGrafoscopioFormatTextNode
]
{ #category : #'visiting-document' }
@ -54,6 +60,6 @@ GrafoscopioPillarTextAnnotator >> visitText: aTextObject [
texts ifNotEmpty: [ texts last next: aTextObject ].
texts add: aTextObject.
aTextObject propertyAt: #textStart put: lastStop.
lastStop := lastStop + aTextObject formattedText size.
lastStop := lastStop + aTextObject text size.
aTextObject propertyAt: #textStop put: lastStop .
]

View File

@ -20,7 +20,7 @@ Class {
#classInstVars : [
'default'
],
#category : #'Grafoscopio-Pillar'
#category : #'Grafoscopio-Pillar-TextFormat'
}
{ #category : #accessing }
@ -30,7 +30,10 @@ GrafoscopioTextFormatter class >> buildDefault [
new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRHeader.
new registerFormat: GrafoscopioFmtAnchorOnTheLeft instance forClass: PRListItem.
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRListItem.
" new registerFormat: GrafoscopioFmtEndingLinebreak instance forClass: PRParagraph ."
" new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRCodeblock ."
new registerFormat: GrafoscopioFmtAnchorOnTheLeft2 instance forClass: PRCodeblock .
new registerFormat: GrafoscopioFmtEndingLinebreak instance forClass: PRParagraph .
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRList.
new registerFormat: GrafoscopioFmtUrlAsBody instance forClass: PRExternalLink .
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRExternalLink.
@ -56,7 +59,7 @@ GrafoscopioTextFormatter class >> default [
{ #category : #initialization }
GrafoscopioTextFormatter >> format: aNode [
(self formatsFor: aNode) do: [ :f | f beInstalledIn: aNode ].
(self formatsFor: aNode) do: [ :f | f beInstalledIn: aNode ]
]
{ #category : #initialization }
@ -108,3 +111,14 @@ GrafoscopioTextFormatter >> visitDocumentItem: anItem [
self format: anItem.
anItem parent: stack first.
]
{ #category : #initialization }
GrafoscopioTextFormatter >> visitEmptyParagraph: aParagraph [
stack top children last = aParagraph
ifTrue: [ stack top children: stack top children allButLast ].
]
{ #category : #'as yet unclassified' }
GrafoscopioTextFormatter >> visitFormatText: aGrafoscopioFormatTextNode [
" No way we format the formatted text. "
]

View File

@ -0,0 +1,13 @@
Extension { #name : #PRCodeblock }
{ #category : #'*Grafoscopio' }
PRCodeblock >> children [
^ self
propertyAt: #children
ifAbsentPut: [ { PRText new text: text; parent: self ;yourself } asOrderedCollection ]
]
{ #category : #'*Grafoscopio' }
PRCodeblock >> children: aCollection [
self propertyAt:#children put: aCollection.
]

View File

@ -0,0 +1,8 @@
Extension { #name : #PRDocumentGroup }
{ #category : #'*Grafoscopio' }
PRDocumentGroup >> children: anArrayOfChildren [
"Answer the children of the receiver."
children := anArrayOfChildren asArray
]

View File

@ -15,13 +15,6 @@ PRLineBreak >> isTextOrLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> leftFormatSize [
^ self formats
inject: 0
into: [ :acc :f | acc + f leftSize ]
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> next [
^ self propertyAt: #next ifAbsent: [ nil ]
@ -32,13 +25,6 @@ PRLineBreak >> next: aText [
self propertyAt: #next put: aText
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> rightFormatSize [
^ self formats
inject: 0
into: [ :acc :f | acc + f rightSize ]
]
{ #category : #'*Grafoscopio' }
PRLineBreak >> text [
^ OSPlatform current lineEnding

View File

@ -1,6 +0,0 @@
Extension { #name : #PRLink }
{ #category : #'*Grafoscopio' }
PRLink >> children: aCollection [
children := aCollection
]

View File

@ -0,0 +1,16 @@
Extension { #name : #PRList }
{ #category : #'*Grafoscopio' }
PRList >> level [
| current level |
current := self.
level := 0.
[ current notNil ]
whileTrue: [
(current isKindOf: PRList) ifTrue: [
level := level + 1.
].
current := current parent
].
^ level
]

View File

@ -0,0 +1,6 @@
Extension { #name : #PRPillarWriter }
{ #category : #'*Grafoscopio' }
PRPillarWriter >> visitFormatText: aGrafoscopioFormatTextNode [
" Do nothing "
]

View File

@ -1,24 +1,10 @@
Extension { #name : #PRText }
{ #category : #'*Grafoscopio' }
PRText >> formattedText [
^ self formats
inject: self text
into: [ :acc :f | f applyOn: acc from: self textStart to: self textStop ]
]
{ #category : #'*Grafoscopio' }
PRText >> isTextOrLineBreak [
^ true
]
{ #category : #'*Grafoscopio' }
PRText >> leftFormatSize [
^ self formats
inject: 0
into: [ :acc :f | acc + f leftSize ]
]
{ #category : #'*Grafoscopio' }
PRText >> next [
^ self propertyAt: #next ifAbsent: [ nil ]
@ -29,13 +15,6 @@ PRText >> next: aText [
self propertyAt: #next put: aText.
]
{ #category : #'*Grafoscopio' }
PRText >> rightFormatSize [
^ self formats
inject: 0
into: [ :acc :f | acc + f rightSize ]
]
{ #category : #'*Grafoscopio' }
PRText >> textStart: aValue [
^ self