Forking from Santiago's changes in a personal repo as I have not the dependencies required to commit his changes (they seem Pillar based but they don't load properly in my image).
This commit is contained in:
parent
8dce989c0c
commit
240ab8e975
@ -4,7 +4,7 @@ I provide some convenience functionality to work with files.
|
||||
Class {
|
||||
#name : #FileUtils,
|
||||
#superclass : #Object,
|
||||
#category : 'Grafoscopio-Model'
|
||||
#category : #'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #utilities }
|
||||
|
@ -32,7 +32,7 @@ Class {
|
||||
#classVars : [
|
||||
'Current'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #'accessing - icons' }
|
||||
|
@ -1,13 +0,0 @@
|
||||
Extension { #name : #FormCanvas }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
FormCanvas >> gfcParagraph: para bounds: bounds color: c [
|
||||
|
||||
| scanner |
|
||||
self setPaintColor: c.
|
||||
scanner := (port clippedBy: (bounds translateBy: origin)) gfcDisplayScannerFor: para
|
||||
foreground: c background: Color transparent
|
||||
ignoreColorChanges: false.
|
||||
para drawOn: (self copyClipRect: bounds) using: scanner at: origin + bounds topLeft.
|
||||
|
||||
]
|
@ -24,7 +24,7 @@ Class {
|
||||
'recentNotebooks',
|
||||
'helpMenu'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #adding }
|
||||
|
@ -7,7 +7,7 @@ Class {
|
||||
#classInstVars : [
|
||||
'recentNotebooks'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #'world menu' }
|
||||
@ -41,32 +41,6 @@ GfWorldMenu class >> helpMenuOn: aBuilder [
|
||||
action: [ GfUIHelpers messageAbout ].
|
||||
]
|
||||
|
||||
{ #category : #'world menu' }
|
||||
GfWorldMenu class >> launchCompatibilityMenuOn: aBuilder [
|
||||
<worldMenu>
|
||||
|
||||
(aBuilder item: #'New notebook')
|
||||
label: 'New notebook';
|
||||
order: 1;
|
||||
parent: #GfLaunchCompatibility;
|
||||
action: [ GrafoscopioNotebook new openDefault ].
|
||||
(aBuilder item: #'Notebook from file...')
|
||||
label: 'Notebook from file...';
|
||||
order: 2;
|
||||
parent: #GfLaunchCompatibility;
|
||||
action: [ GrafoscopioNotebook new openFromFileSelector ].
|
||||
(aBuilder item: #'Notebook from the Internet...')
|
||||
label: 'Notebook from the Internet...';
|
||||
order: 3;
|
||||
parent: #GfLaunchCompatibility;
|
||||
action: [ GrafoscopioNotebook new openFromUrlUI ].
|
||||
(aBuilder item: #recentNotebooks)
|
||||
label: 'Recent notebooks...';
|
||||
order: 4;
|
||||
parent: #GfLaunchCompatibility;
|
||||
action: [ GfUIHelpers openFromRecentlyUsed ]
|
||||
]
|
||||
|
||||
{ #category : #'world menu' }
|
||||
GfWorldMenu class >> launchMenuOn: aBuilder [
|
||||
<worldMenu>
|
||||
@ -75,61 +49,36 @@ GfWorldMenu class >> launchMenuOn: aBuilder [
|
||||
label: 'New notebook';
|
||||
order: 1;
|
||||
parent: #GfLaunch;
|
||||
action: [ GrafoscopioNewNotebook new openDefault ].
|
||||
action: [ GrafoscopioNotebook new openDefault ].
|
||||
(aBuilder item: #'Notebook from file...')
|
||||
label: 'Notebook from file...';
|
||||
order: 2;
|
||||
parent: #GfLaunch;
|
||||
action: [ GrafoscopioNewNotebook new openFromFileSelector ].
|
||||
(aBuilder item: #GfLaunchOpenRecent)
|
||||
label: 'Open recent...';
|
||||
order: 2;
|
||||
parent: #GfLaunch.
|
||||
action: [ GrafoscopioNotebook new openFromFileSelector ].
|
||||
(aBuilder item: #'Notebook from the Internet...')
|
||||
label: 'Notebook from the Internet...';
|
||||
order: 3;
|
||||
parent: #GfLaunch;
|
||||
action: [ GrafoscopioNewNotebook new openFromUrlUI ].
|
||||
action: [ GrafoscopioNotebook new openFromUrlUI ].
|
||||
(aBuilder item: #recentNotebooks)
|
||||
label: 'Recent notebooks...';
|
||||
order: 4;
|
||||
parent: #GfLaunch;
|
||||
action: [ GfUIHelpers openFromRecentlyUsed ]
|
||||
action: [ GfUIHelpers openFromRecentlyUsed ].
|
||||
]
|
||||
|
||||
{ #category : #'world menu' }
|
||||
GfWorldMenu class >> mainMenuItemsOn: aBuilder [
|
||||
"I add the main Grafoscopio menu to the Pharo World."
|
||||
|
||||
<worldMenu>
|
||||
|
||||
(aBuilder item: #Grafoscopio)
|
||||
label: 'Grafoscopio';
|
||||
order: 1;
|
||||
with: [ (aBuilder
|
||||
item: #GfLaunch;
|
||||
label: 'Launch') target: self.
|
||||
(aBuilder
|
||||
item: #GfLaunchCompatibility;
|
||||
label: 'Launch Compatibility') target: self.
|
||||
(aBuilder
|
||||
item: #GfUpdate;
|
||||
label: 'Update') target: self.
|
||||
(aBuilder
|
||||
item: #GfHelpAndDocs;
|
||||
label: 'Help & Docs') target: self ]
|
||||
]
|
||||
|
||||
{ #category : #'world menu' }
|
||||
GfWorldMenu class >> openRecentMenu: aBuilder [
|
||||
<worldMenu>
|
||||
|
||||
GrafoscopioNotebook recents
|
||||
do: [ :f |
|
||||
(aBuilder item: #'Open', f basename )
|
||||
label: 'Open ', f basename;
|
||||
order: 1;
|
||||
parent: #GfLaunchOpenRecent;
|
||||
action: [ GrafoscopioNotebook open: f ] ]
|
||||
with: [
|
||||
(aBuilder item: #GfLaunch; label: 'Launch') target: self.
|
||||
(aBuilder item: #GfUpdate; label: 'Update') target: self.
|
||||
(aBuilder item: #GfHelpAndDocs; label: 'Help & Docs') target: self. ]
|
||||
]
|
||||
|
||||
{ #category : #'world menu' }
|
||||
|
@ -1,79 +0,0 @@
|
||||
"
|
||||
I am a Spec ComposableModel for all Glamour presentations (GLMPresentation subclasses.) By default I open a Playground because its creation contract is special.
|
||||
|
||||
Example uses :
|
||||
|
||||
""open a playground""
|
||||
GlamourPresentationModel new openWithSpec.
|
||||
|
||||
""open a playground on 42""
|
||||
|ui|
|
||||
ui := GlamourPresentationModel new.
|
||||
ui presentationClass: GTPlayground startOn: (GTPlayPage new saveContent: '42').
|
||||
ui openWithSpec
|
||||
|
||||
""open an inspector on 42""
|
||||
|ui|
|
||||
ui := GlamourPresentationModel new.
|
||||
ui presentationClass: GTInspector startOn: 42.
|
||||
ui openWithSpec
|
||||
"
|
||||
Class {
|
||||
#name : #GlamourPresentationModel,
|
||||
#superclass : #SpPresenter,
|
||||
#instVars : [
|
||||
'presentation',
|
||||
'glmPres'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GlamourPresentationModel class >> defaultSpec [
|
||||
<spec: #default>
|
||||
^ SpBoxLayout newHorizontal
|
||||
add: #presentation;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #deprecation }
|
||||
GlamourPresentationModel class >> isDeprecated [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GlamourPresentationModel >> glmPres [
|
||||
glmPres isNil ifTrue:[glmPres := GTPlayground new startOn: GTPlayPage new].
|
||||
^glmPres
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GlamourPresentationModel >> initializeWidgets [
|
||||
"Should actually do nothing at all.
|
||||
This is because we cannot create the morph and later set the presentation.
|
||||
So we will do all of this in the presentation: accessor.
|
||||
"
|
||||
self presentation.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GlamourPresentationModel >> presentation [
|
||||
presentation isNil ifTrue:[
|
||||
| morph |
|
||||
morph := GLMMorphicRenderer new render: self glmPres.
|
||||
morph hResizing: #spaceFill.
|
||||
morph vResizing: #spaceFill.
|
||||
presentation := MorphicGenericAdapter morph: morph].
|
||||
|
||||
^ presentation
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GlamourPresentationModel >> presentation: anObject [
|
||||
presentation := anObject
|
||||
]
|
||||
|
||||
{ #category : #api }
|
||||
GlamourPresentationModel >> presentationClass: aGLMCompositePresentation startOn: anObject [
|
||||
glmPres := aGLMCompositePresentation new startOn: anObject
|
||||
]
|
@ -1,9 +0,0 @@
|
||||
Extension { #name : #GrafPort }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
GrafPort >> gfcDisplayScannerFor: para foreground: foreColor background: backColor ignoreColorChanges: shadowMode [
|
||||
^ (GrafoscopioDisplayScanner new text: para text textStyle: para textStyle
|
||||
foreground: foreColor background: backColor fillBlt: self
|
||||
ignoreColorChanges: shadowMode)
|
||||
setPort: self shallowCopy
|
||||
]
|
@ -1,134 +0,0 @@
|
||||
"
|
||||
Just an abstract node.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioAbstractNode,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'created',
|
||||
'edited',
|
||||
'tags',
|
||||
'order',
|
||||
'name'
|
||||
],
|
||||
#classInstVars : [
|
||||
'clipboard'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioAbstractNode class >> isAbstract [
|
||||
^ self = GrafoscopioAbstractNode
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioAbstractNode class >> isLeaf [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioAbstractNode class >> showInMenu [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> addChild: aBlock ofClass: aClass [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> addTag: aTag [
|
||||
"Tags the recipient node with aTag (string). For the moment we will have only one tag.
|
||||
In the future we will have several and there will be rules to know how tags interact with
|
||||
each other"
|
||||
self tags add: aTag
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> created [
|
||||
|
||||
^ created
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> created: aTimestamp [
|
||||
"I tell when this object was created"
|
||||
|
||||
created := aTimestamp
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> edited [
|
||||
^ edited
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> edited: aTimestamp [
|
||||
"I store the last time when a node was edited.
|
||||
Because nodes in the notebook have a autosave feature, I'm updated automatically when nodes are
|
||||
edited from the GUI.
|
||||
|
||||
If I'm in the notebook root (i.e. node's level equals 0) I should store the last time the notebook
|
||||
was saved on the hard drive."
|
||||
edited := aTimestamp
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> initialize [
|
||||
"I create a empty new node"
|
||||
super initialize.
|
||||
created := DateAndTime now.
|
||||
edited := DateAndTime now
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> isLeaf [
|
||||
^ self class isLeaf
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAbstractNode >> moveDown [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> name [
|
||||
^ name
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> name: aName [
|
||||
name := aName
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAbstractNode >> order [
|
||||
^ order ifNil: [ 0 ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> tagAs: aTag [
|
||||
self
|
||||
error:
|
||||
'tags are not used as markers anymore. Use addTag: instead and ensure you are not relying on text/codigo etc.'
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> tags [
|
||||
"I returns the receiver tags."
|
||||
|
||||
^ tags ifNil: [ tags := Set new ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractNode >> tags: aCollection [
|
||||
tags := aCollection
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAbstractNode >> updateStamp [
|
||||
self edited: DateAndTime now
|
||||
]
|
@ -1,128 +0,0 @@
|
||||
"
|
||||
This abstract class works for defining the basic type required by Rubric
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioAbstractText,
|
||||
#superclass : #Object,
|
||||
#category : 'Grafoscopio-Pillar'
|
||||
}
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAbstractText >> allRangesOfSubstring: aString [
|
||||
^ { }
|
||||
]
|
||||
|
||||
{ #category : #converting }
|
||||
GrafoscopioAbstractText >> asText [
|
||||
^ self
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> at: anIndex [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> attributesAt: characterIndex [
|
||||
"Answer the code for characters in the run beginning at characterIndex."
|
||||
"NB: no senders any more (supplanted by #attributesAt:forStyle: but retained for the moment in order not to break user code that may exist somewhere that still calls this"
|
||||
| attributes |
|
||||
" self size = 0
|
||||
ifTrue: [^ Array with: (TextFontChange new fontNumber: 1)]."
|
||||
self size = 0 ifTrue: [ ^#()].
|
||||
attributes := self runs at: characterIndex.
|
||||
^ attributes
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> attributesAt: anInteger forStyle: aTextStyle [
|
||||
| attributes size |
|
||||
size := self size.
|
||||
(size = 0 or: [ size < anInteger ])
|
||||
ifTrue: [ ^ Array
|
||||
with: (TextFontChange new fontNumber: aTextStyle defaultFontIndex) ]. "null text tolerates access"
|
||||
attributes := self runs at: anInteger.
|
||||
^ attributes
|
||||
]
|
||||
|
||||
{ #category : #copying }
|
||||
GrafoscopioAbstractText >> copy [
|
||||
^ self
|
||||
]
|
||||
|
||||
{ #category : #copying }
|
||||
GrafoscopioAbstractText >> copyFrom: start to: stop [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioAbstractText >> ifNotEmpty: isNotEmptyBlock ifEmpty: isEmptyBlock [
|
||||
^ self isEmpty
|
||||
ifTrue: [ isEmptyBlock value ]
|
||||
ifFalse: [ isNotEmptyBlock value ]
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioAbstractText >> isEmpty [
|
||||
^ self size = 0
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioAbstractText >> isText [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> last [
|
||||
^ self at: self size
|
||||
]
|
||||
|
||||
{ #category : #copying }
|
||||
GrafoscopioAbstractText >> notEmpty [
|
||||
^ self isEmpty not
|
||||
]
|
||||
|
||||
{ #category : #removing }
|
||||
GrafoscopioAbstractText >> removeAttribute: anAttr [
|
||||
^ self removeAttribute: anAttr from: 1 to: self size
|
||||
]
|
||||
|
||||
{ #category : #removing }
|
||||
GrafoscopioAbstractText >> removeAttribute: att from: start to: stop [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #editing }
|
||||
GrafoscopioAbstractText >> replaceFrom: anInteger to: anInteger2 with: aCollection [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #emphasis }
|
||||
GrafoscopioAbstractText >> runLengthFor: characterIndex [
|
||||
^ self runs runLengthFor: characterIndex
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> runs [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> runs: anArray [
|
||||
self subclassResponsibility "runs := RunArray new: self size withAll: anArray . "
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> size [
|
||||
^ self string size
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> string [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAbstractText >> text: aParam [
|
||||
self subclassResponsibility
|
||||
]
|
@ -1,146 +0,0 @@
|
||||
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.
|
||||
^ [ aBranch
|
||||
inject: OrderedCollection new
|
||||
into: [ :attrs :node |
|
||||
node accept: self.
|
||||
attrs addAll: (self attributesAt: node).
|
||||
attrs ] ]
|
||||
ensure: [ index := 0 ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> attributes [
|
||||
^ attributes
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode [
|
||||
^ (attributes detect: [ :a | a first = aNode ]) second
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> attributesAt: aNode ifAbsentPut: aBlock [
|
||||
^ attributes
|
||||
detect: [ :a | a first = aNode ]
|
||||
ifFound: [ :a | a second ]
|
||||
ifNone: [ | val |
|
||||
val := aBlock value.
|
||||
attributes
|
||||
add:
|
||||
{aNode.
|
||||
val}.
|
||||
val ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> index: anIndex [
|
||||
index := anIndex
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> initialize [
|
||||
attributes := OrderedCollection new.
|
||||
styler := GrafoscopioPillarStyler defaultStyler.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> text: aGrafoscopioPillarASText [
|
||||
text := aGrafoscopioPillarASText
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitCodeblock: aPRCodeblock [
|
||||
self
|
||||
attributesAt: aPRCodeblock
|
||||
ifAbsentPut: [ styler attributesForCodeBlock: aPRCodeblock at: index ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitCommentedLine: aPRCommentedLine [
|
||||
self attributesAt: aPRCommentedLine ifAbsentPut: [ styler default ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitDocument: aPRDocument [
|
||||
self attributesAt: aPRDocument ifAbsentPut: [ styler attributesForDocument: aPRDocument ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitExternalLink: aPRExternalLink [
|
||||
self
|
||||
attributesAt: aPRExternalLink
|
||||
ifAbsentPut: [ styler attributesForExternalLink: aPRExternalLink ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitFigure: aPRFigure [
|
||||
self attributesAt: aPRFigure ifAbsentPut: [ styler attributesForFigure: aPRFigure ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitFormatText: aGrafoscopioFormatTextNode [
|
||||
self attributesAt: aGrafoscopioFormatTextNode
|
||||
ifAbsentPut: [ styler attributesForFormatText: aGrafoscopioFormatTextNode ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitHeader: aPRHeader [
|
||||
self
|
||||
attributesAt: aPRHeader
|
||||
ifAbsentPut: [ styler attributesForHeader: aPRHeader ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitInternalLink: aPRInternalLink [
|
||||
self
|
||||
attributesAt: aPRInternalLink
|
||||
ifAbsentPut: [ styler attributesForInternalLink: aPRInternalLink ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitLineBreak: aPRLineBreak [
|
||||
self attributesAt: aPRLineBreak
|
||||
ifAbsentPut: [ styler attributesForLineBreak: aPRLineBreak ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitListItem: aPRListItem [
|
||||
self
|
||||
attributesAt: aPRListItem
|
||||
ifAbsentPut: [ styler attributesForListItem: aPRListItem at: index ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitParagraph: aPRParagraph [
|
||||
self
|
||||
attributesAt: aPRParagraph
|
||||
ifAbsentPut: [ styler attributesForParagraph: aPRParagraph ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitText: aPRText [
|
||||
self attributesAt: aPRText
|
||||
ifAbsentPut: [ styler attributesForText: aPRText ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioAttributeBranchVisitor >> visitUnorderedList: aPRUnorderedList [
|
||||
self attributesAt: aPRUnorderedList
|
||||
ifAbsentPut: [ styler attributesForUnorderedList: aPRUnorderedList ]
|
||||
]
|
@ -1,87 +0,0 @@
|
||||
"
|
||||
Branch node. this kind of node has no content
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioBranchNode,
|
||||
#superclass : #GrafoscopioLeafNode,
|
||||
#instVars : [
|
||||
'children'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioBranchNode class >> isLeaf [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitBranchNode: self.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> acceptsChildsOfClass: aClass [
|
||||
^ {GrafoscopioBranchNode.
|
||||
GrafoscopioUnitNode} includes: aClass
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> addAtBeginningChild: aBlock ofClass: aClass [
|
||||
(self acceptsChildsOfClass: aClass)
|
||||
ifTrue: [| child |
|
||||
child := aBlock value.
|
||||
child parent: self.
|
||||
self children addFirst: child]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> addChild: aBlock ofClass: aClass [
|
||||
(self acceptsChildsOfClass: aClass)
|
||||
ifTrue: [ | child |
|
||||
child := aBlock value.
|
||||
child parent: self.
|
||||
self children add: child ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> children [
|
||||
"Returns the receivers list of children"
|
||||
|
||||
^ children ifNil: [ children := OrderedCollection new ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> children: aCollection [
|
||||
"Sets the receivers children"
|
||||
|
||||
aCollection do: [:currentNode | currentNode parent: self ].
|
||||
children := aCollection.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioBranchNode >> isLeaf [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioBranchNode >> moveDown: aNode [
|
||||
| index |
|
||||
"Moves the current node a place before in the children collection where is located"
|
||||
index := children indexOf: aNode.
|
||||
children swap: index with: (index + 1 min: children size)
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioBranchNode >> moveUp: aNode [
|
||||
| index |
|
||||
"Moves the current node a place before in the children collection where is located"
|
||||
index := children indexOf: aNode.
|
||||
children swap: index with: (index - 1 max: 1)
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioBranchNode >> remove: aGrafoscopioTextNode [
|
||||
children remove: aGrafoscopioTextNode
|
||||
]
|
@ -6,11 +6,11 @@ to explore.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioButtonModel,
|
||||
#superclass : #ComposablePresenter,
|
||||
#superclass : #ComposableModel,
|
||||
#instVars : [
|
||||
'button'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
|
@ -4,15 +4,16 @@ embedded interactive Playground.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioCodeModel,
|
||||
#superclass : #ComposablePresenter,
|
||||
#superclass : #ComposableModel,
|
||||
#instVars : [
|
||||
'body'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GrafoscopioCodeModel class >> defaultSpec [
|
||||
|
||||
^ SpecLayout composed add: #body
|
||||
]
|
||||
|
||||
@ -28,7 +29,10 @@ GrafoscopioCodeModel >> body: anObject [
|
||||
|
||||
{ #category : #API }
|
||||
GrafoscopioCodeModel >> content: aGrafoscopioNodeContent [
|
||||
body text: aGrafoscopioNodeContent
|
||||
|
||||
body
|
||||
presentationClass: GTPlayground
|
||||
startOn: (GTPlayPage new saveContent: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
@ -60,5 +64,5 @@ GrafoscopioCodeModel >> extractHtmlImages [
|
||||
{ #category : #initialization }
|
||||
GrafoscopioCodeModel >> initializeWidgets [
|
||||
|
||||
body := self newCode.
|
||||
body := GlamourPresentationModel new.
|
||||
]
|
||||
|
@ -1,24 +0,0 @@
|
||||
"
|
||||
This kind of a leafNodes holds code text.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioCodeNode,
|
||||
#superclass : #GrafoscopioTextNode,
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioCodeNode class >> icon [
|
||||
^ self iconNamed:#objects
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioCodeNode class >> nameForSelection [
|
||||
^ 'New Code Node'
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioCodeNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitCodeNode: self.
|
||||
|
||||
]
|
@ -4,7 +4,7 @@ I define the documentation for the Grafoscopio package.
|
||||
Class {
|
||||
#name : #GrafoscopioDocs,
|
||||
#superclass : #GrafoscopioDocumentation,
|
||||
#category : 'Grafoscopio'
|
||||
#category : #Grafoscopio
|
||||
}
|
||||
|
||||
{ #category : #operation }
|
||||
|
@ -1,151 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioDocumentEditionPerspective,
|
||||
#superclass : #GrafoscopioPerspective,
|
||||
#instVars : [
|
||||
'tree',
|
||||
'document'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioDocumentEditionPerspective class >> defaultSpec [
|
||||
^ SpBoxLayout newVertical
|
||||
add: #toolbar height: self toolbarHeight;
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add: #tree width: 100;
|
||||
add: #viewport;
|
||||
yourself) yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioDocumentEditionPerspective class >> icon [
|
||||
^ self iconNamed: #merge
|
||||
]
|
||||
|
||||
{ #category : #'adding - convenience' }
|
||||
GrafoscopioDocumentEditionPerspective >> addAtBeginningNewNodeOfClass: aClass [
|
||||
self
|
||||
addAtBeginningOf: (tree selectedItem ifNil: [ document ])
|
||||
aNodeOfClass: aClass
|
||||
]
|
||||
|
||||
{ #category : #'adding - base' }
|
||||
GrafoscopioDocumentEditionPerspective >> addAtBeginningOf: aNode aNodeOfClass: aClass [
|
||||
aNode
|
||||
addAtBeginningChild: [ self instantiateNode: aClass ]
|
||||
ofClass: aClass.
|
||||
self modelChanged
|
||||
]
|
||||
|
||||
{ #category : #'adding - convenience' }
|
||||
GrafoscopioDocumentEditionPerspective >> addAtLastNewNodeOfClass: aClass [
|
||||
self
|
||||
addAtLastOf: (tree selectedItem ifNil: [ document ])
|
||||
aNodeOfClass: aClass
|
||||
]
|
||||
|
||||
{ #category : #'adding - base' }
|
||||
GrafoscopioDocumentEditionPerspective >> addAtLastOf: aNode aNodeOfClass: aClass [
|
||||
aNode
|
||||
addChild: [ self instantiateNode: aClass ]
|
||||
ofClass: aClass.
|
||||
self modelChanged
|
||||
]
|
||||
|
||||
{ #category : #'adding - convenience' }
|
||||
GrafoscopioDocumentEditionPerspective >> addNewNodeAtBeginningOf: aNode [
|
||||
self addAtBeginningOf: aNode aNodeOfClass: self chooseKindsOfNode
|
||||
]
|
||||
|
||||
{ #category : #'adding - convenience' }
|
||||
GrafoscopioDocumentEditionPerspective >> addNewNodeAtLastOf: aNode [
|
||||
self addAtLastOf: aNode aNodeOfClass: self chooseKindsOfNode
|
||||
]
|
||||
|
||||
{ #category : #'adding - convenience' }
|
||||
GrafoscopioDocumentEditionPerspective >> addNewNodeOfClass: aClass [
|
||||
^ self addAtLastNewNodeOfClass: aClass
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> createDefaultViewportVisitor [
|
||||
^ GrafoscopioViewportVisitor new
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> createViewport [
|
||||
^ self renderViewport: document
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> informNodeHasChanged: aNode [
|
||||
| path |
|
||||
path := tree selection selectedPath.
|
||||
tree roots: {document}.
|
||||
tree selectPath: path.
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> initializeWidgets [
|
||||
super initializeWidgets.
|
||||
tree := self newTreeTable.
|
||||
tree
|
||||
addColumn: (SpStringTableColumn evaluated: #name);
|
||||
children: [ :node |
|
||||
node isLeaf
|
||||
ifTrue: [ {} ]
|
||||
ifFalse: [ node children reject:[: a | a isLeaf ] ]].
|
||||
tree activateOnDoubleClick.
|
||||
tree whenSelectionChangedDo: [ : a | self renderViewport: a selectedItem ].
|
||||
tree whenActivatedDo: [ : a | self tooglePresenterForEdition: a ].
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioDocumentEditionPerspective >> instantiateNode: aClass [
|
||||
aClass class = GrafoscopioUnitNode species
|
||||
ifTrue: [ | name |
|
||||
name := UIManager default
|
||||
request: 'Unit name'
|
||||
initialAnswer: 'New unit'.
|
||||
^ aClass new
|
||||
name: name;
|
||||
yourself ].
|
||||
^ aClass new
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> modelChanged [
|
||||
| path |
|
||||
viewport := self createViewport.
|
||||
path := tree selection selectedPath.
|
||||
tree roots: {document}.
|
||||
tree selectPath: path.
|
||||
self needRebuild: false.
|
||||
self buildWithSpec
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> renderViewport: aNode [
|
||||
^ self createDefaultViewportVisitor createViewportFor: ( aNode ifNil: [ document ]) into: self
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> setModelBeforeInitialization: aDomainObject [
|
||||
super setModelBeforeInitialization: aDomainObject.
|
||||
document := aDomainObject .
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> tooglePresenterForEdition: anObect [
|
||||
self halt.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioDocumentEditionPerspective >> viewport [
|
||||
^ viewport
|
||||
]
|
@ -1,15 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioExportPerspective,
|
||||
#superclass : #GrafoscopioPerspective,
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioExportPerspective class >> icon [
|
||||
^ self iconNamed: #export
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioExportPerspective >> createViewport [
|
||||
^ self newLabel
|
||||
]
|
@ -1,14 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtAnchorAsBody,
|
||||
#superclass : #GrafoscopioFmtUrlAsBody,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtAnchorAsBody >> beInstalledIn: anExternalLink [
|
||||
anExternalLink children isEmpty ifFalse: [ ^ self ].
|
||||
self
|
||||
installTextNodeAtRightWithValue: anExternalLink anchor asString
|
||||
in: anExternalLink
|
||||
|
||||
]
|
@ -1,10 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtAnchorOnTheLeft,
|
||||
#superclass : #GrafoscopioFormat,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtAnchorOnTheLeft >> beInstalledIn: aNode [
|
||||
self installTextNodeAtLeftWithValue: (Character value: 1) asString in: aNode
|
||||
]
|
@ -1,13 +0,0 @@
|
||||
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 ]
|
||||
]
|
@ -1,10 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtBeginningLinebreak,
|
||||
#superclass : #GrafoscopioFormat,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtBeginningLinebreak >> beInstalledIn: aNode [
|
||||
self installTextNodeAtLeftWithValue: OSPlatform current lineEnding in: aNode
|
||||
]
|
@ -1,11 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtDoubleLinebreak,
|
||||
#superclass : #GrafoscopioFormat,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtDoubleLinebreak >> beInstalledIn: aNode [
|
||||
self installTextNodeAtLeftWithValue: OSPlatform current lineEnding in: aNode.
|
||||
self installTextNodeAtRightWithValue: OSPlatform current lineEnding in: aNode
|
||||
]
|
@ -1,15 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtEndingLinebreak,
|
||||
#superclass : #GrafoscopioFormat,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtEndingLinebreak >> beInstalledIn: aNode [
|
||||
self installTextNodeAtRightWithValue: OSPlatform current lineEnding in: aNode
|
||||
]
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtEndingLinebreak >> value: aString [
|
||||
^aString , OSPlatform current lineEnding
|
||||
]
|
@ -1,12 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtEndingSpace,
|
||||
#superclass : #GrafoscopioFormat,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtEndingSpace >> beInstalledIn: aNode [
|
||||
self
|
||||
installTextNodeAtRightWithValue: String space
|
||||
in: aNode
|
||||
]
|
@ -1,14 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFmtUrlAsBody,
|
||||
#superclass : #GrafoscopioFormat,
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFmtUrlAsBody >> beInstalledIn: anExternalLink [
|
||||
anExternalLink children isEmpty ifFalse: [ ^ self ].
|
||||
self
|
||||
installTextNodeAtRightWithValue: anExternalLink reference asString
|
||||
in: anExternalLink
|
||||
|
||||
]
|
@ -1,41 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioFormat,
|
||||
#superclass : #Object,
|
||||
#classInstVars : [
|
||||
'instance'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioFormat class >> instance [
|
||||
^ instance ifNil: [ instance := self new ]
|
||||
]
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFormat >> beInstalledIn: aNode [
|
||||
self subclassResponsibility .
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFormat >> installTextNodeAtLeftWithValue: aString in: aNode [
|
||||
| newTextChild |
|
||||
newTextChild := self newTextChildFor: aString in: aNode.
|
||||
aNode children: {newTextChild} , aNode children
|
||||
]
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFormat >> installTextNodeAtRightWithValue: aString in: aNode [
|
||||
| newTextChild |
|
||||
newTextChild := self newTextChildFor: aString in: aNode.
|
||||
aNode children: aNode children , {newTextChild}
|
||||
]
|
||||
|
||||
{ #category : #'target resize' }
|
||||
GrafoscopioFormat >> newTextChildFor: aString in: aNode [
|
||||
^ GrafoscopioFormatTextNode new
|
||||
text: aString;
|
||||
parent: aNode;
|
||||
yourself
|
||||
]
|
@ -1,16 +0,0 @@
|
||||
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
|
||||
]
|
@ -1,65 +0,0 @@
|
||||
"
|
||||
Leaf node. Any content node is leaf
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioLeafNode,
|
||||
#superclass : #GrafoscopioAbstractNode,
|
||||
#instVars : [
|
||||
'parent'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioLeafNode class >> isLeaf [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioLeafNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitLeafNode: self.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioLeafNode >> addAtBeginningChild: aBlock ofClass: aClass [
|
||||
self error: 'Leaf nodes are abstract. '
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioLeafNode >> addChild: aBlock ofClass: aClass [
|
||||
self error: 'Leaf nodes are abstract. '
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioLeafNode >> level [
|
||||
"Returns the level of the node. See the setter message for details"
|
||||
|
||||
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent level ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioLeafNode >> moveDown [
|
||||
parent moveDown: self.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioLeafNode >> moveUp [
|
||||
parent moveUp: self.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioLeafNode >> parent [
|
||||
"Returns the parent of the current node"
|
||||
^ parent
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioLeafNode >> parent: aNode [
|
||||
parent := aNode
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioLeafNode >> remove [
|
||||
parent remove: self.
|
||||
]
|
@ -5,16 +5,16 @@ I'm responsable for showing the links and selecting them.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioLinksList,
|
||||
#superclass : #ComposablePresenter,
|
||||
#superclass : #ComposableModel,
|
||||
#instVars : [
|
||||
'links'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GrafoscopioLinksList class >> defaultSpec [
|
||||
^ SpLayout composed
|
||||
^ SpecLayout composed
|
||||
add: #links;
|
||||
yourself
|
||||
]
|
||||
|
8
repository/Grafoscopio/GrafoscopioLinkstModel.class.st
Normal file
8
repository/Grafoscopio/GrafoscopioLinkstModel.class.st
Normal file
@ -0,0 +1,8 @@
|
||||
Class {
|
||||
#name : #GrafoscopioLinkstModel,
|
||||
#superclass : #ComposableModel,
|
||||
#instVars : [
|
||||
'links'
|
||||
],
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioNewCodeModel,
|
||||
#superclass : #GrafoscopioNewTextModel,
|
||||
#instVars : [
|
||||
'preview',
|
||||
'previewButton'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GrafoscopioNewCodeModel class >> defaultSpec [
|
||||
^ SpBoxLayout newVertical
|
||||
add: #body;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> content: aGrafoscopioNodeContent [
|
||||
self layout: (self createLayoutFor: aGrafoscopioNodeContent).
|
||||
body text: (aGrafoscopioNodeContent ifNil: [ '' ])
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> createLayoutFor: aGrafoscopioNodeContent [
|
||||
^ SpBoxLayout newVertical
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add:
|
||||
(SpBoxLayout newVertical
|
||||
add: #up;
|
||||
add: #down;
|
||||
add: #delete;
|
||||
yourself)
|
||||
width: 30;
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add: #body;
|
||||
add: #previewButton width: 30;
|
||||
add: #preview;
|
||||
yourself);
|
||||
yourself)
|
||||
height: (self heightFor: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> editionLayoutFor: aGrafoscopioNodeContent [
|
||||
^ SpBoxLayout newVertical
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add:
|
||||
(SpBoxLayout newVertical
|
||||
add: #up;
|
||||
add: #down;
|
||||
add: #delete;
|
||||
yourself)
|
||||
width: 30;
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add: #body;
|
||||
add: #previewButton width: 30;
|
||||
add: #preview;
|
||||
yourself);
|
||||
yourself)
|
||||
height: (self heightFor: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> initializeWidgets [
|
||||
super initializeWidgets.
|
||||
previewButton := self newButton.
|
||||
previewButton icon: (self iconNamed: #smallFind).
|
||||
previewButton action: [ self previewCode ].
|
||||
preview := self newLabel
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> newTextComponent [
|
||||
^ self newCode
|
||||
whenTextChangedDo: [ model text: body text ];
|
||||
autoAccept: true;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> normalLayoutFor: aGrafoscopioNodeContent [
|
||||
^ SpBoxLayout newVertical
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add: #body;
|
||||
add: #previewButton width: 30;
|
||||
add: #preview;
|
||||
yourself);
|
||||
yourself)
|
||||
height: (self heightFor: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewCodeModel >> previewCode [
|
||||
[ preview label: (self class compiler evaluate: body text) asString ]
|
||||
on: Error
|
||||
do: [ :e | preview label: e asString]
|
||||
]
|
@ -1,85 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioNewTextInputModel,
|
||||
#superclass : #SpDynamicPresenter,
|
||||
#instVars : [
|
||||
'#body',
|
||||
'#model',
|
||||
'=>',
|
||||
'SpObservableSlot',
|
||||
'#onModifyNodeLocationDo'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GrafoscopioNewTextInputModel class >> defaultSpec [
|
||||
^ SpBoxLayout newVertical
|
||||
add: #body height: 300;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #API }
|
||||
GrafoscopioNewTextInputModel >> content: aGrafoscopioNodeContent [
|
||||
self layout: (self createLayoutFor: aGrafoscopioNodeContent).
|
||||
body text: (aGrafoscopioNodeContent ifNil: [ '' ])
|
||||
]
|
||||
|
||||
{ #category : #API }
|
||||
GrafoscopioNewTextInputModel >> createLayoutFor: aGrafoscopioNodeContent [
|
||||
^ SpBoxLayout newVertical
|
||||
add: #body
|
||||
height: (self heightFor: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioNewTextInputModel >> heightFor: aGrafoscopioNodeContent [
|
||||
^ aGrafoscopioNodeContent
|
||||
ifNil: [ 100 ]
|
||||
ifNotNil: [ (aGrafoscopioNodeContent asString lines size * self class toolbarHeight) max: 100 ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> informModification [
|
||||
onModifyNodeLocationDo
|
||||
ifNotNil: [ onModifyNodeLocationDo cull: self ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> initialize [
|
||||
super initialize.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> initializePrivateAnnouncements [
|
||||
super initializePrivateAnnouncements.
|
||||
self property: #model whenChangedDo: [ self modelChanged ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> initializeWidgets [
|
||||
body := self newTextComponent.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> model: aModel [
|
||||
model := aModel
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> modelChanged [
|
||||
self content: model text.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> newTextComponent [
|
||||
^ self newTextInput whenTextChangedDo: [
|
||||
model text: body text.
|
||||
self informModification ];
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextInputModel >> onModifyNodeLocationDo: aBlock [
|
||||
onModifyNodeLocationDo := aBlock
|
||||
]
|
@ -1,78 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioNewTextModel,
|
||||
#superclass : #GrafoscopioNewTextInputModel,
|
||||
#instVars : [
|
||||
'up',
|
||||
'down',
|
||||
'delete',
|
||||
'editionMode',
|
||||
'lastHeightUsed'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> createLayoutFor: aGrafoscopioNodeContent [
|
||||
lastHeightUsed := (self heightFor: aGrafoscopioNodeContent).
|
||||
^ editionMode
|
||||
ifTrue: [ self editionLayoutFor: aGrafoscopioNodeContent ]
|
||||
ifFalse: [ self normalLayoutFor: aGrafoscopioNodeContent ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> editionLayoutFor: aGrafoscopioNodeContent [
|
||||
^ SpBoxLayout newVertical
|
||||
add:
|
||||
(SpBoxLayout newHorizontal
|
||||
add:
|
||||
(SpBoxLayout newVertical
|
||||
add: #up;
|
||||
add: #down;
|
||||
add: #delete;
|
||||
yourself)
|
||||
width: 30;
|
||||
add: #body;
|
||||
yourself)
|
||||
height: (self heightFor: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> initializeWidgets [
|
||||
super initializeWidgets .
|
||||
editionMode := true.
|
||||
up := self newButton icon: (self iconNamed: #up) ; color: Color transparent ; yourself .
|
||||
down := self newButton icon: (self iconNamed: #down) ; color: Color transparent ; yourself .
|
||||
delete := self newButton icon: (self iconNamed: #delete) ; color: Color transparent ; yourself .
|
||||
up action: [ model moveUp. self informModification. ].
|
||||
down action: [ model moveDown. self informModification.].
|
||||
delete action: [ model remove .self informModification. ]
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> newTextComponent [
|
||||
^ self newText
|
||||
whenTextChangedDo: [ self textChanged ];
|
||||
autoAccept: true;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> normalLayoutFor: aGrafoscopioNodeContent [
|
||||
^ SpBoxLayout newVertical
|
||||
add: #body
|
||||
height: (self heightFor: aGrafoscopioNodeContent)
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> textChanged [
|
||||
model text: body text.
|
||||
(lastHeightUsed - (self heightFor: model text )) abs
|
||||
> (lastHeightUsed * 0.1)
|
||||
ifTrue: [ self modelChanged ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNewTextModel >> toogleEditionMode [
|
||||
editionMode := editionMode not.
|
||||
]
|
@ -32,7 +32,7 @@ Class {
|
||||
#classInstVars : [
|
||||
'clipboard'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
#category : #'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #utility }
|
||||
@ -96,6 +96,7 @@ GrafoscopioNode >> addNode: aNode [
|
||||
of the node"
|
||||
"aNode parent = self ifTrue: [ ^ self ]."
|
||||
self children add: aNode.
|
||||
aNode level: (self level) + 1.
|
||||
aNode parent: self.
|
||||
^aNode
|
||||
]
|
||||
@ -103,19 +104,13 @@ GrafoscopioNode >> addNode: aNode [
|
||||
{ #category : #'add/remove nodes' }
|
||||
GrafoscopioNode >> addNodeAfterMe [
|
||||
"Adds a generic node after the given node so they become slibings of the same parent"
|
||||
|
||||
| genericNode |
|
||||
genericNode := self class new
|
||||
created: DateAndTime now printString;
|
||||
header: 'newNode';
|
||||
body: ''.
|
||||
self parent
|
||||
ifNil: [
|
||||
self children add: genericNode.
|
||||
genericNode parent: self ]
|
||||
ifNotNil: [ self parent children add: genericNode after: self.
|
||||
genericNode parent: self parent ].
|
||||
genericNode := self class new header: 'newNode'; body: ''.
|
||||
self parent children add: genericNode after: self.
|
||||
genericNode parent: self parent.
|
||||
genericNode level: self level.
|
||||
^ genericNode
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -190,17 +185,6 @@ GrafoscopioNode >> asSton [
|
||||
"Exports current tree as STON format"
|
||||
| stonOutput |
|
||||
|
||||
stonOutput := '' writeStream.
|
||||
stonOutput nextPutAll: (STON toStringPretty: self "flatten").
|
||||
^stonOutput contents
|
||||
|
||||
]
|
||||
|
||||
{ #category : #exporting }
|
||||
GrafoscopioNode >> asStonFromRoot [
|
||||
"Exports current tree as STON format"
|
||||
| stonOutput |
|
||||
|
||||
stonOutput := '' writeStream.
|
||||
self flatten.
|
||||
stonOutput nextPutAll: (STON toStringPretty: self children).
|
||||
@ -208,14 +192,57 @@ GrafoscopioNode >> asStonFromRoot [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #exporting }
|
||||
GrafoscopioNode >> asTreeNodePresenter [
|
||||
node := TreeNodePresenter new.
|
||||
node
|
||||
hasChildren: [ self children isNotEmpty ];
|
||||
children: [ self children collect: [ :subNode | subNode asTreeNodePresenter ] ];
|
||||
content: self.
|
||||
^ node
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> asText [
|
||||
^ self body
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNode >> becomeDefaultTestTree [
|
||||
| node1 node2 node3 node4 |
|
||||
self
|
||||
level: 0;
|
||||
header: 'Arbol principal'.
|
||||
node1 := self class new
|
||||
header: 'Markup';
|
||||
body: 'I am <b>just a node with markup</b>';
|
||||
tagAs: 'text';
|
||||
links: 'temp.md';
|
||||
level: 1.
|
||||
node2 := self class new
|
||||
header: '%output Code';
|
||||
tagAs: 'código';
|
||||
body: '(ConfigurationOfGrafoscopio>>#version14:) sourceCode'.
|
||||
node3 := self class new
|
||||
header: '%invisible';
|
||||
tagAs: 'text';
|
||||
body: '<i>Just testing</i>'.
|
||||
node1 addNode: node3.
|
||||
node4 := self class new
|
||||
header: 'Something';
|
||||
tagAs: 'text';
|
||||
body: '<h1>else</h1>'.
|
||||
node1 addNode: node4.
|
||||
node1 addNode: node2.
|
||||
self
|
||||
addNode: node1.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNode >> becomeDefaultTree [
|
||||
"I create a starting tree for all Grafoscopio notebooks with just one textual node as child."
|
||||
| node1 |
|
||||
self class new.
|
||||
self
|
||||
level: 0;
|
||||
header: 'Arbol principal';
|
||||
tagAs: 'código'.
|
||||
node1 := self class new
|
||||
header: 'Node 1';
|
||||
body: '';
|
||||
tagAs: 'text'.
|
||||
self addNode: node1.
|
||||
^ self
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -228,6 +255,8 @@ GrafoscopioNode >> body [
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> body: anObject [
|
||||
"Sets the receivers body to the given object"
|
||||
|
||||
body := anObject
|
||||
]
|
||||
|
||||
@ -250,39 +279,11 @@ GrafoscopioNode >> bodyAsMarkdownInto: aStream [
|
||||
self embeddedNodes ifNotNil: [ aStream nextPutAll: (self embedNodes contents asString withInternetLineEndings); crlf; crlf].
|
||||
]
|
||||
|
||||
{ #category : #'add/remove nodes' }
|
||||
GrafoscopioNode >> buildPreorderCollection: aCollection [
|
||||
"Stores the current node in a collection and recursively stores its children"
|
||||
|
||||
aCollection add: self.
|
||||
(self children isNotEmpty) & ((self header findString: '#invisible')=1) not
|
||||
ifTrue: [ (self children) do: [ :eachNode | eachNode buildPreorderCollection: aCollection]].
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> checksum [
|
||||
"I return the SHA1SUM of the current node.
|
||||
I'm used to test changes on the node contents, without including changes in the children."
|
||||
| nodeCopy |
|
||||
nodeCopy := self surfaceCopy.
|
||||
^ self checksumFor: nodeCopy asSton.
|
||||
]
|
||||
|
||||
{ #category : #utility }
|
||||
GrafoscopioNode >> checksumFor: aText [
|
||||
"I return the SHA1SUM of the current tree. I'm used to test changes on the contents
|
||||
and for traceability of how the document tree is converted to other formats, as markdown."
|
||||
^ (SHA1 new hashMessage: aText) hex
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> checksumForRootSubtree [
|
||||
"I return the SHA1SUM of the current tree. I'm used to test changes on the contents
|
||||
and for traceability of how the document tree is converted to other formats, as markdown."
|
||||
^ self checksumFor: self root flatten asStonFromRoot.
|
||||
"^ (SHA1 new hashMessage: self root flatten asStonFromRoot) hex"
|
||||
^ (SHA1 new hashMessage: self root flatten asSton) hex
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -300,9 +301,19 @@ GrafoscopioNode >> children: aCollection [
|
||||
children := aCollection.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> content [
|
||||
"Returns the receivers body"
|
||||
|
||||
^ body
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> content: anObject [
|
||||
"Sets the receivers body to the given object"
|
||||
|
||||
body := anObject
|
||||
]
|
||||
|
||||
{ #category : #'add/remove nodes' }
|
||||
@ -312,19 +323,6 @@ GrafoscopioNode >> copyToClipboard [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> created [
|
||||
|
||||
^ created
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> created: aTimestamp [
|
||||
"I tell when this object was created"
|
||||
|
||||
created := aTimestamp
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> currentLink [
|
||||
"TODO: This method should not only select sanitized links, but also provide ways to detect wich link
|
||||
@ -355,34 +353,6 @@ GrafoscopioNode >> demote [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioNode >> detectSelectionIndex [
|
||||
"I tell which is the index of the current selected node or return the first childre
|
||||
(indexed at 1) if is not found."
|
||||
|
||||
| root |
|
||||
root := self root.
|
||||
root preorderTraversal allButFirst doWithIndex: [ :currentNode :index |
|
||||
currentNode isSelected ifTrue: [ ^ index ] ].
|
||||
^ 1.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> edited [
|
||||
^ edited
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> edited: aTimestamp [
|
||||
"I store the last time when a node was edited.
|
||||
Because nodes in the notebook have a autosave feature, I'm updated automatically when nodes are
|
||||
edited from the GUI.
|
||||
|
||||
If I'm in the notebook root (i.e. node's level equals 0) I should store the last time the notebook
|
||||
was saved on the hard drive."
|
||||
edited := aTimestamp
|
||||
]
|
||||
|
||||
{ #category : #'custom markup' }
|
||||
GrafoscopioNode >> embedAll [
|
||||
"This is just a previous part of the messy markDownContent. The %embed-all keyword should be revaluated.
|
||||
@ -495,7 +465,7 @@ GrafoscopioNode >> footnoteAsMarkdownInto: aStream [
|
||||
and replace all line endings to make them Internet friendly.
|
||||
Maybe I should include the condition about my own header, instead of leaving it to markdownCotent..."
|
||||
aStream nextPutAll: ('[^',(self header copyReplaceAll: '%footnote ' with: ''),']: ' ); lf.
|
||||
self body contents asString withInternetLineEndings
|
||||
self body contents withInternetLineEndings
|
||||
linesDo: [ :line | aStream nextPutAll: ' ', line; lf ].
|
||||
aStream nextPutAll: String lf.
|
||||
|
||||
@ -557,7 +527,7 @@ GrafoscopioNode >> headerStartsWith: aString [
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> headers [
|
||||
"I returns the headers of the receiver children"
|
||||
^ self children collect: [:currentNode | currentNode header ]
|
||||
^ headers := self children collect: [:currentNode | currentNode header ]
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
@ -597,18 +567,6 @@ GrafoscopioNode >> icon: aSymbol [
|
||||
icon := aSymbol
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> id [
|
||||
^id
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> id: aChecksum [
|
||||
"I'm a unique identifier that changes when node content changes (i.e. header, body, links)."
|
||||
|
||||
id := aChecksum
|
||||
]
|
||||
|
||||
{ #category : #importing }
|
||||
GrafoscopioNode >> importHtmlLink [
|
||||
"I take the last link and import its contents in node body. "
|
||||
@ -643,10 +601,8 @@ GrafoscopioNode >> initialize [
|
||||
self
|
||||
header: 'newHeader';
|
||||
tagAs: 'text';
|
||||
body: ''.
|
||||
id := UUID new.
|
||||
created := DateAndTime now.
|
||||
edited := DateAndTime now
|
||||
body: '';
|
||||
level: 0
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -654,21 +610,6 @@ GrafoscopioNode >> isEmpty [
|
||||
body ifNil: [ ^ true ] ifNotNil: [ ^ false ]
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> isSavedAfterLastEdition [
|
||||
| root |
|
||||
root := self root.
|
||||
root edited ifNil: [ ^ false ].
|
||||
^ self unsavedNodes isEmpty.
|
||||
"self unsavedNodes isEmpty ifFalse: [ ^ self unsavedNodes inspect ]"
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioNode >> isSelected [
|
||||
self selected ifNil: [ ^ false ].
|
||||
^ self selected.
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> isTaggedAs: aString [
|
||||
self tags ifEmpty: [ self tagAs: 'text' ].
|
||||
@ -720,14 +661,22 @@ GrafoscopioNode >> lastLink [
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> lastNetLink [
|
||||
^ self links detect: [ :l | l asZnUrl ]
|
||||
^ self links detect: [ :l | l asZnUrl isURL ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> level [
|
||||
"Returns the level of the node. See the setter message for details"
|
||||
|
||||
^ parent ifNil: [ 0 ] ifNotNil: [ 1 + parent level ]
|
||||
^level
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> level: anInteger [
|
||||
"Sets the node level in a hierarchy. The only node with level 0 is the root node and from there levels increase
|
||||
in 1 for its direct children, 2 for its grand children and so on. Silibings nodes has the same level"
|
||||
|
||||
level := anInteger
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -742,12 +691,12 @@ GrafoscopioNode >> links: anObject [
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> linksToMarkupFile [
|
||||
GrafoscopioNode >> linksToMarkdownFile [
|
||||
"I detect if the links contains any reference to a file ending in '.md' or '.markdown'"
|
||||
self links
|
||||
ifNotNil: [
|
||||
self links
|
||||
detect: [:l | (l endsWithAnyOf: #('.md' '.markdown' '.md.html'))]
|
||||
detect: [:l | (l endsWith: '.md') or: [ l endsWith: '.markdown']]
|
||||
ifFound: [ ^ true ]
|
||||
ifNone: [^ false]].
|
||||
^ false
|
||||
@ -845,33 +794,29 @@ GrafoscopioNode >> metadataAsYamlIn: markdownStream [
|
||||
]
|
||||
|
||||
{ #category : #movement }
|
||||
GrafoscopioNode >> moveDown [
|
||||
GrafoscopioNode >> moveAfter [
|
||||
"Moves the current node a place before in the children collection where is located"
|
||||
|
||||
self parent moveDown: self
|
||||
| collection index successor |
|
||||
collection := self parent children.
|
||||
index := collection indexOf: self.
|
||||
(index between: 1 and: collection size - 1)
|
||||
ifTrue: [
|
||||
successor := collection after: self.
|
||||
collection at: index + 1 put: self.
|
||||
collection at: index put: successor]
|
||||
]
|
||||
|
||||
{ #category : #movement }
|
||||
GrafoscopioNode >> moveDown: aNode [
|
||||
| index |
|
||||
GrafoscopioNode >> moveBefore [
|
||||
"Moves the current node a place before in the children collection where is located"
|
||||
index := children indexOf: aNode.
|
||||
children swap: index with: (index + 1 min: children size)
|
||||
]
|
||||
|
||||
{ #category : #movement }
|
||||
GrafoscopioNode >> moveUp [
|
||||
"Moves the current node a place before in the children collection where is located"
|
||||
|
||||
self parent moveUp: self
|
||||
]
|
||||
|
||||
{ #category : #movement }
|
||||
GrafoscopioNode >> moveUp: aNode [
|
||||
| index |
|
||||
"Moves the current node a place before in the children collection where is located"
|
||||
index := children indexOf: aNode.
|
||||
children swap: index with: (index - 1 max: 1)
|
||||
| collection index predecessor |
|
||||
collection := self parent children.
|
||||
index := collection indexOf: self.
|
||||
(index between: 2 and: collection size)
|
||||
ifTrue: [
|
||||
predecessor := collection before: self.
|
||||
collection at: index -1 put: self.
|
||||
collection at: index put: predecessor]
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
@ -886,12 +831,14 @@ GrafoscopioNode >> newNode [
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> output [
|
||||
(self isTaggedAs: 'código')
|
||||
ifFalse: [ ^ self ].
|
||||
(self isTaggedAs: 'código') ifFalse: [ ^ self ].
|
||||
self body ifNil: [ ^ nil ].
|
||||
^ OpalCompiler new
|
||||
source: self body;
|
||||
evaluate
|
||||
^ (Compiler evaluate: self body)
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> output: anObject [
|
||||
output := anObject
|
||||
]
|
||||
|
||||
{ #category : #utility }
|
||||
@ -952,10 +899,9 @@ GrafoscopioNode >> pasteFromClipboard [
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> preorderTraversal [
|
||||
| nodesInPreorder |
|
||||
nodesInPreorder := OrderedCollection new.
|
||||
self buildPreorderCollection: nodesInPreorder.
|
||||
^ nodesInPreorder
|
||||
self visitedGoTo: nodesInPreorder.
|
||||
^ nodesInPreorder.
|
||||
]
|
||||
|
||||
{ #category : #movement }
|
||||
@ -967,6 +913,7 @@ GrafoscopioNode >> promote [
|
||||
collection isNotNil & grandparent isNotNil
|
||||
ifTrue: [
|
||||
(grandparent children) add: self after: (self parent).
|
||||
self level: (self parent) level.
|
||||
self parent: grandparent.
|
||||
collection remove: self.]
|
||||
|
||||
@ -1049,16 +996,15 @@ GrafoscopioNode >> saveContent: anObject [
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> selectMarkupSubtreesToExport [
|
||||
^ (self root preorderTraversal) select: [ :each | each linksToMarkupFile ].
|
||||
GrafoscopioNode >> selectMarkdownSubtreesToExport [
|
||||
^ (self root preorderTraversal) select: [ :each | each linksToMarkdownFile ].
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNode >> specModelClass [
|
||||
(self isTaggedAs: 'código')
|
||||
ifTrue: [ ^ GrafoscopioCodeModel ].
|
||||
(self isTaggedAs: 'johan')
|
||||
ifTrue: [ ^ GrafoscopioButtonModel ].
|
||||
|
||||
(self isTaggedAs: 'código') ifTrue: [^GrafoscopioCodeModel].
|
||||
(self isTaggedAs: 'johan') ifTrue:[^GrafoscopioButtonModel].
|
||||
"por defecto"
|
||||
^ GrafoscopioTextModel
|
||||
]
|
||||
@ -1083,12 +1029,10 @@ GrafoscopioNode >> surfaceCopy [
|
||||
to the rest of the container tree, which could end in copying the whole tree."
|
||||
| newNode |
|
||||
newNode := self class new.
|
||||
newNode
|
||||
^ newNode
|
||||
header: self header;
|
||||
body: self body;
|
||||
tags: self tags.
|
||||
self links ifNotEmpty: [ newNode links addAll: self links ].
|
||||
^ newNode.
|
||||
|
||||
|
||||
]
|
||||
@ -1144,26 +1088,10 @@ GrafoscopioNode >> toggleCodeText [
|
||||
ifTrue: [ ^ self tags replaceAll: 'código' with: 'text' ].
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNode >> unsavedNodes [
|
||||
"I collect all nodes that have changed after the last saving"
|
||||
| lastSavedOn root unsavedNodes |
|
||||
root := self root.
|
||||
lastSavedOn := root edited asDateAndTime.
|
||||
unsavedNodes := root preorderTraversal select: [ :currentNode |
|
||||
currentNode edited isNotNil and: [currentNode edited asDateAndTime > lastSavedOn] ].
|
||||
^ unsavedNodes.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioNode >> updateEditionTimestamp [
|
||||
self edited: DateAndTime now printString
|
||||
]
|
||||
|
||||
{ #category : #importing }
|
||||
GrafoscopioNode >> uploadBodyFrom: fileLocator filteredFor: selectedLink [
|
||||
self body: fileLocator contents
|
||||
(self linksFilters contains: selectedLink)
|
||||
ifFalse: [ self body: fileLocator contents ]
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
@ -1173,27 +1101,48 @@ GrafoscopioNode >> visitLastLink [
|
||||
[WebBrowser openOn: self lastLink] fork
|
||||
]
|
||||
|
||||
{ #category : #'add/remove nodes' }
|
||||
GrafoscopioNode >> visitedGoTo: aCollection [
|
||||
"Stores the current node in a collection and recursively stores its children"
|
||||
|
||||
aCollection add: self.
|
||||
(self children isNotEmpty) & ((self header findString: '#invisible')=1) not
|
||||
ifTrue: [ (self children) do: [ :eachNode | eachNode visitedGoTo: aCollection]].
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioNode >> wrapBodyLines [
|
||||
"I convert the node body from HTML format to Pandoc's Markdown."
|
||||
|
||||
self wrapBodyLines: 80
|
||||
| bodyFile |
|
||||
(self isTaggedAs: 'código' ) ifTrue: [ ^self ].
|
||||
bodyFile := FileLocator temp asFileReference / 'body.txt'.
|
||||
bodyFile ensureCreateFile.
|
||||
bodyFile writeStreamDo: [:out | out nextPutAll: self body ].
|
||||
Smalltalk platformName = 'unix'
|
||||
ifTrue: [ self body: (self wrapBodyLinesFor: bodyFile) ].
|
||||
Smalltalk platformName = 'Win32'
|
||||
ifTrue: [ self shouldBeImplemented ].
|
||||
bodyFile ensureDelete.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioNode >> wrapBodyLines: aWidth [
|
||||
"I convert the node body from HTML format to Pandoc's Markdown."
|
||||
|
||||
| bodyReader chunck |
|
||||
(self isTaggedAs: 'código')
|
||||
ifTrue: [ ^ self ].
|
||||
bodyReader := body readStream.
|
||||
body := String
|
||||
streamContents: [ :bodyWriter |
|
||||
[ bodyReader atEnd ]
|
||||
whileFalse: [
|
||||
chunck := bodyReader next: aWidth - 1.
|
||||
bodyWriter nextPutAll: chunck.
|
||||
bodyReader atEnd
|
||||
ifFalse: [ bodyWriter nextPut: Character lf ] ] ]
|
||||
GrafoscopioNode >> wrapBodyLinesFor: inputFile [
|
||||
| outputFile |
|
||||
outputFile := FileLocator temp / 'body.tmp.txt'.
|
||||
outputFile ensureDelete.
|
||||
outputFile ensureCreateFile.
|
||||
OSSUnixSubprocess new
|
||||
command: 'fold';
|
||||
arguments: {'-sw'. '80'. inputFile fullName. outputFile fullName};
|
||||
redirectStdout;
|
||||
redirectStderr;
|
||||
runAndWaitOnExitDo: [ :process :outString :errString |
|
||||
process isSuccess
|
||||
ifTrue: [ ^ outString ]
|
||||
ifFalse: [
|
||||
self inform: errString.
|
||||
^inputFile contents ]
|
||||
]
|
||||
]
|
||||
|
@ -4,7 +4,7 @@ I test the main functionality of the GrafoscopioNode class.
|
||||
Class {
|
||||
#name : #GrafoscopioNodeTest,
|
||||
#superclass : #TestCase,
|
||||
#category : 'Grafoscopio-Model'
|
||||
#category : #'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #tests }
|
||||
@ -16,45 +16,11 @@ GrafoscopioNodeTest >> dummyHtml [
|
||||
^ txt
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> newTestTree [
|
||||
| node0 node1 node2 node3 node4 |
|
||||
node0 := GrafoscopioTextNode new
|
||||
created: DateAndTime now;
|
||||
header: 'Arbol principal'.
|
||||
node1 := GrafoscopioTextNode new
|
||||
created: DateAndTime now;
|
||||
header: 'Markup';
|
||||
body: 'I am <b>just a node with markup</b>';
|
||||
tagAs: 'text';
|
||||
links: 'temp.md'.
|
||||
node2 := GrafoscopioTextNode new
|
||||
created: DateAndTime now ;
|
||||
header: '%output Code';
|
||||
tagAs: 'código';
|
||||
body: '(ConfigurationOfGrafoscopio>>#version14:) sourceCode'.
|
||||
node3 := GrafoscopioTextNode new
|
||||
created: DateAndTime now ;
|
||||
header: '%invisible';
|
||||
tagAs: 'text';
|
||||
body: '<i>Just testing</i>'.
|
||||
node1 addNode: node3.
|
||||
node4 := GrafoscopioTextNode new
|
||||
created: DateAndTime now ;
|
||||
header: 'Something';
|
||||
tagAs: 'text';
|
||||
body: '<h1>else</h1>'.
|
||||
node1 addNode: node4.
|
||||
node1 addNode: node2.
|
||||
node0 addNode: node1.
|
||||
^ node0
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> testAddingChildren [
|
||||
| tree nnode orig |
|
||||
tree := self newTestTree.
|
||||
nnode := GrafoscopioTextNode new.
|
||||
tree := GrafoscopioNode new becomeDefaultTestTree.
|
||||
nnode := GrafoscopioNode new.
|
||||
orig := tree children size.
|
||||
tree addNode: nnode.
|
||||
self assert: tree children size equals: orig + 1.
|
||||
@ -64,9 +30,9 @@ GrafoscopioNodeTest >> testAddingChildren [
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> testDemoteNode [
|
||||
| tree child1 child2 |
|
||||
tree := GrafoscopioTextNode new.
|
||||
child1 := GrafoscopioTextNode new.
|
||||
child2 := GrafoscopioTextNode new.
|
||||
tree := GrafoscopioNode new.
|
||||
child1 := GrafoscopioNode new.
|
||||
child2 := GrafoscopioNode new.
|
||||
tree
|
||||
addNode: child1;
|
||||
addNode: child2.
|
||||
@ -79,7 +45,7 @@ GrafoscopioNodeTest >> testDemoteNode [
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> testFindAndReplace [
|
||||
| tree |
|
||||
tree := GrafoscopioTextNode new.
|
||||
tree := GrafoscopioNode new.
|
||||
tree body: 'I''m only a test node.'.
|
||||
tree find: 'only' andReplaceWith: 'JUST'.
|
||||
self assert: (tree body findString: 'JUST') > 0.
|
||||
@ -93,22 +59,22 @@ GrafoscopioNodeTest >> testHasMarkdownSubtreesToExport [
|
||||
result of this test is true.
|
||||
Please see look #becomeDefaultTestTree message to see the details that makes this test true."
|
||||
| tree |
|
||||
tree := self newTestTree.
|
||||
self assert: tree selectMarkupSubtreesToExport isNotEmpty equals: true.
|
||||
tree := GrafoscopioNode new becomeDefaultTestTree.
|
||||
self assert: tree selectMarkdownSubtreesToExport isNotEmpty equals: true.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> testInitializeIsOk [
|
||||
self shouldnt: [ GrafoscopioTextNode new ] raise: Error
|
||||
self shouldnt: [ GrafoscopioNode new ] raise: Error
|
||||
]
|
||||
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> testPromoteNode [
|
||||
| tree child1 child2 |
|
||||
tree := GrafoscopioTextNode new.
|
||||
child1 := GrafoscopioTextNode new.
|
||||
child2 := GrafoscopioTextNode new.
|
||||
tree := GrafoscopioNode new.
|
||||
child1 := GrafoscopioNode new.
|
||||
child2 := GrafoscopioNode new.
|
||||
tree addNode: child1.
|
||||
child1 addNode: child2.
|
||||
child2 promote.
|
||||
@ -132,7 +98,7 @@ GrafoscopioNodeTest >> testRemoveLeadingLineNumbersSized [
|
||||
9var nodes = tree.nodes(treeData);
|
||||
10var links = tree.links(nodes);
|
||||
11 '.
|
||||
testNode := GrafoscopioTextNode new
|
||||
testNode := GrafoscopioNode new
|
||||
body: copiedCode.
|
||||
testNode removeLeadingLineNumbersSized: 3.
|
||||
self assert: testNode body equals: '
|
||||
@ -153,7 +119,7 @@ var links = tree.links(nodes);
|
||||
{ #category : #tests }
|
||||
GrafoscopioNodeTest >> testRemovingChildren [
|
||||
| tree orig |
|
||||
tree := self newTestTree..
|
||||
tree := GrafoscopioNode new becomeDefaultTestTree.
|
||||
orig := tree children size.
|
||||
orig > 0 ifTrue: [ tree removeNode: (tree children at: 1) ].
|
||||
self assert: tree children size equals: orig - 1.
|
||||
@ -165,7 +131,7 @@ GrafoscopioNodeTest >> testSanitizedLink [
|
||||
| node link |
|
||||
|
||||
link := 'docutopia://hackbo:hackbot'.
|
||||
node := GrafoscopioTextNode new links: link.
|
||||
node := GrafoscopioNode new links: link.
|
||||
self assert: (node sanitizeDefaultLink = 'https://docutopia.tupale.co/hackbo:hackbot') equals: true
|
||||
|
||||
]
|
||||
|
@ -20,13 +20,9 @@ Class {
|
||||
'workingFile',
|
||||
'notebook',
|
||||
'debugMessage',
|
||||
'imagesList',
|
||||
'exporting'
|
||||
'imagesList'
|
||||
],
|
||||
#classInstVars : [
|
||||
'recents'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #utility }
|
||||
@ -52,11 +48,6 @@ GrafoscopioNotebook class >> defaultSpec [
|
||||
bc add: #body; add: #links height: self toolbarHeight ]]]
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioNotebook class >> initialize [
|
||||
recents := Set new.
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioNotebook class >> newDefault [
|
||||
^ self new.
|
||||
@ -67,16 +58,6 @@ GrafoscopioNotebook class >> open: aFileReference [
|
||||
self newDefault openFromFile: aFileReference
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioNotebook class >> recents [
|
||||
^ recents
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioNotebook class >> registerRecent: aFileReference [
|
||||
recents add: aFileReference
|
||||
]
|
||||
|
||||
{ #category : #utilities }
|
||||
GrafoscopioNotebook >> addCommandFrom: dictionary into: stream [
|
||||
dictionary keysAndValuesDo: [ :k :v |
|
||||
@ -87,44 +68,21 @@ GrafoscopioNotebook >> addCommandFrom: dictionary into: stream [
|
||||
|
||||
{ #category : #'editing nodes' }
|
||||
GrafoscopioNotebook >> addNode [
|
||||
self currentNode addNodeAfterMe.
|
||||
self currentNodeContent addNodeAfterMe.
|
||||
self notebookContent: notebook.
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> askToSaveBeforeClosing [
|
||||
|
||||
| saveChanges |
|
||||
|
||||
saveChanges := UIManager default
|
||||
question: 'Do you want to save changes in the notebook before closing?'
|
||||
title: 'Save changes before closing?'.
|
||||
saveChanges ifNil: [ ^ self notebook unsavedNodes inspect ].
|
||||
^ saveChanges
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNotebook >> autoSaveBodyOf: aNode [
|
||||
| playground bodyContents |
|
||||
bodyContents := aNode body.
|
||||
| playground |
|
||||
self body class = GrafoscopioTextModel
|
||||
ifTrue: [ self body body
|
||||
whenTextChangedDo: [ :arg |
|
||||
aNode body: arg.
|
||||
"self body body whenTextIsAccepted: [:bodyText |
|
||||
self inform: bodyText.
|
||||
aNode updateEditionTimestamp ]."
|
||||
bodyContents = arg
|
||||
ifFalse: [ "self inform: arg.""aNode updateEditionTimestamp" ] ] ].
|
||||
self body body class = GlamourPresentationModel
|
||||
ifTrue: [ body body whenTextChanged: [ :arg | aNode body: arg ] ].
|
||||
body body class = GlamourPresentationModel
|
||||
ifFalse: [ ^ self ].
|
||||
playground := self body body glmPres.
|
||||
playground := body body glmPres.
|
||||
playground
|
||||
onChangeOfPort: #text
|
||||
act: [ :x |
|
||||
aNode body: (x pane port: #entity) value content
|
||||
"aNode updateEditionTimestamp."
|
||||
"self inform: aNode edited" ]
|
||||
act: [ :x | aNode body: (x pane port: #entity) value content ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -138,7 +96,7 @@ GrafoscopioNotebook >> body: anObject [
|
||||
]
|
||||
|
||||
{ #category : #utilities }
|
||||
GrafoscopioNotebook >> checksumForRootSubtree [
|
||||
GrafoscopioNotebook >> checksum [
|
||||
"I return the checksum (crypto hash) of the workingFile where this notebook is being stored.
|
||||
I'm useful for data provenance and traceability of derivated files coming from this source
|
||||
notebook."
|
||||
@ -147,42 +105,18 @@ GrafoscopioNotebook >> checksumForRootSubtree [
|
||||
^ GrafoscopioUtils checksumFor: self workingFile
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioNotebook >> content [
|
||||
self shouldBeImplemented.
|
||||
]
|
||||
|
||||
{ #category : #'editing nodes' }
|
||||
GrafoscopioNotebook >> copyNodeToClipboard [
|
||||
tree highlightedItem content copyToClipboard.
|
||||
self notebookContent: notebook.
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> createNewExample [
|
||||
| node0 node1 |
|
||||
node0 := GrafoscopioNode new
|
||||
created: DateAndTime now printString;
|
||||
header: 'Arbol principal';
|
||||
tagAs: 'código';
|
||||
yourself.
|
||||
node1 := GrafoscopioNode new
|
||||
created: DateAndTime now printString;
|
||||
header: 'Node 1';
|
||||
body: '';
|
||||
tagAs: 'text';
|
||||
yourself.
|
||||
node0 addNode: node1.
|
||||
^ node0
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNotebook >> currentNode [
|
||||
^ tree highlightedItem
|
||||
ifNil: [ notebook children
|
||||
ifEmpty: [ notebook root ]
|
||||
ifNotEmpty: [ notebook children first ] ]
|
||||
ifNotNil: [ :v | v content ]
|
||||
| currentNode |
|
||||
currentNode := tree highlightedItem.
|
||||
currentNode ifNil: [ ^ self ].
|
||||
^ currentNode
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
@ -253,15 +187,9 @@ GrafoscopioNotebook >> downloadImages [
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> ensureNotExporting [
|
||||
self isAlreadyExporting
|
||||
ifTrue: [ ^ self error: ' Already exporting! Please wait ' ]
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> exportAllSubtreesAsMarkup [
|
||||
GrafoscopioNotebook >> exportAllSubtreesAsMarkdow [
|
||||
| toBeExported |
|
||||
toBeExported := self notebook selectMarkupSubtreesToExport.
|
||||
toBeExported := self notebook selectMarkdownSubtreesToExport.
|
||||
toBeExported ifEmpty: [ ^ self ].
|
||||
toBeExported do: [ :each | self subtreeAsMarkdownFileFor: each ].
|
||||
self inform: toBeExported size asString , ' exported markdown subtrees.'
|
||||
@ -271,26 +199,24 @@ GrafoscopioNotebook >> exportAllSubtreesAsMarkup [
|
||||
GrafoscopioNotebook >> exportAsHTML [
|
||||
"I export the current tree/document to a HTML file, using pandoc external app.
|
||||
I suppose pandoc is already installed and available in the system."
|
||||
|
||||
| htmlFile |
|
||||
self markdownFile exists
|
||||
ifTrue: [ self markdownFile delete ].
|
||||
self markdownFile exists ifTrue: [ self markdownFile delete ].
|
||||
self exportAsMarkdown.
|
||||
htmlFile := self htmlFile.
|
||||
htmlFile exists
|
||||
ifTrue: [ htmlFile delete ].
|
||||
self
|
||||
exportUsing:
|
||||
{'--standalone'.
|
||||
self markdownFile fullName.
|
||||
'--output'.
|
||||
htmlFile fullName}
|
||||
output: htmlFile fullName
|
||||
"
|
||||
|
||||
|
||||
htmlFile := self markdownFile parent fullName,'/', self markdownFile basenameWithoutExtension, '.html'.
|
||||
htmlFile asFileReference exists ifTrue: [ htmlFile asFileReference delete ].
|
||||
Smalltalk platformName = 'unix'
|
||||
ifTrue: [
|
||||
OSSUnixSubprocess new
|
||||
command: 'pandoc';
|
||||
arguments: {'--standalone'. self markdownFile fullName. '--output' . htmlFile};
|
||||
redirectStdout;
|
||||
runAndWaitOnExitDo: [ :process :outString :errString |
|
||||
process isSuccess
|
||||
ifTrue: [ self inform: ('File exported as: ', String cr, htmlFile) ]
|
||||
ifFalse: [ self inform: 'Exportation unsuccesful. Please review that you have
|
||||
installed Pandoc and have used the exportation options properly.' ]]].
|
||||
Smalltalk platformName = 'Win32'
|
||||
ifTrue: [WinProcess createProcess: 'pandoc --standalone ', self markdownFile fullName, ' -o ', htmlFile]."
|
||||
ifTrue: ["WinProcess createProcess: 'pandoc --standalone ', self markdownFile fullName, ' -o ', htmlFile"].
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
@ -299,14 +225,12 @@ GrafoscopioNotebook >> exportAsLaTeX [
|
||||
I suppose pandoc is already installed and available in the system."
|
||||
| texFile |
|
||||
self markdownFile exists ifTrue: [ self markdownFile delete ].
|
||||
self halt.
|
||||
|
||||
"self exportAsMarkdown.""<- This violates the separation of concenrs. Markdown exportation should
|
||||
be explicit. There is still the issue of how to deal with desynchronization between a notebook
|
||||
which has unsaved changes as markdown.... TO BE REVIWED!"
|
||||
texFile := self markdownFile parent fullName,'/', self markdownFile basenameWithoutExtension, '.tex'.
|
||||
texFile asFileReference exists ifTrue: [ texFile asFileReference delete ].
|
||||
"OSProcess command: 'pandoc --standalone ', self markdownFile fullName, ' -o ', texFile."
|
||||
OSProcess command: 'pandoc --standalone ', self markdownFile fullName, ' -o ', texFile.
|
||||
self inform: ('File exported as: ', String cr, texFile).
|
||||
]
|
||||
|
||||
@ -323,28 +247,26 @@ GrafoscopioNotebook >> exportAsPDF [
|
||||
"I export the current tree/document to a PDF file, using pandoc and LaTeX external apps.
|
||||
The latex engine used is xelatex, to minimize errors and warnings related with UTF8 support.
|
||||
I suppose all them are already installed and defined in the system."
|
||||
|
||||
| pandocCommonCommand |
|
||||
self ensureNotExporting.
|
||||
self exportAsMarkdown.
|
||||
self markdownFile exists ifFalse: [ self exportAsMarkdown ].
|
||||
self pdfFile ensureDelete.
|
||||
pandocCommonCommand := self pandocOptionsComputed , ' '
|
||||
, self markdownFile fullName , ' --output ' , self pdfFile fullName.
|
||||
^ self
|
||||
exportUsing: ((' ' split: pandocCommonCommand) reject: #isEmpty)
|
||||
output: self pdfFile fullName
|
||||
pandocCommonCommand := 'pandoc ', self pandocOptionsComputed, ' ', self markdownFile fullName,
|
||||
' --output ', self pdfFile fullName.
|
||||
Smalltalk platformName = 'unix'
|
||||
ifTrue: [ ExternalOSProcess command: 'cd ', self markdownFile parent fullName,'; ', pandocCommonCommand ].
|
||||
Smalltalk platformName = 'Win32'
|
||||
ifTrue: [ WinProcess createProcess: pandocCommonCommand ].
|
||||
self inform: ('File exported as: ', String cr, self pdfFile fullName)
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> exportAsSton: aNotebook on: aFileStream [
|
||||
aNotebook flatten.
|
||||
self notebook root updateEditionTimestamp.
|
||||
(STON writer on: aFileStream)
|
||||
newLine: String crlf;
|
||||
prettyPrint: true;
|
||||
keepNewLines: true;
|
||||
nextPut: aNotebook children.
|
||||
|
||||
nextPut: aNotebook children
|
||||
]
|
||||
|
||||
{ #category : #utility }
|
||||
@ -362,7 +284,7 @@ GrafoscopioNotebook >> exportNode: aGrafoscopioNode asMarkdownIn: aFile [
|
||||
stream
|
||||
nextPutAll:
|
||||
('---', String cr,
|
||||
'exportedFrom: ', self checksumForRootSubtree, String cr) withInternetLineEndings.
|
||||
'exportedFrom: ', self checksum, String cr) withInternetLineEndings.
|
||||
aGrafoscopioNode metadataAsYamlIn: stream.
|
||||
stream
|
||||
nextPutAll:
|
||||
@ -371,37 +293,6 @@ GrafoscopioNotebook >> exportNode: aGrafoscopioNode asMarkdownIn: aFile [
|
||||
self inform: 'Exported as: ', String cr, aFile fullName
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> exportUsing: arguments [
|
||||
self ensureNotExporting.
|
||||
exporting := (#pandoc command arguments: arguments) future.
|
||||
exporting
|
||||
onSuccessDo: [ :val |
|
||||
exporting := nil.
|
||||
self
|
||||
inform: 'File exported as: ' , String cr , self pdfFile fullName ].
|
||||
exporting
|
||||
onFailureDo: [ :e |
|
||||
exporting := nil.
|
||||
self
|
||||
inform: 'Error exporting, ' , self pdfFile fullName , ': ' , e messageText ]
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> exportUsing: arguments output: aName [
|
||||
self ensureNotExporting.
|
||||
exporting := (#pandoc command arguments: arguments) future.
|
||||
exporting
|
||||
onSuccessDo: [ :val |
|
||||
exporting := nil.
|
||||
self inform: 'File exported as: ' , String cr , aName ].
|
||||
exporting
|
||||
onFailureDo: [ :e |
|
||||
exporting := nil.
|
||||
self inform: 'Error exporting, ' , aName , ': ' , e messageText ].
|
||||
^ exporting
|
||||
]
|
||||
|
||||
{ #category : #api }
|
||||
GrafoscopioNotebook >> extent [
|
||||
^900@500
|
||||
@ -422,11 +313,6 @@ GrafoscopioNotebook >> findAndReplace [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioNotebook >> hasAWorkingFileDefined [
|
||||
self workingFile ifNil: [ ^ false ] ifNotNil: [ ^ true ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNotebook >> header [
|
||||
^ header
|
||||
@ -437,13 +323,6 @@ GrafoscopioNotebook >> header: anObject [
|
||||
header := anObject
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> htmlFile [
|
||||
^ (self markdownFile parent fullName , '/'
|
||||
, self markdownFile basenameWithoutExtension , '.html')
|
||||
asFileReference
|
||||
]
|
||||
|
||||
{ #category : #operation }
|
||||
GrafoscopioNotebook >> htmlToMarkdown [
|
||||
self currentNodeContent htmlToMarkdown.
|
||||
@ -464,7 +343,6 @@ GrafoscopioNotebook >> imagesList [
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioNotebook >> imagesList: anObject [
|
||||
self halt.
|
||||
imagesList := anObject
|
||||
]
|
||||
|
||||
@ -491,12 +369,22 @@ GrafoscopioNotebook >> importLinkContent [
|
||||
GrafoscopioNotebook >> initialize [
|
||||
super initialize.
|
||||
self
|
||||
notebook: (self createNewExample );
|
||||
notebook: (GrafoscopioNode new becomeDefaultTree);
|
||||
title: ' New | Grafoscopio notebook'.
|
||||
self notebookContent: self notebook.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNotebook >> initializeDefaultTest [
|
||||
super initialize.
|
||||
self
|
||||
notebook: (GrafoscopioNode new becomeDefaultTestTree);
|
||||
title: ' New test | Grafoscopio notebook'.
|
||||
self notebookContent: self notebook.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNotebook >> initializePresenter [
|
||||
tree whenHighlightedItemChanged: [ :item |
|
||||
@ -506,12 +394,8 @@ GrafoscopioNotebook >> initializePresenter [
|
||||
(tree highlightedItem content header) = arg
|
||||
ifFalse: [
|
||||
tree highlightedItem content header: arg.
|
||||
tree highlightedItem content updateEditionTimestamp.
|
||||
tree roots: tree roots]].
|
||||
links whenTextChanged: [ :arg |
|
||||
tree highlightedItem content addLink: arg.
|
||||
tree highlightedItem content updateEditionTimestamp.
|
||||
]
|
||||
links whenTextChanged: [ :arg | tree highlightedItem content addLink: arg ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
@ -520,37 +404,20 @@ GrafoscopioNotebook >> initializeWidgets [
|
||||
header := self newTextInput.
|
||||
header autoAccept: true.
|
||||
body := self newText.
|
||||
body class traceCr.
|
||||
body disable.
|
||||
body text: '<- Select a node'.
|
||||
body autoAccept: true.
|
||||
links := self newTextInput.
|
||||
tree := self newTree.
|
||||
tree
|
||||
childrenBlock: [ :node | node children ];
|
||||
displayBlock: [ :node | node title ].
|
||||
childrenBlock: [:node | node children];
|
||||
displayBlock: [:node | node title ].
|
||||
self focusOrder
|
||||
add: tree;
|
||||
add: header;
|
||||
add: body;
|
||||
add: links.
|
||||
self askOkToClose: true
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> isAlreadyExporting [
|
||||
^ exporting isNotNil
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> isSaved [
|
||||
"I tell if a notebook has been saved in a persistence storage, including last editions."
|
||||
^ self hasAWorkingFileDefined and: [self isSavedAfterLastEdition ].
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
GrafoscopioNotebook >> isSavedAfterLastEdition [
|
||||
^ self notebook isSavedAfterLastEdition
|
||||
self askOkToClose: true.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -575,7 +442,7 @@ GrafoscopioNotebook >> linksList [
|
||||
|
||||
{ #category : #utilities }
|
||||
GrafoscopioNotebook >> listImagesUI [
|
||||
ListPresenter new
|
||||
ListModel new
|
||||
title: 'Images files list';
|
||||
items: self imagesList ;
|
||||
openWithSpec
|
||||
@ -620,18 +487,18 @@ GrafoscopioNotebook >> metadata [
|
||||
]
|
||||
|
||||
{ #category : #'editing nodes' }
|
||||
GrafoscopioNotebook >> moveSelectedNodeDown [
|
||||
GrafoscopioNotebook >> moveNodeAfter [
|
||||
| editedNode |
|
||||
editedNode := tree selectedItem content.
|
||||
editedNode moveDown.
|
||||
editedNode moveAfter.
|
||||
self notebookContent: notebook
|
||||
]
|
||||
|
||||
{ #category : #'editing nodes' }
|
||||
GrafoscopioNotebook >> moveSelectedNodeUp [
|
||||
GrafoscopioNotebook >> moveNodeBefore [
|
||||
| editedNode |
|
||||
editedNode := tree highlightedItem content.
|
||||
editedNode moveUp.
|
||||
editedNode moveBefore.
|
||||
self notebookContent: notebook
|
||||
]
|
||||
|
||||
@ -671,14 +538,21 @@ GrafoscopioNotebook >> notebook: anObject [
|
||||
|
||||
{ #category : #api }
|
||||
GrafoscopioNotebook >> notebookContent: aTree [
|
||||
tree
|
||||
roots: (aTree children collect: [ :gfcNode | gfcNode asTreeNodePresenter ]).
|
||||
tree selectedIndex: (tree selectedIndex min: aTree children size)
|
||||
|
||||
| nodeBlock |
|
||||
nodeBlock:= [:gfcNode | |node|
|
||||
node := TreeNodeModel new.
|
||||
node
|
||||
hasChildren: [ gfcNode children isNotEmpty ];
|
||||
children: [ gfcNode children collect: [:subNode | nodeBlock value: subNode ]];
|
||||
content: gfcNode].
|
||||
tree roots: (aTree children collect:[ :gfcNode | nodeBlock value: gfcNode])
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNotebook >> notebookSubMenu [
|
||||
^ MenuPresenter new
|
||||
^ MenuModel new
|
||||
addGroup: [ :group |
|
||||
group
|
||||
addItem: [ :item |
|
||||
@ -739,15 +613,15 @@ GrafoscopioNotebook >> notebookSubMenu [
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'See html';
|
||||
icon: (self iconNamed: #smallInspectIt);
|
||||
action: [ self seeHtml ] ].
|
||||
icon:
|
||||
(self iconNamed: #smallInspectIt);
|
||||
action: [ self inform: 'To be implemented...' ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'See pdf';
|
||||
icon: (Smalltalk ui icons iconNamed: #smallInspectIt);
|
||||
action: [ self seePdf ] ].
|
||||
|
||||
action: [ self inform: 'To be implemented...' ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
@ -756,10 +630,9 @@ GrafoscopioNotebook >> notebookSubMenu [
|
||||
action: [ self defineDebugMessageUI ] ] ]
|
||||
]
|
||||
|
||||
{ #category : #'event handling' }
|
||||
{ #category : #private }
|
||||
GrafoscopioNotebook >> okToChange [
|
||||
|
||||
self isSaved ifTrue: [ ^ true ] ifFalse: [ ^ self askToSaveBeforeClosing ]
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
@ -771,7 +644,7 @@ GrafoscopioNotebook >> openDefault [
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> openFromFile: aFileReference [
|
||||
self class registerRecent: aFileReference.
|
||||
|
||||
self loadFromFile: aFileReference.
|
||||
^ self openWithSpec.
|
||||
]
|
||||
@ -911,14 +784,14 @@ GrafoscopioNotebook >> promoteNode [
|
||||
{ #category : #'editing nodes' }
|
||||
GrafoscopioNotebook >> removeNode [
|
||||
| contentToDelete parentContent newSelectedContent children |
|
||||
tree selectedItem
|
||||
ifNil: [ ^ self inform: 'No node available or properly selected ' ].
|
||||
contentToDelete := tree selectedItem content.
|
||||
parentContent := contentToDelete parent.
|
||||
children := parentContent children.
|
||||
children size > 1
|
||||
ifTrue: [ children last = contentToDelete
|
||||
ifTrue: [ newSelectedContent := children at: children size - 1 ] ]
|
||||
ifTrue: [
|
||||
children last = contentToDelete
|
||||
ifTrue: [ newSelectedContent := children at: (children size - 1) ]
|
||||
]
|
||||
ifFalse: [ newSelectedContent := parentContent ].
|
||||
contentToDelete parent removeNode: contentToDelete.
|
||||
self notebookContent: notebook
|
||||
@ -926,7 +799,7 @@ GrafoscopioNotebook >> removeNode [
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> saveToFile: aFileReference [
|
||||
"I save the current tree/document to a file and update storage timestamp."
|
||||
"I save the current tree/document to a file."
|
||||
|
||||
aFileReference ifNil: [ self inform: 'No file selected for saving. Save NOT done.'. ^ self ].
|
||||
workingFile := aFileReference.
|
||||
@ -958,24 +831,11 @@ GrafoscopioNotebook >> saveWorkingNotebook [
|
||||
self workingFile
|
||||
ifNil: [ self saveToFileUI ]
|
||||
ifNotNil: [ self saveToFile: workingFile ].
|
||||
self notebook root updateEditionTimestamp.
|
||||
GfUIHelpers updateRecentNotebooksWith: workingFile
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #inspecting }
|
||||
GrafoscopioNotebook >> seeHtml [
|
||||
self pdfFile exists
|
||||
ifTrue: [ (#open command argument: self htmlFile fullName) schedule ]
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> seePdf [
|
||||
self exportAsPDF
|
||||
onSuccessDo: [ :v | (#open command argument: self pdfFile fullName) schedule ]
|
||||
]
|
||||
|
||||
{ #category : #persistence }
|
||||
GrafoscopioNotebook >> subtreeAsMarkdown [
|
||||
| currentNode |
|
||||
@ -1003,7 +863,7 @@ GrafoscopioNotebook >> toggleCodeNode [
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioNotebook >> topBar [
|
||||
^ MenuPresenter new
|
||||
^ MenuModel new
|
||||
addGroup: [ :group |
|
||||
group
|
||||
addItem: [ :item |
|
||||
@ -1031,7 +891,7 @@ GrafoscopioNotebook >> topBar [
|
||||
name: nil;
|
||||
description: 'Export all Markdown subtrees';
|
||||
icon: (self iconNamed: #glamorousMore);
|
||||
action: [ self exportAllSubtreesAsMarkup ] ].
|
||||
action: [ self exportAllSubtreesAsMarkdow ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
@ -1081,14 +941,14 @@ GrafoscopioNotebook >> topBar [
|
||||
name: nil;
|
||||
description: 'Move node up';
|
||||
icon: MendaIcons new arrowUpIcon;
|
||||
action: [ self moveSelectedNodeUp ] ].
|
||||
action: [ self moveNodeBefore ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Move node down';
|
||||
icon: MendaIcons new arrowDownIcon;
|
||||
action: [ self moveSelectedNodeDown ] ].
|
||||
action: [ self moveNodeAfter ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
@ -1206,7 +1066,7 @@ GrafoscopioNotebook >> updateBodyFor: aNodeContainer [
|
||||
body := self instantiate: aNode specModelClass new.
|
||||
body content: aNode body.
|
||||
links text: aNode lastLink.
|
||||
|
||||
self autoSaveBodyOf: aNode.
|
||||
self buildWithSpecLayout: self class defaultSpec
|
||||
]
|
||||
|
||||
|
@ -4,5 +4,5 @@ I test the main functionality of the GrafoscopioNode class.
|
||||
Class {
|
||||
#name : #GrafoscopioNotebookTest,
|
||||
#superclass : #TestCase,
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
@ -1,196 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioPerspective,
|
||||
#superclass : #SpPresenterWithModel,
|
||||
#instVars : [
|
||||
'toolbar',
|
||||
'viewport'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective class >> defaultPerspective [
|
||||
^ GrafoscopioDocumentEditionPerspective
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective class >> defaultSpec [
|
||||
^ SpBoxLayout newVertical
|
||||
add: #toolbar height: self toolbarHeight;
|
||||
add: #viewport;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective class >> isAbstract [
|
||||
^ self = GrafoscopioPerspective
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective class >> perspectives [
|
||||
^ self allSubclasses select: [ : c | c isAbstract not ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> aboutToBeUninstalledFrom: aTreeNotebook [
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> addItemTo: aGroup [
|
||||
aGroup
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'Dynamic';
|
||||
icon: (self iconNamed: #delete);
|
||||
action: [ aGroup menuItems remove: item.
|
||||
self needRebuild: false.
|
||||
self buildWithSpec ] ].
|
||||
self needRebuild: false.
|
||||
self buildWithSpec
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> addingMenu [
|
||||
| menu |
|
||||
menu := self newMenu.
|
||||
self kindsOfNode
|
||||
do: [ :n |
|
||||
menu
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: n nameForSelection;
|
||||
icon: n icon;
|
||||
action: [ self addNewNodeOfClass: n ] ] ].
|
||||
^ menu
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective >> chooseKindsOfNode [
|
||||
| idx values |
|
||||
values := self kindsOfNode.
|
||||
idx := UIManager default
|
||||
chooseFrom: values
|
||||
lines: {}
|
||||
title: 'What kind of node? '.
|
||||
^ idx = 0
|
||||
ifTrue: [ nil ]
|
||||
ifFalse: [ values at: idx ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> createToolbar [
|
||||
| aMenu |
|
||||
aMenu := self newMenuBar
|
||||
addGroup: [ :group |
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'File';
|
||||
icon: (self iconNamed: #openIcon);
|
||||
subMenu: self subMenu ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Open file';
|
||||
icon: (self iconNamed: #openIcon);
|
||||
action: [ self inform: 'Open File' ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Save File';
|
||||
icon: (self iconNamed: #smallSaveIcon);
|
||||
action: [ self inform: 'Save File' ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Print file';
|
||||
icon: (self iconNamed: #smallPrintIcon);
|
||||
action: [ self inform: 'Print file' ] ] ];
|
||||
addGroup: [ :group |
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Undo';
|
||||
icon: (self iconNamed: #smallUndoIcon);
|
||||
action: [ self inform: 'Undo' ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Redo';
|
||||
icon: (self iconNamed: #smallRedoIcon);
|
||||
action: [ self inform: 'Redo' ] ].
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: '';
|
||||
icon: (self iconNamed: #add);
|
||||
subMenu: self addingMenu ].
|
||||
|
||||
];
|
||||
addGroup: [ :group |
|
||||
group
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: nil;
|
||||
description: 'Add menu item';
|
||||
icon: (self iconNamed: #add);
|
||||
action: [ self addItemTo: group ] ] ].
|
||||
aMenu color: Color transparent.
|
||||
^ aMenu
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> createViewport [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> initializeWidgets [
|
||||
super initializeWidgets.
|
||||
toolbar := self createToolbar.
|
||||
viewport := self createViewport
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective >> kindsOfNode [
|
||||
^ GrafoscopioAbstractNode allSubclasses select: [ :c | c showInMenu ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioPerspective >> subMenu [
|
||||
^ self newMenu
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'Open';
|
||||
icon: (self iconNamed: #openIcon);
|
||||
shortcut: $o meta;
|
||||
action: [ self inform: 'Open' ] ];
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'Save';
|
||||
icon: (self iconNamed: #smallSaveIcon);
|
||||
shortcut: $s meta;
|
||||
action: [ self inform: 'Save' ] ];
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'Print';
|
||||
shortcut: $p meta;
|
||||
icon: (self iconNamed: #smallPrintIcon);
|
||||
action: [ self inform: 'Print' ] ];
|
||||
addItem: [ :item |
|
||||
item
|
||||
name: 'Close';
|
||||
shortcut: $c meta;
|
||||
icon: (self iconNamed: #smallCancelIcon);
|
||||
action: [ self inform: 'Kill' ] ];
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPerspective >> updateModel: aModel [
|
||||
]
|
@ -1,526 +0,0 @@
|
||||
"
|
||||
Pillar ASText delegates the text behavior into a pillar AST .
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioPillarASText,
|
||||
#superclass : #GrafoscopioAbstractText,
|
||||
#instVars : [
|
||||
'ast',
|
||||
'stringDecorator',
|
||||
'lastNode',
|
||||
'runs'
|
||||
],
|
||||
#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
|
||||
ast: self pillarExample;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText class >> pillarExample [
|
||||
^ PRPillarParser
|
||||
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.
|
||||
|
||||
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 >> ast [
|
||||
^ ast
|
||||
]
|
||||
|
||||
{ #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 : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> attributesAt: characterIndex do: aBlockClosure [
|
||||
self size = 0 ifTrue:[^self].
|
||||
(self runs at: characterIndex) do: aBlockClosure
|
||||
]
|
||||
|
||||
{ #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 [
|
||||
^ self detectAstNodeFor: anInteger in: ast
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> detectAstNodeFor: anInteger in: aNode [
|
||||
" The size should match "
|
||||
(anInteger between: aNode textStart and: aNode textStop)
|
||||
ifFalse: [ self error: 'Cannot find a node for ' , anInteger asString ].
|
||||
|
||||
" if the node is the same as the last, or if it is further (probably we are just iterating the thing) we try to reuse the last result or to go throug as a list. "
|
||||
lastNode ifNotNil: [
|
||||
(anInteger between: lastNode textStart and: lastNode textStop -1 ) ifTrue: [
|
||||
^ lastNode.
|
||||
].
|
||||
anInteger >= lastNode textStop ifTrue: [
|
||||
[(lastNode := lastNode next) notNil ] whileTrue: [
|
||||
(anInteger between: lastNode textStart and: lastNode textStop -1) ifTrue:[ ^ lastNode ]
|
||||
]
|
||||
]
|
||||
].
|
||||
|
||||
^ aNode hasChildren
|
||||
ifTrue: [ aNode children
|
||||
detect: [ :c | anInteger between: c textStart and: c textStop -1 ]
|
||||
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 [
|
||||
| current nodes |
|
||||
nodes := OrderedCollection new.
|
||||
current := self detectAstNodeFor: from.
|
||||
from > to
|
||||
ifTrue: [ nodes add: current ]
|
||||
ifFalse: [ [ current isNotNil and: [ current textStart <= to ] ]
|
||||
whileTrue: [ nodes add: current.
|
||||
current := current next ] ].
|
||||
^ nodes
|
||||
|
||||
|
||||
|
||||
"| 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 >> detectFullBranchFor: anId [
|
||||
^ self detectFullBranchFor: anId in: ast.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> detectFullBranchFor: anInteger in: aNode [
|
||||
| branch basenode |
|
||||
basenode := (self detectAstNodeFor: anInteger) .
|
||||
branch := OrderedCollection new.
|
||||
[basenode notNil ] whileTrue:[ branch add: basenode. basenode := basenode parent ].
|
||||
^ branch reverse.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> errorSubscriptBounds: aSomedthing [
|
||||
self halt.
|
||||
]
|
||||
|
||||
{ #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.
|
||||
|
||||
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 >> fontAt: characterIndex withStyle: aTextStyle [
|
||||
"Answer the fontfor characters in the run beginning at characterIndex."
|
||||
| attributes font |
|
||||
self size = 0 ifTrue: [^ aTextStyle defaultFont]. "null text tolerates access"
|
||||
attributes := runs at: characterIndex.
|
||||
font := aTextStyle defaultFont. "default"
|
||||
attributes do:
|
||||
[:att | att forFontInStyle: aTextStyle do: [:f | font := f]].
|
||||
^ font
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> rangeOf: aTextURL startingAt: anInteger [
|
||||
^ self runs rangeOf: aTextURL startingAt: anInteger
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> reannotate: aPRText [
|
||||
| current previous parents |
|
||||
|
||||
aPRText textStop: aPRText textStart + aPRText text size.
|
||||
aPRText markAsDirty.
|
||||
parents := Set new.
|
||||
parents add: aPRText parent.
|
||||
current := aPRText next.
|
||||
|
||||
previous := aPRText.
|
||||
|
||||
[ current isNotNil ]
|
||||
whileTrue: [
|
||||
current markAsDirty.
|
||||
current textStart: previous textStop.
|
||||
current textStop: current textStart + current text size.
|
||||
previous := current.
|
||||
current := current next.
|
||||
self ].
|
||||
|
||||
|
||||
self resetRuns.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASText >> removeAttribute: att from: start to: stop [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #editing }
|
||||
GrafoscopioPillarASText >> replaceFrom: start to: stop with: aCollection [
|
||||
| nodes realStart realStop newText node |
|
||||
((stop - start )> 1 and:[ aCollection isEmpty ]) ifTrue: [ ^self ].
|
||||
nodes := self detectAstNodesBetween: start and: stop in: ast.
|
||||
self assert: nodes size <= 1.
|
||||
node := nodes first.
|
||||
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: [
|
||||
node := self detectAstNodeFor: node textStart - 1.
|
||||
node text: node text, aCollection.
|
||||
nodes := { node }.
|
||||
].
|
||||
nodes first markAsDirty.
|
||||
self reannotate: nodes first.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASText >> resetRuns [
|
||||
^ runs := GrafoscopioPillarRuns new
|
||||
ast: self;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASText >> runs [
|
||||
^ runs
|
||||
ifNil: [ runs := GrafoscopioPillarRuns new
|
||||
ast: self;
|
||||
yourself ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASText >> size [
|
||||
^ ast textSize
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASText >> string [
|
||||
^ stringDecorator
|
||||
]
|
@ -1,74 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioPillarASTextStringDecorator,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'text'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringDecorator >> at: aNumber [
|
||||
^ text at: aNumber
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringDecorator >> at: aNumber put: aChar [
|
||||
self halt
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
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
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringDecorator >> isEmpty [
|
||||
^ text isEmpty
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringDecorator >> isWideString [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringDecorator >> notEmpty [
|
||||
^ text notEmpty
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringDecorator >> size [
|
||||
^ text size
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringDecorator >> string [
|
||||
self shouldBeImplemented.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringDecorator >> text: aGFPText [
|
||||
text := aGFPText
|
||||
]
|
@ -1,64 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioPillarASTextStringProjectionDecorator,
|
||||
#superclass : #GrafoscopioPillarASTextStringDecorator,
|
||||
#instVars : [
|
||||
'from',
|
||||
'to',
|
||||
'cached'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar'
|
||||
}
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> allRangesOfSubstring: aString [
|
||||
^ { }
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> asText [
|
||||
^ self string asText
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> at: anInteger [
|
||||
^ self cached at: anInteger
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> cached [
|
||||
^ cached ifNil: [ cached := text extractStringFrom: from to: to ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> copyFrom: one to: two [
|
||||
^ self class new
|
||||
text: text;
|
||||
from: from + one;
|
||||
to: from + two;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> from: anInteger [
|
||||
from := anInteger
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> isEmpty [
|
||||
^ from <= to
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> size [
|
||||
^ to - from
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> string [
|
||||
^ text extractStringFrom: from to: to
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarASTextStringProjectionDecorator >> to: anInteger [
|
||||
to := anInteger
|
||||
]
|
@ -1,80 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioPillarRuns,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'ast',
|
||||
'lastBranch',
|
||||
'lastAttributes',
|
||||
'visitor'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar-Style'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarRuns >> 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 ].
|
||||
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 analyzeBranch: aCollection at: anIndex.
|
||||
]
|
||||
|
||||
{ #category : #'basic api' }
|
||||
GrafoscopioPillarRuns >> isEmpty [
|
||||
^ ast isNil or: [ ast isEmpty ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarRuns >> rangeOf: aTextURL startingAt: anInteger [
|
||||
self assert: (aTextURL isKindOf: TextAction).
|
||||
|
||||
((self at: anInteger) contains: [ : a | (a isKindOf: TextAction)]) ifTrue: [
|
||||
(ast extractStringFrom: anInteger to: (ast detectAstNodeFor: anInteger ) textStop) traceCr.
|
||||
^ anInteger to: (ast detectAstNodeFor: anInteger ) textStop
|
||||
].
|
||||
^ 0 to: 0
|
||||
]
|
||||
|
||||
{ #category : #'basic api' }
|
||||
GrafoscopioPillarRuns >> reset [
|
||||
lastAttributes := nil.
|
||||
lastBranch := nil.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarRuns >> runLengthFor: anInteger [
|
||||
| node |
|
||||
anInteger > ast size
|
||||
ifTrue: [ ^ 0 ].
|
||||
node := ast detectAstNodeFor: anInteger.
|
||||
^ (node isKindOf: PRCodeblock)
|
||||
ifTrue: [ 1 ]
|
||||
ifFalse: [ node textStop - anInteger ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarRuns >> withStartStopAndValueDo: aBlockClosure [
|
||||
thisContext sender asString traceCr.
|
||||
'Should implement' traceCr.
|
||||
]
|
@ -1,104 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioPillarStyler,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'pharoStyler'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar-Style'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioPillarStyler class >> defaultStyler [
|
||||
^ self new
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioPillarStyler >> attributesForCodeBlock: aPRCodeblock at: index [
|
||||
|
||||
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))) . TextEmphasis bold}
|
||||
]
|
||||
|
||||
{ #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)} ] ifFalse: [ { } ]
|
||||
]
|
||||
|
||||
{ #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]
|
||||
]
|
@ -1,65 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioPillarTextAnnotator,
|
||||
#superclass : #PRVisitor,
|
||||
#instVars : [
|
||||
'texts',
|
||||
'formatter',
|
||||
'lastStop'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar'
|
||||
}
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
GrafoscopioPillarTextAnnotator >> formatter: aFormatter [
|
||||
formatter := aFormatter
|
||||
]
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
GrafoscopioPillarTextAnnotator >> initialize [
|
||||
super initialize.
|
||||
texts := OrderedCollection new.
|
||||
formatter := GrafoscopioTextFormatter default.
|
||||
]
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
GrafoscopioPillarTextAnnotator >> visitCodeblock: aTextObject [
|
||||
self visitText: aTextObject
|
||||
]
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
GrafoscopioPillarTextAnnotator >> visitCommentedLine: aTextObject [
|
||||
self visitText: aTextObject
|
||||
]
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
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' }
|
||||
GrafoscopioPillarTextAnnotator >> visitLineBreak: anObject [
|
||||
^ self visitText: anObject
|
||||
]
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
GrafoscopioPillarTextAnnotator >> visitRaw: aTextObject [
|
||||
self visitText: aTextObject
|
||||
]
|
||||
|
||||
{ #category : #'visiting-document' }
|
||||
GrafoscopioPillarTextAnnotator >> visitText: aTextObject [
|
||||
texts ifNotEmpty: [ texts last next: aTextObject ].
|
||||
texts add: aTextObject.
|
||||
aTextObject propertyAt: #textStart put: lastStop.
|
||||
lastStop := lastStop + aTextObject text size.
|
||||
aTextObject propertyAt: #textStop put: lastStop .
|
||||
]
|
@ -1,26 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioProject,
|
||||
#superclass : #Object,
|
||||
#instVars : [
|
||||
'document',
|
||||
'dictionary'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioProject >> document [
|
||||
^ document
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioProject >> initialize [
|
||||
super initialize.
|
||||
document := GrafoscopioRootNode new.
|
||||
dictionary := GrafoscopioRootNode new
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioProject >> name: aName [
|
||||
document name: aName
|
||||
]
|
@ -4,14 +4,14 @@ nodes.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioReplace,
|
||||
#superclass : #ComposablePresenter,
|
||||
#superclass : #ComposableModel,
|
||||
#instVars : [
|
||||
'find',
|
||||
'replace',
|
||||
'ok',
|
||||
'cancel'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
|
@ -1,68 +0,0 @@
|
||||
"
|
||||
This is a root node. It represents a document.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioRootNode,
|
||||
#superclass : #GrafoscopioAbstractNode,
|
||||
#instVars : [
|
||||
'children'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitRootNode: self.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> acceptsChildsOfClass: aClass [
|
||||
^ {GrafoscopioUnitNode} includes: aClass
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> addAtBeginningChild: aBlock ofClass: aClass [
|
||||
(self acceptsChildsOfClass: aClass)
|
||||
ifTrue: [ | child |
|
||||
child := aBlock value.
|
||||
child parent: self.
|
||||
self children addFirst: child ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> addChild: aBlock ofClass: aClass [
|
||||
(self acceptsChildsOfClass: aClass)
|
||||
ifTrue: [ | child |
|
||||
child := aBlock value.
|
||||
child parent: self.
|
||||
self children add: child ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioRootNode >> children [
|
||||
^ children
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> initialize [
|
||||
super initialize.
|
||||
children := SortedCollection new
|
||||
sortBlock: [ :a :b | a order < b order ];
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> level [
|
||||
^ 1
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> text [
|
||||
^ name
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioRootNode >> text: aText [
|
||||
name := aText
|
||||
]
|
@ -1,124 +0,0 @@
|
||||
"
|
||||
I am in charge of formatting a document in terms of text.
|
||||
Our text model does not support break lines or tabbings as text attribute, but as text content. (By example, our header needs to have a line break before and after by default. This kind of things can be done in rubbric by adding the character cr. Still, our pillar AST does not have this breakline for the header, and we do not wan to add it, since it would affect the parsing. No, what we want is to be able to format and modify the text before returning it when being displayed, composed, scanned, etc. So for doing so we add the text formatter.
|
||||
This text formatter contains a dictionary that allows the user to add as many as needed for each class.
|
||||
This class provides as extention point:
|
||||
|
||||
#formatsFor: anObject > Returning a collection of formats for the given object (the default behaviour stores it by class).
|
||||
#Redefine the specific visit methods for specific class behaviour.
|
||||
|
||||
|
||||
)
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioTextFormatter,
|
||||
#superclass : #PRVisitor,
|
||||
#instVars : [
|
||||
'formats',
|
||||
'stack'
|
||||
],
|
||||
#classInstVars : [
|
||||
'default'
|
||||
],
|
||||
#category : 'Grafoscopio-Pillar-TextFormat'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioTextFormatter class >> buildDefault [
|
||||
| new |
|
||||
new := self new.
|
||||
new registerFormat: GrafoscopioFmtDoubleLinebreak instance forClass: PRHeader.
|
||||
new registerFormat: GrafoscopioFmtAnchorOnTheLeft instance forClass: PRListItem.
|
||||
new registerFormat: GrafoscopioFmtBeginningLinebreak instance forClass: PRListItem.
|
||||
|
||||
" 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.
|
||||
new registerFormat: GrafoscopioFmtUrlAsBody instance forClass: PRMailLink.
|
||||
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRMailLink.
|
||||
new registerFormat: GrafoscopioFmtAnchorAsBody instance forClass: PRInternalLink.
|
||||
new registerFormat: GrafoscopioFmtEndingSpace instance forClass: PRInternalLink.
|
||||
^ new
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioTextFormatter class >> buildEmpty [
|
||||
| new |
|
||||
new := self new.
|
||||
|
||||
^ new
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioTextFormatter class >> default [
|
||||
^ self buildDefault
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> format: aNode [
|
||||
(self formatsFor: aNode) do: [ :f | f beInstalledIn: aNode ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> formatsFor: aNode [
|
||||
^ formats at: aNode ifAbsent: [ self formatsForClass: aNode class ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> formatsForClass: aNodeClass [
|
||||
^ formats at: aNodeClass ifAbsent: [ Array empty ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> initialize [
|
||||
super initialize .
|
||||
formats := Dictionary new.
|
||||
stack := Stack new.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> registerFormat: aFormat for: aNode [
|
||||
^ (formats at: aNode ifAbsentPut: [ OrderedCollection new ])
|
||||
add: aFormat
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> registerFormat: aFormat forClass: aNodeClass [
|
||||
^ self registerFormat: aFormat for: aNodeClass
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> visitDocument: aDocument [
|
||||
self assert: stack isEmpty.
|
||||
super visitDocument: aDocument.
|
||||
self assert: stack isEmpty
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTextFormatter >> visitDocumentGroup: aNode [
|
||||
aNode parent: (stack ifNotEmpty: [stack first] ifEmpty:[ nil ]).
|
||||
self format: aNode.
|
||||
stack push: aNode.
|
||||
super visitDocumentGroup: aNode.
|
||||
stack pop
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
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. "
|
||||
]
|
@ -4,15 +4,16 @@ Usually my content is markdown text.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioTextModel,
|
||||
#superclass : #ComposablePresenter,
|
||||
#superclass : #ComposableModel,
|
||||
#instVars : [
|
||||
'body'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GrafoscopioTextModel class >> defaultSpec [
|
||||
|
||||
^ SpecLayout composed add: #body
|
||||
]
|
||||
|
||||
@ -35,5 +36,6 @@ GrafoscopioTextModel >> content: aGrafoscopioNodeContent [
|
||||
GrafoscopioTextModel >> initializeWidgets [
|
||||
|
||||
body := self newText.
|
||||
body beForText.
|
||||
body autoAccept: true.
|
||||
]
|
||||
|
@ -1,42 +0,0 @@
|
||||
"
|
||||
This kind of a leafNodes holds plain text.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioTextNode,
|
||||
#superclass : #GrafoscopioLeafNode,
|
||||
#instVars : [
|
||||
'text'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioTextNode class >> icon [
|
||||
^ self iconNamed: #workspace
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioTextNode class >> nameForSelection [
|
||||
^ 'New text node'
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioTextNode class >> showInMenu [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioTextNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitTextNode: self.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioTextNode >> text [
|
||||
^ text
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioTextNode >> text: aString [
|
||||
text := aString
|
||||
]
|
@ -1,80 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioTreeNotebook,
|
||||
#superclass : #SpPresenterWithModel,
|
||||
#instVars : [
|
||||
'sidebar',
|
||||
'viewport',
|
||||
'model',
|
||||
'empty',
|
||||
'perspectives'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
GrafoscopioTreeNotebook class >> defaultSpec [
|
||||
^ SpBoxLayout newHorizontal
|
||||
add:
|
||||
(SpBoxLayout newVertical
|
||||
add: #empty height: self toolbarHeight;
|
||||
add: #sidebar;
|
||||
yourself)
|
||||
width: 51;
|
||||
add: #viewport;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioTreeNotebook >> basicInstallPerspective: aPerspective [
|
||||
viewport ifNotNil: [ viewport aboutToBeUninstalledFrom: self ].
|
||||
viewport := self perspectives
|
||||
at: aPerspective
|
||||
ifAbsentPut: [ self instantiate: aPerspective on: model document ].
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTreeNotebook >> createDefaultComponent [
|
||||
^ self basicInstallPerspective: GrafoscopioPerspective defaultPerspective
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTreeNotebook >> initializeWidgets [
|
||||
super initializeWidgets.
|
||||
sidebar := self sidebar.
|
||||
self createDefaultComponent.
|
||||
empty := self newLabel.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTreeNotebook >> installPerspective: aPerspective [
|
||||
self basicInstallPerspective: aPerspective .
|
||||
self modelChanged
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTreeNotebook >> modelChanged [
|
||||
viewport modelChanged.
|
||||
self needRebuild: false.
|
||||
self buildWithSpec
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTreeNotebook >> perspectives [
|
||||
^ perspectives ifNil: [ perspectives := Dictionary new ]
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioTreeNotebook >> setModelBeforeInitialization: aDomainObject [
|
||||
super setModelBeforeInitialization: aDomainObject.
|
||||
model := aDomainObject
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioTreeNotebook >> sidebar [
|
||||
| bar |
|
||||
bar := self instantiate: SpSidebar.
|
||||
GrafoscopioPerspective perspectives
|
||||
do:
|
||||
[ :p | bar addAction: [ self installPerspective: p ] icon: p icon ].
|
||||
^ bar
|
||||
]
|
@ -1,41 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioUnitNode,
|
||||
#superclass : #GrafoscopioBranchNode,
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUnitNode class >> icon [
|
||||
^ self iconNamed: #smallHierarchyBrowser
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUnitNode class >> nameForSelection [
|
||||
^ 'New unit'
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUnitNode class >> showInMenu [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioUnitNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitUnitNode: self.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioUnitNode >> acceptsChildsOfClass: aClass [
|
||||
^ aClass isLeaf or: [ aClass = self class ]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioUnitNode >> text [
|
||||
^ name
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioUnitNode >> text: aText [
|
||||
name := aText
|
||||
]
|
@ -1,97 +0,0 @@
|
||||
"
|
||||
URL Node downloads content for rendering.
|
||||
"
|
||||
Class {
|
||||
#name : #GrafoscopioUrlNode,
|
||||
#superclass : #GrafoscopioLeafNode,
|
||||
#instVars : [
|
||||
'link'
|
||||
],
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUrlNode class >> icon [
|
||||
^ self iconNamed: #remote
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUrlNode class >> nameForSelection [
|
||||
^ 'New URL Node'
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUrlNode class >> new [
|
||||
^ super new
|
||||
content;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
GrafoscopioUrlNode class >> showInMenu [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> acceptVisitor: aGrafoscopioVisitor [
|
||||
aGrafoscopioVisitor visitUrlNode: self.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> content [
|
||||
^ (self url
|
||||
ifNil: [ ' Invalid url ' ]
|
||||
ifNotNil: [ :url | self fetchContent: url ])
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> fetchContent: anUrl [
|
||||
^ (ZnEasy get: anUrl) entity contents
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> getUrl [
|
||||
| url |
|
||||
url := UIManager default
|
||||
request: 'Please insert a url '
|
||||
initialAnswer: 'http://'
|
||||
title: 'URL Node'.
|
||||
url ifNil: [ ^ nil ].
|
||||
url := url asZnUrl.
|
||||
(url host isEmptyOrNil
|
||||
or: [ url scheme isEmptyOrNil or: [ url authority isEmptyOrNil ] ])
|
||||
ifTrue: [ ^ nil ].
|
||||
^ url
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioUrlNode >> link: aZnUrl [
|
||||
link := aZnUrl
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> openIn: aNotebook [
|
||||
super openIn: aNotebook.
|
||||
aNotebook links text: (link ifNil: 'Invalid url') asString
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> shouldAskBeforeRemove [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #content }
|
||||
GrafoscopioUrlNode >> text [
|
||||
^ self content
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> text: aString [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
GrafoscopioUrlNode >> url [
|
||||
^ link ifNil: [ link := self getUrl ]
|
||||
]
|
@ -1,77 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioViewportVisitor,
|
||||
#superclass : #GrafoscopioVisitor,
|
||||
#instVars : [
|
||||
'viewport',
|
||||
'stack',
|
||||
'items',
|
||||
'presenter'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioViewportVisitor >> createViewportFor: aDocumentNode into: aPresenter [
|
||||
presenter := aPresenter.
|
||||
items := OrderedCollection new.
|
||||
aDocumentNode acceptVisitor: self.
|
||||
viewport := aPresenter viewport
|
||||
ifNil: [ aPresenter instantiate: SpComponentListPresenter ].
|
||||
viewport items: items.
|
||||
^ viewport
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioViewportVisitor >> visitCodeNode: aNode [
|
||||
| code |
|
||||
code := presenter instantiate: GrafoscopioNewCodeModel.
|
||||
code onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
|
||||
code model: aNode.
|
||||
items add: code.
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioViewportVisitor >> visitRootNode: aNode [
|
||||
| text |
|
||||
text := presenter instantiate: GrafoscopioNewTextInputModel.
|
||||
text model: aNode.
|
||||
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
|
||||
items add: text.
|
||||
super visitRootNode: aNode.
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioViewportVisitor >> visitTextNode: aNode [
|
||||
| text |
|
||||
text := presenter instantiate: GrafoscopioNewTextModel.
|
||||
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
|
||||
text model: aNode.
|
||||
items add: text.
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioViewportVisitor >> visitUnitNode: aNode [
|
||||
| text |
|
||||
text := presenter instantiate: GrafoscopioNewTextInputModel.
|
||||
text model: aNode.
|
||||
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
|
||||
items add: text.
|
||||
items add: (presenter newButton
|
||||
label: ' Add node on the beginning ';
|
||||
action: [ presenter addNewNodeAtBeginningOf: aNode ];
|
||||
yourself).
|
||||
super visitUnitNode: aNode.
|
||||
items add: (presenter newButton
|
||||
label: ' Add node on the end ';
|
||||
action: [ presenter addNewNodeAtLastOf: aNode ];
|
||||
yourself)
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioViewportVisitor >> visitUrlNode: aNode [
|
||||
| text |
|
||||
text := presenter instantiate: GrafoscopioNewTextInputModel.
|
||||
text onModifyNodeLocationDo: [ presenter informNodeHasChanged: aNode ].
|
||||
text model: aNode.
|
||||
items add: text.
|
||||
]
|
@ -1,48 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioVisitor,
|
||||
#superclass : #Object,
|
||||
#category : 'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitBranchNode: aNode [
|
||||
self visitNode: aNode.
|
||||
aNode children do: [ : c | c acceptVisitor: self ].
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitCodeNode: aNode [
|
||||
self visitNode: aNode
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitLeafNode: aNode [
|
||||
self visitNode: aNode
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitNode: aNode [
|
||||
" nothing to do here"
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitRootNode: aNode [
|
||||
self visitNode: aNode.
|
||||
aNode children do: [ : c | c acceptVisitor: self ].
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitTextNode: aNode [
|
||||
self visitNode: aNode
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitUnitNode: aNode [
|
||||
self visitNode: aNode.
|
||||
aNode children do: [ : c | c acceptVisitor: self ].
|
||||
]
|
||||
|
||||
{ #category : #visiting }
|
||||
GrafoscopioVisitor >> visitUrlNode: aNode [
|
||||
self visitNode: aNode
|
||||
]
|
@ -1,15 +0,0 @@
|
||||
Class {
|
||||
#name : #GrafoscopioZoaPediaPerspective,
|
||||
#superclass : #GrafoscopioPerspective,
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
GrafoscopioZoaPediaPerspective class >> icon [
|
||||
^ self iconNamed: #edit
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
GrafoscopioZoaPediaPerspective >> createViewport [
|
||||
^ self newLabel
|
||||
]
|
@ -4,12 +4,12 @@ I store metadata for this package. These meta data are used by other tools such
|
||||
Class {
|
||||
#name : #ManifestGrafoscopio,
|
||||
#superclass : #PackageManifest,
|
||||
#category : 'Grafoscopio'
|
||||
#category : #Grafoscopio
|
||||
}
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
ManifestGrafoscopio class >> ruleRBAssignmentInIfTrueRuleV1FalsePositive [
|
||||
^ #(#(#(#RGMethodDefinition #(#GrafoscopioTextNode #embedNodes #false)) #'2017-02-16T20:07:02.600781-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #navigateRelativePathFor: #false)) #'2017-03-28T22:30:53.541042-05:00') )
|
||||
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNode #embedNodes #false)) #'2017-02-16T20:07:02.600781-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNotebook #navigateRelativePathFor: #false)) #'2017-03-28T22:30:53.541042-05:00') )
|
||||
]
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
@ -24,7 +24,7 @@ ManifestGrafoscopio class >> ruleRBBooleanPrecedenceRuleV1FalsePositive [
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
ManifestGrafoscopio class >> ruleRBCascadedNextPutAllsRuleV1FalsePositive [
|
||||
^ #(#(#(#RGMethodDefinition #(#GrafoscopioTextNode #metadataAsYamlIn: #false)) #'2017-04-20T19:01:59.286212-05:00') )
|
||||
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNode #metadataAsYamlIn: #false)) #'2017-04-20T19:01:59.286212-05:00') )
|
||||
]
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
@ -39,12 +39,12 @@ ManifestGrafoscopio class >> ruleRBEqualsTrueRuleV1FalsePositive [
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
ManifestGrafoscopio class >> ruleRBLongMethodsRuleV1FalsePositive [
|
||||
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #topBar #false)) #'2016-12-17T18:51:33.99062-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #notebookSubMenu #false)) #'2017-02-02T11:43:53.106456-05:00') )
|
||||
^ #(#(#(#RGMethodDefinition #(#GrafoscopioNotebook #topBar #false)) #'2016-12-17T18:51:33.99062-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNotebook #notebookSubMenu #false)) #'2017-02-02T11:43:53.106456-05:00') )
|
||||
]
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
ManifestGrafoscopio class >> ruleRBSentNotImplementedRuleV1FalsePositive [
|
||||
^ #(#(#(#RGMetaclassDefinition #(#'GrafoscopioGUI class' #GfUIHelpers)) #'2015-12-23T10:38:16.706667-05:00') #(#(#RGClassDefinition #(#GfUIHelpers)) #'2016-01-06T18:53:45.844051-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNewNotebook #topBar #false)) #'2016-12-17T18:51:40.617924-05:00') )
|
||||
^ #(#(#(#RGMetaclassDefinition #(#'GrafoscopioGUI class' #GfUIHelpers)) #'2015-12-23T10:38:16.706667-05:00') #(#(#RGClassDefinition #(#GfUIHelpers)) #'2016-01-06T18:53:45.844051-05:00') #(#(#RGMethodDefinition #(#GrafoscopioNotebook #topBar #false)) #'2016-12-17T18:51:40.617924-05:00') )
|
||||
]
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
@ -59,5 +59,5 @@ ManifestGrafoscopio class >> ruleRBStringConcatenationRuleV1FalsePositive [
|
||||
|
||||
{ #category : #'code-critics' }
|
||||
ManifestGrafoscopio class >> ruleSmTMethodTestedRuleV1FalsePositive [
|
||||
^ #(#(#(#RGClassDefinition #(#GrafoscopioTextNode)) #'2017-10-31T19:59:03.294735-05:00') )
|
||||
^ #(#(#(#RGClassDefinition #(#GrafoscopioNode)) #'2017-10-31T19:59:03.294735-05:00') )
|
||||
]
|
||||
|
@ -29,7 +29,7 @@ Class {
|
||||
#classVars : [
|
||||
'Current'
|
||||
],
|
||||
#category : 'Grafoscopio-UI'
|
||||
#category : #'Grafoscopio-UI'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
|
@ -6,7 +6,7 @@ to javascript enabled web presentations.
|
||||
Class {
|
||||
#name : #MindMap,
|
||||
#superclass : #Object,
|
||||
#category : 'Grafoscopio-Model'
|
||||
#category : #'Grafoscopio-Model'
|
||||
}
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
|
@ -1,13 +0,0 @@
|
||||
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.
|
||||
]
|
@ -1,8 +0,0 @@
|
||||
Extension { #name : #PRDocumentGroup }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentGroup >> children: anArrayOfChildren [
|
||||
"Answer the children of the receiver."
|
||||
|
||||
children := anArrayOfChildren asArray
|
||||
]
|
@ -1,63 +0,0 @@
|
||||
Extension { #name : #PRDocumentItem }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> formats [
|
||||
| ancestors |
|
||||
ancestors := (self parent ifNil: [ {} ] ifNotNil: [ self parent formats ]).
|
||||
^ ancestors , (self propertyAt: #gfpFormat ifAbsent: [ Array empty ])
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> installFormat: aFormat [
|
||||
(self propertyAt: #gfpFormat ifAbsentPut: [ OrderedCollection new ]) add: aFormat.
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> isLineBreak [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> isTextOrLineBreak [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> markAsDirty [
|
||||
self parent ifNotNil: [ :p | p markAsDirty ].
|
||||
properties removeKey: #textStart ifAbsent: [ ].
|
||||
properties removeKey: #textStop ifAbsent: [ ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> parent [
|
||||
^ self propertyAt: #parent ifAbsent: [ nil ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> parent: aParent [
|
||||
self propertyAt: #parent put: aParent
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> textSize [
|
||||
^ self textStop - self textStart
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> textStart [
|
||||
^ self
|
||||
propertyAt: #textStart
|
||||
ifAbsentPut: [ self hasChildren
|
||||
ifTrue: [ self children first textStart ]
|
||||
ifFalse: [ 0 ] ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRDocumentItem >> textStop [
|
||||
^ self
|
||||
propertyAt: #textStop
|
||||
ifAbsentPut: [ self hasChildren
|
||||
ifTrue: [ self children last textStop ]
|
||||
ifFalse: [ 0 ] ]
|
||||
]
|
@ -1,70 +0,0 @@
|
||||
Extension { #name : #PRLineBreak }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> formattedText [
|
||||
^ OSPlatform current lineEnding
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> isLineBreak [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> isTextOrLineBreak [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> markAsDirty [
|
||||
self parent ifNotNil: [ :p | p markAsDirty ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> next [
|
||||
^ self propertyAt: #next ifAbsent: [ nil ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> next: aText [
|
||||
self propertyAt: #next put: aText
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> text [
|
||||
^ OSPlatform current lineEnding
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> text: aString [
|
||||
self shouldBeImplemented.
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> textSize [
|
||||
^ self text size
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> textStart [
|
||||
^ self propertyAt: #textStart
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> textStart: aValue [
|
||||
^ self
|
||||
propertyAt: #textStart
|
||||
put: aValue
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> textStop [
|
||||
^ self propertyAt: #textStop
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRLineBreak >> textStop: aValue [
|
||||
^ self
|
||||
propertyAt: #textStop
|
||||
put: aValue
|
||||
]
|
@ -1,16 +0,0 @@
|
||||
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
|
||||
]
|
@ -1,6 +0,0 @@
|
||||
Extension { #name : #PRPillarWriter }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRPillarWriter >> visitFormatText: aGrafoscopioFormatTextNode [
|
||||
" Do nothing "
|
||||
]
|
@ -1,45 +0,0 @@
|
||||
Extension { #name : #PRText }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> isTextOrLineBreak [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> markAsDirty [
|
||||
self parent ifNotNil: [ :p | p markAsDirty ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> next [
|
||||
^ self propertyAt: #next ifAbsent: [ nil ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> next: aText [
|
||||
self propertyAt: #next put: aText.
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> textStart [
|
||||
^ self propertyAt: #textStart
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> textStart: aValue [
|
||||
^ self
|
||||
propertyAt: #textStart
|
||||
put: aValue
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> textStop [
|
||||
^ self propertyAt: #textStop
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
PRText >> textStop: aValue [
|
||||
^ self
|
||||
propertyAt: #textStop
|
||||
put: aValue
|
||||
]
|
@ -1,44 +0,0 @@
|
||||
Class {
|
||||
#name : #SpSidebar,
|
||||
#superclass : #SpPresenter,
|
||||
#instVars : [
|
||||
'container'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
SpSidebar class >> defaultSpec [
|
||||
^ SpBoxLayout newHorizontal
|
||||
add: #container ;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSidebar >> addAction: aBlock icon: anIcon [
|
||||
container
|
||||
addPresenter:
|
||||
(self createDefaultPresenter
|
||||
parent: self;
|
||||
action: [ :state |
|
||||
container unselectAll.
|
||||
aBlock cull: state ];
|
||||
icon: anIcon;
|
||||
yourself)
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
SpSidebar >> buttons [
|
||||
^ container items
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSidebar >> createDefaultPresenter [
|
||||
^ self instantiate: SpSquareButton.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSidebar >> initializeWidgets [
|
||||
super initializeWidgets.
|
||||
container := self instantiate: SpComponentListPresenter.
|
||||
]
|
@ -1,52 +0,0 @@
|
||||
Class {
|
||||
#name : #SpSquareButton,
|
||||
#superclass : #SpPresenter,
|
||||
#instVars : [
|
||||
'button',
|
||||
'parent'
|
||||
],
|
||||
#category : 'Grafoscopio-New-UI'
|
||||
}
|
||||
|
||||
{ #category : #specs }
|
||||
SpSquareButton class >> defaultSpec [
|
||||
^ SpBoxLayout newVertical
|
||||
add: (SpBoxLayout newHorizontal add: #button width: 50; yourself) height: 50;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSquareButton >> action: anAction [
|
||||
button
|
||||
action: [ :state |
|
||||
state
|
||||
ifTrue: [ parent buttons
|
||||
reject: [ :b | b = self ]
|
||||
thenDo: [ :b | b toggleOff ].
|
||||
anAction cull: state ]
|
||||
ifFalse: [ ] ]
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSquareButton >> icon: icon [
|
||||
button icon: icon
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSquareButton >> initializeWidgets [
|
||||
super initializeWidgets.
|
||||
button := self newToggleButton
|
||||
extent: 90 @ 50;
|
||||
color: Color transparent;
|
||||
yourself
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
SpSquareButton >> parent: aSpSidebar [
|
||||
parent := aSpSidebar
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
SpSquareButton >> toggleOff [
|
||||
button state: false.
|
||||
]
|
@ -1,6 +0,0 @@
|
||||
Extension { #name : #Text }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
Text >> allSegmentsOfLinesDo: aBlockClosure [
|
||||
|
||||
]
|
@ -1,9 +0,0 @@
|
||||
Extension { #name : #TextPresenter }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
TextPresenter >> beForGrafoscopio [
|
||||
self
|
||||
isCodeCompletionAllowed: true;
|
||||
menuHolder: [ self getMenu ];
|
||||
isForSmalltalkCode: true
|
||||
]
|
@ -1,17 +0,0 @@
|
||||
Extension { #name : #TreePresenter }
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
TreePresenter >> selectedIndex [
|
||||
^ selectedItem value
|
||||
ifNil: [ 1 min: rootsHolder value size ]
|
||||
ifNotNil: [ rootsHolder value indexOf: selectedItem value ]
|
||||
]
|
||||
|
||||
{ #category : #'*Grafoscopio' }
|
||||
TreePresenter >> selectedIndex: anInteger [
|
||||
anInteger = 0
|
||||
ifTrue: [ self resetSelection.
|
||||
self highlightedItem: nil ]
|
||||
ifFalse: [ self selectedItem: (rootsHolder value at: anInteger).
|
||||
self highlightedItem: (rootsHolder value at: anInteger) ]
|
||||
]
|
Loading…
Reference in New Issue
Block a user