diff --git a/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st b/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st index 1dcb5502..3fe56ceb 100644 --- a/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st +++ b/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st @@ -14,25 +14,20 @@ BaselineOfMicrodown >> baseline: spec [ spec for: #common do: [ - - self xmlParserHtml: spec. + self xmlParserHtml: spec. spec package: #Microdown; package: #'Microdown-Tests' - with: [ spec requires: #( #Microdown ) ]; - + with: [ spec requires: #( #Microdown ) ]; package: #'Microdown-Pharo-Tools' - with: [ spec requires: #( #Microdown ) ]; - + with: [ spec requires: #( #Microdown ) ]; package: #'Microdown-RichTextComposer' - with: [ spec requires: #( #Microdown ) ]; + with: [ spec requires: #( #Microdown ) ]; package: #'Microdown-RichTextComposer-Tests' - with: [ spec requires: #( #'Microdown-RichTextComposer' ) ]; - + with: [ spec requires: #( #'Microdown-RichTextComposer' ) ]; package: #'Microdown-MathFlaky-Tests' - with: [ spec requires: #( #'Microdown-RichTextComposer-Tests' ) ]; - + with: [ spec requires: #( #'Microdown-RichTextComposer-Tests' ) ]; "package: #'Microdown-RichTextPresenter' with: [ spec requires: #( #Microdown ) ]; package: #'Microdown-RichTextPresenter-Tests' @@ -42,62 +37,57 @@ BaselineOfMicrodown >> baseline: spec [ with: [ spec requires: #( #Microdown #'Microdown-RichTextPresenter') ]; package: #'Microdown-DocumentBrowser-Tests' with: [ spec requires: #( #'Microdown-DocumentBrowser' ) ];" - package: #'Microdown-Transformer' - with: [ spec requires: #( #Microdown ) ]; + with: [ spec requires: #( #Microdown ) ]; package: #'Microdown-Transformer-Tests' - with: [ spec requires: #( #'Microdown-Transformer' ) ]; - + with: [ spec requires: #( #'Microdown-Transformer' ) ]; package: #'Microdown-Evaluator' - with: [ spec requires: #( #'Microdown-Transformer' ) ]; + with: [ spec requires: #( #'Microdown-Transformer' ) ]; package: #'Microdown-Evaluator-Tests' - with: [ spec requires: #( #'Microdown-Evaluator') ]; - + with: [ spec requires: #( #'Microdown-Evaluator' ) ]; package: #'Microdown-HTMLExporter' - with: [ spec requires: #( #Microdown #'Microdown-LaTeXExporter') ]; - package: #'Microdown-HTMLExporter-Tests' - with: [ spec requires: #( #'Microdown-HTMLExporter' 'Microdown-Tests' 'XMLParserHTML') ]; - + with: [ spec requires: #( #Microdown #'Microdown-LaTeXExporter' ) ]; + package: #'Microdown-HTMLExporter-Tests' with: [ + spec requires: + #( #'Microdown-HTMLExporter' 'Microdown-Tests' 'XMLParserHTML' ) ]; package: #'Microdown-LaTeXExporter' - with: [ spec requires: #( #Microdown ) ]; - package: #'Microdown-LaTeXExporter-Tests' - with: [ spec requires: #( #'Microdown-LaTeXExporter' #'Microdown-Tests') ]; - + with: [ spec requires: #( #Microdown ) ]; + package: #'Microdown-LaTeXExporter-Tests' with: [ + spec requires: #( #'Microdown-LaTeXExporter' + #'Microdown-Tests' ) ]; package: #'Microdown-BeamerExporter' - with: [ spec requires: #( #'Microdown-LaTeXExporter' ) ]; + with: [ spec requires: #( #'Microdown-LaTeXExporter' ) ]; package: #'Microdown-BeamerExporter-Tests' - with: [ spec requires: #( #'Microdown-LaTeXExporter-Tests') ]; - + with: [ spec requires: #( #'Microdown-LaTeXExporter-Tests' ) ]; package: #'Microdown-PrettyPrinter' - with: [ spec requires: #( #Microdown ) ]; - - package: #'Microdown-PrettyPrinter-Tests' - with: [ spec requires: #( #'Microdown-PrettyPrinter' #'Microdown-Tests') ]. - - + with: [ spec requires: #( #Microdown ) ]; + package: #'Microdown-ReferenceChecker' with: [ + spec requires: #( #'Microdown' ) ]; + package: #'Microdown-PrettyPrinter-Tests' with: [ + spec requires: #( #'Microdown-PrettyPrinter' + #'Microdown-Tests' ) ]. + + "I do not want group without tests for now" spec - group: 'Core' with: #('Microdown'); - group: 'Tests' with: #('Core' 'Microdown-Tests'); - group: 'RichText' with: #('Core' 'Microdown-RichTextComposer' ); - group: 'Extensions' with: #( - " + group: 'Core' with: #( 'Microdown' ); + group: 'Tests' with: #( 'Core' 'Microdown-Tests' ); + group: 'RichText' with: #( 'Core' 'Microdown-RichTextComposer' ); + group: 'Extensions' + with: #( #'Microdown-Evaluator' #'Microdown-Evaluator-Tests' #'Microdown-ReferenceChecker' + #'Microdown-PrettyPrinter' #'Microdown-PrettyPrinter-Tests' + #'Microdown-HTMLExporter' #'Microdown-HTMLExporter-Tests' + #'Microdown-LaTeXExporter' #'Microdown-LaTeXExporter-Tests' + #'Microdown-Transformer' #'Microdown-Transformer-Tests' ); + group: 'All' + with: #( 'Core' 'Tests' 'Extensions' 'Microdown-Pharo-Tools' + 'RichText' ) + " #'Microdown-RichTextPresenter' #'Microdown-RichTextPresenter-Tests' #'Microdown-DocumentBrowser' #'Microdown-DocumentBrowser-Tests' - " - #'Microdown-Evaluator' - #'Microdown-Evaluator-Tests' - #'Microdown-PrettyPrinter' - #'Microdown-PrettyPrinter-Tests' - #'Microdown-HTMLExporter' - #'Microdown-HTMLExporter-Tests' - #'Microdown-LaTeXExporter' - #'Microdown-LaTeXExporter-Tests' - #'Microdown-Transformer' - #'Microdown-Transformer-Tests'); - group: 'All' with: #('Core' 'Tests' 'Extensions' 'Microdown-Pharo-Tools' 'RichText') ] + " ] ] { #category : 'external projects' } diff --git a/src/Microdown-ParentChildrenChecker/ParentChildrenChecker.class.st b/src/Microdown-ParentChildrenChecker/ParentChildrenChecker.class.st new file mode 100644 index 00000000..63859456 --- /dev/null +++ b/src/Microdown-ParentChildrenChecker/ParentChildrenChecker.class.st @@ -0,0 +1,68 @@ +Class { + #name : 'ParentChildrenChecker', + #superclass : 'MicrodownVisitor', + #instVars : [ + 'childrenList', + 'parentsList' + ], + #category : 'Microdown-ParentChildrenChecker', + #package : 'Microdown-ParentChildrenChecker' +} + +{ #category : 'visiting main API' } +ParentChildrenChecker >> addChild: aChild [ + childrenList add: aChild . +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> addParent: aParent [ + parentsList add: aParent . +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> childrenList [ + ^ childrenList +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> childrenList: anObject [ + childrenList := anObject +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> initialize [ + super initialize. + childrenList := OrderedCollection new. + parentsList := OrderedCollection new. +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> parentsList [ + ^ parentsList +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> parentsList: anObject [ + parentsList := anObject +] + +{ #category : 'visiting main API' } +ParentChildrenChecker >> visit: anElement [ [ + "Check if the parent of the element correctly includes this element as a child" + anElement parent ifNotNil: [ + (anElement parent children includes: anElement) ifFalse: [ + "Instead of adding an error, add to parentsList" + self addParent: anElement parent + ] + ]. + + "Visit each child and check if it correctly points back to its parent" + anElement children do: [ :child | + child parent = anElement ifFalse: [ + "Instead of adding an error, add to childrenList" + self addChild: child + ]. + self visit: child + ]. +] +] diff --git a/src/Microdown-ParentChildrenChecker/ParentChildrenCheckerTest.class.st b/src/Microdown-ParentChildrenChecker/ParentChildrenCheckerTest.class.st new file mode 100644 index 00000000..4cbceef9 --- /dev/null +++ b/src/Microdown-ParentChildrenChecker/ParentChildrenCheckerTest.class.st @@ -0,0 +1,56 @@ +Class { + #name : 'ParentChildrenCheckerTest', + #superclass : 'TestCase', + #instVars : [ + 'checker' + ], + #category : 'Microdown-ParentChildrenChecker', + #package : 'Microdown-ParentChildrenChecker' +} + +{ #category : 'running' } +ParentChildrenCheckerTest >> setUp [ + checker := ParentChildrenChecker new. + +] + +{ #category : 'tests' } +ParentChildrenCheckerTest >> testAddChild [ + "Test adding a child to the childrenList." + checker addChild: #child1. + self assert: (checker childrenList size = 1). + self assert: (checker childrenList includes: #child1). + +] + +{ #category : 'tests' } +ParentChildrenCheckerTest >> testAddParent [ + "Test adding a parent to the parentsList." + checker addParent: #parent1. + self assert: (checker parentsList size = 1). + self assert: (checker parentsList includes: #parent1). +] + +{ #category : 'running' } +ParentChildrenCheckerTest >> testInitialization [ + "Test that collections are initialized properly and are empty." + self assert: checker childrenList isEmpty. + self assert: checker parentsList isEmpty. + +] + +{ #category : 'tests' } +ParentChildrenCheckerTest >> testMultipleAdds [ + "Test adding multiple different children and parents." + checker addChild: #child1. + checker addChild: #child2. + checker addParent: #parent1. + checker addParent: #parent2. + self assert: (checker childrenList size = 2). + self assert: (checker parentsList size = 2). + self assert: (checker childrenList includes: #child1). + self assert: (checker childrenList includes: #child2). + self assert: (checker parentsList includes: #parent1). + self assert: (checker parentsList includes: #parent2). + +] diff --git a/src/Microdown-ParentChildrenChecker/package.st b/src/Microdown-ParentChildrenChecker/package.st new file mode 100644 index 00000000..66cc7cd2 --- /dev/null +++ b/src/Microdown-ParentChildrenChecker/package.st @@ -0,0 +1 @@ +Package { #name : 'Microdown-ParentChildrenChecker' } diff --git a/src/Microdown-ReferenceChecker/MicReferenceChecker.class.st b/src/Microdown-ReferenceChecker/MicReferenceChecker.class.st new file mode 100644 index 00000000..c6e500e9 --- /dev/null +++ b/src/Microdown-ReferenceChecker/MicReferenceChecker.class.st @@ -0,0 +1,94 @@ +" +I'm a little tool that checks whether a document has (1) references to undeclared anchors or (2) duplicated anchors. + +For now Microdown is file agnostic so this is impossible to report in which file such duplication or reference occurs. +Once file support is introduced I should be revised to report better information to the user. +" +Class { + #name : 'MicReferenceChecker', + #superclass : 'MicrodownVisitor', + #instVars : [ + 'references', + 'anchors', + 'duplicatedAnchors' + ], + #category : 'Microdown-ReferenceChecker', + #package : 'Microdown-ReferenceChecker' +} + +{ #category : 'reporting' } +MicReferenceChecker >> duplicatedAnchors [ + + ^ duplicatedAnchors +] + +{ #category : 'visiting' } +MicReferenceChecker >> handleAnchorOf: anElement [ + + anElement hasAnchor ifTrue: [ + (anchors includes: anElement anchor) + ifTrue: [ duplicatedAnchors add: anElement anchor ] + ifFalse: [ anchors add: anElement anchor ] ] + + "Pay attention if we want to report all the occurrences of the + anchor definition we would have to count the one already included + in anchors - Imagine that you have File1/anc1 File2/anc1 and File3/anc1 + the reporting should be anc1 is File1, File2 and File3" +] + +{ #category : 'initialization' } +MicReferenceChecker >> initialize [ + + super initialize. + references := OrderedCollection new. + anchors := OrderedCollection new. + duplicatedAnchors := OrderedCollection new +] + +{ #category : 'testing' } +MicReferenceChecker >> isOk [ + + ^ duplicatedAnchors isEmpty and: [ + references allSatisfy: [ :each | anchors includes: each ] ] +] + +{ #category : 'reporting' } +MicReferenceChecker >> unknownAnchors [ + + | unk | + unk := references copy. + anchors do: [ :each | + unk remove: each ifAbsent: [ ] ]. + ^ unk +] + +{ #category : 'visiting' } +MicReferenceChecker >> visitAnchor: anAnchor [ + + (anchors includes: anAnchor label) + ifTrue: [ + duplicatedAnchors add: anAnchor label + "Pay attention if we want to report all the occurrences of the + anchor definition we would have to count the one already included + in anchors - Imagine that you have File1/anc1 File2/anc1 and File3/anc1 + the reporting should be anc1 is File1, File2 and File3" ] + ifFalse: [ anchors add: anAnchor label ] +] + +{ #category : 'visiting' } +MicReferenceChecker >> visitAnchorReference: anAnchorReference [ + + references add: anAnchorReference bodyString +] + +{ #category : 'visiting' } +MicReferenceChecker >> visitFigure: aFigure [ + + self handleAnchorOf: aFigure +] + +{ #category : 'visiting' } +MicReferenceChecker >> visitMath: aMathEnv [ + + self handleAnchorOf: aMathEnv +] diff --git a/src/Microdown-ReferenceChecker/MicReferenceCheckerTest.class.st b/src/Microdown-ReferenceChecker/MicReferenceCheckerTest.class.st new file mode 100644 index 00000000..4fe4d320 --- /dev/null +++ b/src/Microdown-ReferenceChecker/MicReferenceCheckerTest.class.st @@ -0,0 +1,169 @@ +Class { + #name : 'MicReferenceCheckerTest', + #superclass : 'TestCase', + #category : 'Microdown-ReferenceChecker', + #package : 'Microdown-ReferenceChecker' +} + +{ #category : 'tests' } +MicReferenceCheckerTest >> testAllReferencesAreCorrect [ + + | doc visitor | + doc := Microdown parse: '# Section 1 +@anchorSection1 + +See *@anchorSection1@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self assert: visitor isOk. +] + +{ #category : 'tests' } +MicReferenceCheckerTest >> testReferToAFigure [ + + | doc visitor | + doc := Microdown parse: '# Section 1 +![alittle caption.](figures/f.png anchor=anchorSection1) + +See *@anchorSection1@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self assert: visitor isOk +] + +{ #category : 'tests' } +MicReferenceCheckerTest >> testReferToAMathEquation [ + + | doc visitor | + doc := Microdown parse: '# Section 1 + +$$ %anchor=anchorSection1 +balbalbalb! +$$ +See *@anchorSection1@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self assert: visitor isOk +] + +{ #category : 'tests' } +MicReferenceCheckerTest >> testReferToAnUknownAnchor [ + + | doc visitor | + doc := Microdown parse: '# Section 1 + +See *@anchorSection1@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self deny: visitor isOk +] + +{ #category : 'tests - duplicated anchors' } +MicReferenceCheckerTest >> testReportingDuplicatedAnchors [ + + | doc visitor | + doc := Microdown parse: '# Section +@anchorSection0 + +# Section 1 +@anchorSection1 + +# Section 2 +@anchorSection1 + +# Section 3 +@anchorSection1 + +See *@anchorSection1@* and *@anchorSection0@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self deny: visitor isOk. + self assert: visitor duplicatedAnchors equals: OrderedCollection <- #('anchorSection1' 'anchorSection1') +] + +{ #category : 'tests - duplicated anchors' } +MicReferenceCheckerTest >> testReportingDuplicatedFigures [ + + | doc visitor | + doc := Microdown parse: '# Section +@anchorSection0 + +![a caption 1](figures/f.png anchor=anchorSection1) + +![a caption 2](figures/f.png anchor=anchorSection1) + +![a caption 3](figures/f.png anchor=anchorSection2) + +See *@anchorSection1@* and *@anchorSection3@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self deny: visitor isOk. + self + assert: visitor duplicatedAnchors + equals: OrderedCollection <- #( 'anchorSection1' ) +] + +{ #category : 'tests - duplicated anchors' } +MicReferenceCheckerTest >> testReportingDuplicatedMaths [ + + | doc visitor | + doc := Microdown parse: '# Section +@anchorSection0 + +$$ %anchor=anchorSection1 +balbalbalb! +$$ + +$$ %anchor=anchorSection1 +balbalbalb! +$$ + +$$ %anchor=anchorSection1 +balbalbalb! +$$ + +$$ %anchor=anchorSection3 +balbalbalb! +$$ + +See *@anchorSection1@* and *@anchorSection3@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self deny: visitor isOk. + self + assert: visitor duplicatedAnchors + equals: OrderedCollection <- #( 'anchorSection1' 'anchorSection1' ) +] + +{ #category : 'tests' } +MicReferenceCheckerTest >> testReportingUnknownAnchor [ + + | doc visitor | + doc := Microdown parse: '# Section +@anchorSection0 + +# Section 1 +@anchorSection1 + +See *@anchorSection1@* and *@anchorSection2@* + +'. + visitor := MicReferenceChecker new. + doc accept: visitor. + self deny: visitor isOk. + self assert: visitor unknownAnchors equals: (OrderedCollection <- #('anchorSection2')) +] diff --git a/src/Microdown-ReferenceChecker/package.st b/src/Microdown-ReferenceChecker/package.st new file mode 100644 index 00000000..993a8dba --- /dev/null +++ b/src/Microdown-ReferenceChecker/package.st @@ -0,0 +1 @@ +Package { #name : 'Microdown-ReferenceChecker' } diff --git a/src/Microdown-Tests/MicrodownParserTest.class.st b/src/Microdown-Tests/MicrodownParserTest.class.st index 45625ae6..a74f2e65 100644 --- a/src/Microdown-Tests/MicrodownParserTest.class.st +++ b/src/Microdown-Tests/MicrodownParserTest.class.st @@ -44,11 +44,11 @@ MicrodownParserTest >> stestMathBlockWithArguments [ { #category : 'tests - anchor' } MicrodownParserTest >> testAnchorBlock [ | source root annotated | - source := AnchorMarkup, 'label1'. + source := AnchorMarkup, 'label1' , String cr , AnchorMarkup , 'label2'. root := parser parse: source. - self assert: root children size equals: 1. - annotated := root children first. - self assert: annotated label equals: 'label1'. + self assert: root children size equals: 2. + annotated := root children at: 2. + self assert: annotated label equals: 'label2'. ] diff --git a/src/Microdown/MicAnchorBlock.class.st b/src/Microdown/MicAnchorBlock.class.st index fc68b98f..4fe06945 100644 --- a/src/Microdown/MicAnchorBlock.class.st +++ b/src/Microdown/MicAnchorBlock.class.st @@ -44,8 +44,9 @@ MicAnchorBlock >> label [ ] { #category : 'accessing' } -MicAnchorBlock >> label: anObject [ - label := anObject +MicAnchorBlock >> label: aLabel [ + label := aLabel. + ] { #category : 'accessing' } diff --git a/src/Microdown/MicrodownParser.class.st b/src/Microdown/MicrodownParser.class.st index 0ddf6918..38dbcd5f 100644 --- a/src/Microdown/MicrodownParser.class.st +++ b/src/Microdown/MicrodownParser.class.st @@ -15,7 +15,7 @@ Microdown covers Markdown basis syntax, with great Pillar's features. It's more - item a on another line - item b - - item b1 + - item b1 haaaaaaaaaa - item b2 - item c ```