diff --git a/src/Microdown-BookTester/MicFigureCaptionChecker.class.st b/src/Microdown-BookTester/MicFigureCaptionChecker.class.st new file mode 100644 index 000000000..d68f9723d --- /dev/null +++ b/src/Microdown-BookTester/MicFigureCaptionChecker.class.st @@ -0,0 +1,109 @@ +Class { + #name : 'MicFigureCaptionChecker', + #superclass : 'MicChecker', + #instVars : [ + 'checkFigure', + 'checkCode', + 'checkMath' + ], + #category : 'Microdown-BookTester', + #package : 'Microdown-BookTester' +} + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkCaptionOf: aBlock [ + (self hasCorrectCaption: aBlock caption) ifFalse: [ + self results add: MicMissingFigureCaptionResult new ] +] + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkCode [ + + ^ checkCode +] + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkCode: anObject [ + + checkCode := anObject +] + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkFigure [ + + ^ checkFigure +] + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkFigure: anObject [ + + checkFigure := anObject +] + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkMath [ + + ^ checkMath +] + +{ #category : 'accessing' } +MicFigureCaptionChecker >> checkMath: anObject [ + + checkMath := anObject +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> checkMissingCaptionIn: aBlock text: captionText [ + (captionText isEmpty or: [ (captionText anySatisfy: #isAlphaNumeric) not ]) ifTrue: [ + self results add: (MicMissingFigureCaptionResult new + figure: aBlock; + yourself) ] +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> configureFrom: aDictionary [ + super configureFrom: aDictionary. + aDictionary at: 'checkOnly' ifPresent: [ :list | + self checkCode: false. + self checkFigure: false. + self checkMath: false. + (list includes: 'code') ifTrue: [ self checkCode: true ]. + (list includes: 'figure') ifTrue: [ self checkFigure: true ]. + (list includes: 'math') ifTrue: [ self checkMath: true ] ] +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> explanationForConfiguration [ + ^ 'I check that figures, math environments and code blocks have a valid and non-empty caption.' +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> hasCorrectCaption: aCaptionText [ + ^ aCaptionText isNotEmpty and: [ aCaptionText anySatisfy: #isAlphaNumeric ] +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> initialize [ + super initialize. + self checkCode: true. + self checkFigure: true. + self checkMath: true. +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> visitCode: aCode [ + self checkCode ifTrue: [ self checkCaptionOf: aCode ]. + ^ super visitCode: aCode +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> visitFigure: aFigure [ + self checkFigure ifTrue: [ self checkCaptionOf: aFigure ]. + ^ super visitFigure: aFigure +] + +{ #category : 'visiting - inline elements' } +MicFigureCaptionChecker >> visitMath: aMath [ + self checkMath ifTrue: [ self checkCaptionOf: aMath ]. + ^ super visitMath: aMath +] diff --git a/src/Microdown-BookTester/MicFigureCaptionCheckerTest.class.st b/src/Microdown-BookTester/MicFigureCaptionCheckerTest.class.st new file mode 100644 index 000000000..4eafee8c4 --- /dev/null +++ b/src/Microdown-BookTester/MicFigureCaptionCheckerTest.class.st @@ -0,0 +1,119 @@ +Class { + #name : 'MicFigureCaptionCheckerTest', + #superclass : 'TestCase', + #instVars : [ + 'results' + ], + #category : 'Microdown-BookTester', + #package : 'Microdown-BookTester' +} + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testCaptionIsEmpty [ + | visitor mdFile mem | + mem := FileSystem memory root. + mdFile := mem / 'test.md'. + mdFile writeStreamDo: [ :stream | stream nextPutAll: '![](/fig.png)' ]. + + visitor := MicFigureCaptionChecker new. + visitor rootDirectory: mem. + visitor checkProject: mdFile. + + self assert: visitor results size equals: 1. + self assert: visitor results first class name equals: #MicMissingFigureCaptionResult. +] + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testCaptionIsOnlyPunctuationAndSpaces [ + | visitor mdFile mem | + mem := FileSystem memory root. + mdFile := mem / 'test.md'. + mdFile writeStreamDo: [ :stream | stream nextPutAll: '![ , ; ](/fig.png)' ]. + + visitor := MicFigureCaptionChecker new. + visitor rootDirectory: mem. + visitor checkProject: mdFile. + + self assert: visitor results size equals: 1. + self assert: visitor results first class name equals: #MicMissingFigureCaptionResult. +] + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testCaptionIsOnlySpaces [ + | visitor mdFile mem | + mem := FileSystem memory root. + mdFile := mem / 'test.md'. + mdFile writeStreamDo: [ :stream | stream nextPutAll: '![ ](/fig.png)' ]. + visitor := MicFigureCaptionChecker new. + visitor rootDirectory: mem. + visitor checkProject: mdFile. + + self assert: visitor results size equals: 1. +] + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testCaptionIsValid [ + | visitor mdFile mem | + mem := FileSystem memory root. + mdFile := mem / 'test.md'. + mdFile writeStreamDo: [ :stream | stream nextPutAll: '![Une vraie légende](fig.png)' ]. + + visitor := MicFigureCaptionChecker new. + visitor rootDirectory: mem. + visitor checkProject: mdFile. + + self assert: visitor results isEmpty. +] + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testCodeBlockCaptionIsOnlySpaces [ + | visitor mdFile mem | + mem := FileSystem memory root. + mdFile := mem / 'bogusCaption.md'. + mdFile writeStreamDo: [ :stream | + stream nextPutAll: '```smalltalk&caption= '; cr. + stream nextPutAll: '1 + 1'; cr. + stream nextPutAll: '```' ]. + + visitor := MicFigureCaptionChecker new. + visitor rootDirectory: mem. + visitor checkProject: mdFile. + + self assert: visitor results size equals: 1. +] + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testConfigureFromCheckOnly [ + | checker config | + checker := MicFigureCaptionChecker new. + + self assert: checker checkCode. + self assert: checker checkFigure. + self assert: checker checkMath. + + config := Dictionary new. + config at: 'checkOnly' put: #('code' 'math'). + + checker configureFrom: config. + + self assert: checker checkCode. + self assert: checker checkMath. + self deny: checker checkFigure. +] + +{ #category : 'tests' } +MicFigureCaptionCheckerTest >> testMathBlockCaptionIsEmpty [ + | visitor mdFile mem | + mem := FileSystem memory root. + mdFile := mem / 'emptyCaption.md'. + mdFile writeStreamDo: [ :stream | + stream nextPutAll: '$$&caption='; cr. + stream nextPutAll: 'V = \frac{4}{3}\pi r^3'; cr. + stream nextPutAll: '$$' ]. + + visitor := MicFigureCaptionChecker new. + visitor rootDirectory: mem. + visitor checkProject: mdFile. + + self assert: visitor results size equals: 1. +] diff --git a/src/Microdown-BookTester/MicMissingFigureCaptionResult.class.st b/src/Microdown-BookTester/MicMissingFigureCaptionResult.class.st new file mode 100644 index 000000000..efacc897f --- /dev/null +++ b/src/Microdown-BookTester/MicMissingFigureCaptionResult.class.st @@ -0,0 +1,19 @@ +Class { + #name : 'MicMissingFigureCaptionResult', + #superclass : 'MicResult', + #instVars : [ + 'figure' + ], + #category : 'Microdown-BookTester', + #package : 'Microdown-BookTester' +} + +{ #category : 'accessing' } +MicMissingFigureCaptionResult >> figure [ + ^ figure +] + +{ #category : 'accessing' } +MicMissingFigureCaptionResult >> figure: aFigure [ + figure := aFigure +] diff --git a/src/Microdown/MicFigureBlock.class.st b/src/Microdown/MicFigureBlock.class.st index b100f286a..8dd4a8b00 100644 --- a/src/Microdown/MicFigureBlock.class.st +++ b/src/Microdown/MicFigureBlock.class.st @@ -40,6 +40,11 @@ MicFigureBlock >> altText [ ^ (self children collect: #plainText) joinUsing: ' ' ] +{ #category : 'accessing' } +MicFigureBlock >> caption [ + ^ ' ' join: (self captionElements collect: [ :each | each text ]) +] + { #category : 'visiting' } MicFigureBlock >> closeMe [