diff --git a/README.md b/README.md index 43349aa6..40794b88 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,16 @@ Microdown is a smaller markdown but it is more extensible. It contains a nice bu Microdown is now the default markup for the Pillar document compilation chain. +## Instal + +```Smalltalk +Metacello new + baseline: 'Microdown'; + repository: 'github://pillar-markup/Microdown:v2.9.3/src'; + load. +``` + + ## Why should you use Microdown? Microdown is a smaller markdown but it is more extensible. @@ -163,12 +173,13 @@ The markup is not interpreted. Codeblock does not support more than four backticks. -## Development in Pharo 12! +## Development in Pharo 13! ### Loading specific version -To load the latest stable version load the master. If you have trouble loading in the latest Pharo just execute the preloading.st script in the .github folder. -This script will remove the existing Microdown package and clear the system. +To load the latest stable version load the master. If you have trouble loading in the latest Pharo just execute the preloading.st script in the .github folder. This script will remove the existing Microdown package and clear the system. +You can also execute the script provided below. + ```Smalltalk Metacello new @@ -178,8 +189,8 @@ Metacello new ``` The process is the following: -- Development in dev -- When stable dev -> in master +- Development happens dev. +- When stable dev -> in master. - When we can build books master is tagged. - Then there is the Pharo integration in dedicated branches. @@ -189,13 +200,7 @@ The process is the following: The following script loads all groups in the Baseline: ```Smalltalk -#( 'Microdown' 'BeautifulComments' 'DocumentBrowser' ) do: [ :name | - (IceRepository repositoryNamed: name) - ifNil: [ self inform: 'Project not found: ' , name ] - ifNotNil: [ :found | - found - unload; - forget ] ]. + Smalltalk globals at: #BaselineOfMicrodown @@ -207,14 +212,38 @@ Metacello new onConflict: [ :ex | ex useIncoming ]; onUpgrade: [ :ex | ex useIncoming ]; load: #('All'). - ``` +``` + +In addition you may want to execute this before. +``` +#( 'Microdown' ) do: [ :name | + (IceRepository repositoryNamed: name) + ifNil: [ self inform: 'Project not found: ' , name ] + ifNotNil: [ :found | + found + unload; + forget ] ]. +``` ## History -We have two sources: Pharo in one hand and Pillar and both are not totally synchronized. +We have two sources: +- Pharo in one hand (a minimal version managed with the pharo* branches) and +- Pillar (eg. all the tools and support for slides and books) and both are not totally synchronized. + +Now we also maintain different versions between Pharo versions. Currently the situation is the following: + +Working with Pharo 13: +- v2.9.2 a little release to support Foliage v2.1.0 and two new release of Pillar (probably one for P13 and one for P13 dropping pillar format). +- v2.9.1 provides a better integration with Pillar (the Microdown visitors were not used before even if they worked) +v2.7.x +- v2.7.2 merge pharo 13 changes / added gitbridge / OCompiler migration / cleaning syntax description / Ready for Pillar and Foliage +- v2.7.1 LatexQuoteblock-should-not-use-verbatim +- v2.7.0 Fix some errors and API/clients of the textualbuilder -Using Pharo 12: v2.5.x +Working with Pharo 12: v2.5.x +- v2.5.6 - Change html visitor and test for annotated paragraph - v2.5.5 - add support for top-level header as slide definition - v2.5.4 - add backward compatible anchor in caption + tonel V3 format - v2.5.1 - add LaTeX math with reference support for Pharo 12 and Pillar development up to v10.0.0 @@ -223,7 +252,8 @@ Using Pharo 12: v2.5.x Watch out v2.6.0 is older than v.2.5.4 -### Pillar History +### Extract of Pillar History + For Pharo 12 - v10.0.0 but with some links problems due to new inline parser using MD v2.5.0 @@ -235,7 +265,10 @@ For Pharo 10 -v8.3.2 fixed baseline and updated readme + + ## Implementation + The parser follows the design mentioned in [https://github.github.com/gfm](https://github.github.com/gfm), in particular the parsing strategy in Appendix A. In short, the strategy is that at any point in time, we might have several children of the root which are ""open"". The deepest in open in the tree is called ""current"". All the parents of the current are open. diff --git a/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st b/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st index c40c2a93..dcb65a28 100644 --- a/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st +++ b/src/BaselineOfMicrodown/BaselineOfMicrodown.class.st @@ -19,15 +19,9 @@ BaselineOfMicrodown >> baseline: spec [ xmlParserHtml: spec; mustache: spec; gitBridge: spec. - " I disable this because against all my best effort, I cannot avoid the fucking pop up to raise - even if I unload all the packages. I get the Microdown-RichTextComposer in conflict." - + spec preLoadDoIt: #'preload:package:'. - - - "I disable this because in a postload - (IceRepository repositoryNamed: 'microdown') is nil and I do not get why" - + spec postLoadDoIt: #'postload:package:'. spec @@ -43,6 +37,7 @@ BaselineOfMicrodown >> baseline: spec [ package: #'Microdown-RichTextComposer' with: [ spec requires: #( #Microdown ) ]; + package: #'Microdown-RichTextComposer-Tests' with: [ spec requires: #( #'Microdown-RichTextComposer' ) ]; @@ -65,12 +60,13 @@ BaselineOfMicrodown >> baseline: spec [ with: [ spec requires: #( #'Microdown-HTMLExporter' 'Microdown-Tests' 'XMLParserHTML') ]; package: #'Microdown-LaTeXExporter' - with: [ spec requires: #( #Microdown ) ]; + with: [ spec requires: #( #Microdown ) ]; package: #'Microdown-LaTeXExporter-Tests' with: [ spec requires: #( #'Microdown-LaTeXExporter' #'Microdown-Tests') ]; - + package: #'Microdown-BeamerExporter' with: [ spec requires: #( #'Microdown-LaTeXExporter' ) ]; + package: #'Microdown-BeamerExporter-Tests' with: [ spec requires: #( #'Microdown-LaTeXExporter-Tests') ]; @@ -93,12 +89,12 @@ BaselineOfMicrodown >> baseline: spec [ package: #'Microdown-Blog-Tests' with: [ spec requires: #( #'Microdown-Blog' 'GitBridge') ]. - "I do not want group without tests for now" spec - group: 'Core' with: #('Microdown'); + group: 'Core' with: #('Microdown' 'Microdown-Tests'); group: 'ForPharo' with: #('Microdown' #'Microdown-BrowserExtensions'); - group: 'Tests' with: #('Core' 'Microdown-Tests'); group: 'RichText' with: #('Core' 'Microdown-RichTextComposer' ); + group: 'Editor' with: #('RichText' #'Microdown-PrettyPrinter' #'Microdown-PrettyPrinter-Tests'); + group: 'LaTeX' with: #('Core' #'Microdown-LaTeXExporter' #'Microdown-LaTeXExporter-Tests'); group: 'Extensions' with: #( #'Microdown-Evaluator' #'Microdown-Evaluator-Tests' @@ -115,9 +111,15 @@ BaselineOfMicrodown >> baseline: spec [ #'Microdown-BookTester-Tests' #'Microdown-Blog' #'Microdown-Blog-Tests' - ); - group: 'All' with: #('Core' #'Microdown-BrowserExtensions' 'Tests' 'Extensions' 'Microdown-Pharo-Tools' 'RichText') ] + group: 'All' with: #('Core' #'Microdown-BrowserExtensions' 'Editor' 'LaTeX' 'Extensions' 'Microdown-Pharo-Tools' 'RichText') + ] + + + + + + ] { #category : 'baselines' } @@ -131,7 +133,7 @@ BaselineOfMicrodown >> mustache: spec [ spec baseline: 'Mustache' with: [ spec - repository: 'github://noha/mustache:v1.0/repository'; + repository: 'github://noha/mustache:v1.3/repository'; loads: #( 'Core' 'Tests' ) ] ] @@ -162,16 +164,21 @@ BaselineOfMicrodown >> preload: loader package: packageSpec [ forget ] ]" | packagesToUnload | - "If we are building the Pharo image, we do not want to unload packages." - SystemBuildInfo current isBuildFinished ifFalse: [ ^ self ]. + + self flag: 'This is necessary to not break the bootstrapping. Microdown makes a cleaning of classes and as Microdown is loaded in the image it can cause conflits.'. + self flag: 'We do not access the class SystemBuildInfo directly because it is only present in Pharo 13 but Microdown works on different Pharo versions. We can simplifly this when Pharo 13 will be the minimal supported version.'. + self class environment at: #SystemBuildInfo ifPresent: [ :info | info + current isBuildFinished ifFalse: [ ^ self ]. ]. "If it is absent it's because we are in the Pharo bootstrap" self class environment at: #IceRepository ifPresent: [ :iceRepositoryClass | - packagesToUnload := ((PackageOrganizer default packages select: [ :each | each name beginsWith: 'Microdown' ]) collect: [ :each | each name ]) reject: [ :each | - #( 'Microdown-RichTextPresenter' 'Microdown-RichTextPresenter-Tests' ) includes: each ]. + | packages | + "The same here, not direct access to PackageOrganizer because it is only for Pharo 13." + packages := self class environment allClasses collect: #package as: Set. + packagesToUnload := ((packages select: [ :each | each name beginsWith: 'Microdown' ]) collect: [ :each | each name ]) reject: [ :each | + #( 'Microdown-RichTextPresenter' 'Microdown-RichTextPresenter-Tests' ) includes: each ]. - "these two are not managed by the microdown repo but the documentation. - I should rename them in the future to avoid confusion" + "these two are not managed by the microdown repo but the documentation. We should rename them in the future to avoid confusion" packagesToUnload do: [ :each | ((iceRepositoryClass repositoryNamed: 'Microdown') packageNamed: each) unload ] ] ] diff --git a/src/Microdown-Blog-Tests/MicBridge.class.st b/src/Microdown-Blog-Tests/MicBridge.class.st index 07b6d832..eab3a43b 100644 --- a/src/Microdown-Blog-Tests/MicBridge.class.st +++ b/src/Microdown-Blog-Tests/MicBridge.class.st @@ -4,8 +4,9 @@ I am a bridge to access resources from Microdown clone Class { #name : 'MicBridge', #superclass : 'GitBridge', - #category : 'Microdown-Blog-Tests', - #package : 'Microdown-Blog-Tests' + #category : 'Microdown-Blog-Tests-Utils', + #package : 'Microdown-Blog-Tests', + #tag : 'Utils' } { #category : 'accessing' } diff --git a/src/Microdown-BookTester-Tests/MicBookTesterVisitorTest.class.st b/src/Microdown-BookTester-Tests/MicCodeBlockValitorTest.class.st similarity index 81% rename from src/Microdown-BookTester-Tests/MicBookTesterVisitorTest.class.st rename to src/Microdown-BookTester-Tests/MicCodeBlockValitorTest.class.st index 7952601d..69320294 100644 --- a/src/Microdown-BookTester-Tests/MicBookTesterVisitorTest.class.st +++ b/src/Microdown-BookTester-Tests/MicCodeBlockValitorTest.class.st @@ -1,12 +1,12 @@ Class { - #name : 'MicBookTesterVisitorTest', + #name : 'MicCodeBlockValitorTest', #superclass : 'TestCase', #category : 'Microdown-BookTester-Tests', #package : 'Microdown-BookTester-Tests' } { #category : 'utilities' } -MicBookTesterVisitorTest >> parseAndTest: docText [ +MicCodeBlockValitorTest >> parseAndTest: docText [ | doc bTester | doc := Microdown parse: docText. bTester := MicCodeBlockValidator new. @@ -15,7 +15,7 @@ MicBookTesterVisitorTest >> parseAndTest: docText [ ] { #category : 'tests - valid book tests' } -MicBookTesterVisitorTest >> testExampleCodeblock [ +MicCodeBlockValitorTest >> testExampleCodeblock [ | docText bTester | docText := '```example=true 3 + 4 @@ -27,7 +27,7 @@ MicBookTesterVisitorTest >> testExampleCodeblock [ ] { #category : 'tests - failing book tests' } -MicBookTesterVisitorTest >> testExampleCodeblockWithFailingTest [ +MicCodeBlockValitorTest >> testExampleCodeblockWithFailingTest [ | docText bTester | docText := '```example=true 3 + ''12'' @@ -40,7 +40,7 @@ MicBookTesterVisitorTest >> testExampleCodeblockWithFailingTest [ ] { #category : 'tests - failing book tests' } -MicBookTesterVisitorTest >> testExampleCodeblockWithFalseTest [ +MicCodeBlockValitorTest >> testExampleCodeblockWithFalseTest [ | docText bTester | docText := '```example=true @@ -54,7 +54,7 @@ MicBookTesterVisitorTest >> testExampleCodeblockWithFalseTest [ ] { #category : 'tests - failing book tests' } -MicBookTesterVisitorTest >> testExampleCodeblockWithNoBrakets [ +MicCodeBlockValitorTest >> testExampleCodeblockWithNoBrakets [ | docText bTester | docText := '```example=true @@ -68,7 +68,7 @@ MicBookTesterVisitorTest >> testExampleCodeblockWithNoBrakets [ ] { #category : 'tests - strange codeblock' } -MicBookTesterVisitorTest >> testExampleCodeblockWithTwoBrackets [ +MicCodeBlockValitorTest >> testExampleCodeblockWithTwoBrackets [ ">> instead of > > > should not work so there is one failed test" | docText bTester | @@ -83,7 +83,7 @@ MicBookTesterVisitorTest >> testExampleCodeblockWithTwoBrackets [ ] { #category : 'tests - strange codeblock' } -MicBookTesterVisitorTest >> testExampleEmptyCodeblockWithTwoBrackets [ +MicCodeBlockValitorTest >> testExampleEmptyCodeblockWithTwoBrackets [ | docText bTester | docText := '```example=true @@ -99,7 +99,7 @@ MicBookTesterVisitorTest >> testExampleEmptyCodeblockWithTwoBrackets [ ] { #category : 'tests - valid book tests' } -MicBookTesterVisitorTest >> testExpectedFailureForAFailure [ +MicCodeBlockValitorTest >> testExpectedFailureForAFailure [ | docText bTester | docText := '```example=true&expectedFailure=true 3 + 4 @@ -112,7 +112,7 @@ MicBookTesterVisitorTest >> testExpectedFailureForAFailure [ ] { #category : 'tests - valid book tests' } -MicBookTesterVisitorTest >> testExpectedFailureForARaisedException [ +MicCodeBlockValitorTest >> testExpectedFailureForARaisedException [ | docText bTester | docText := '```example=true&expectedFailure=true 3 + ''a'' @@ -125,7 +125,7 @@ MicBookTesterVisitorTest >> testExpectedFailureForARaisedException [ ] { #category : 'tests - valid book tests' } -MicBookTesterVisitorTest >> testExplanationIsExceptionCatchedInFailingTest [ +MicCodeBlockValitorTest >> testExplanationIsExceptionCatchedInFailingTest [ | docText bTester | docText := '```example=true 3 + ''12'' @@ -140,7 +140,7 @@ MicBookTesterVisitorTest >> testExplanationIsExceptionCatchedInFailingTest [ ] { #category : 'tests - valid book tests' } -MicBookTesterVisitorTest >> testExplanationIsTestFailedWithoutException [ +MicCodeBlockValitorTest >> testExplanationIsTestFailedWithoutException [ | docText bTester | docText := '```example=true @@ -155,7 +155,7 @@ MicBookTesterVisitorTest >> testExplanationIsTestFailedWithoutException [ ] { #category : 'tests - valid book tests' } -MicBookTesterVisitorTest >> testExplanationIsTestPassed [ +MicCodeBlockValitorTest >> testExplanationIsTestPassed [ | docText bTester | docText := '```example=true @@ -170,7 +170,7 @@ MicBookTesterVisitorTest >> testExplanationIsTestPassed [ ] { #category : 'tests - no example' } -MicBookTesterVisitorTest >> testNoExampleCodeblock [ +MicCodeBlockValitorTest >> testNoExampleCodeblock [ | docText bTester | docText := '``` 3 + 4 @@ -183,7 +183,7 @@ MicBookTesterVisitorTest >> testNoExampleCodeblock [ ] { #category : 'tests - no example' } -MicBookTesterVisitorTest >> testThreeCodeBlocksWithTwoExamples [ +MicCodeBlockValitorTest >> testThreeCodeBlocksWithTwoExamples [ | docText bTester | docText := diff --git a/src/Microdown-BookTester-Tests/MicReferenceCheckerTest.class.st b/src/Microdown-BookTester-Tests/MicReferenceCheckerTest.class.st index de434de3..915d0a8f 100644 --- a/src/Microdown-BookTester-Tests/MicReferenceCheckerTest.class.st +++ b/src/Microdown-BookTester-Tests/MicReferenceCheckerTest.class.st @@ -16,7 +16,7 @@ Class { #package : 'Microdown-BookTester-Tests' } -{ #category : 'as yet unclassified' } +{ #category : 'helpers - anchors & references' } MicReferenceCheckerTest >> anchorNames: checker [ ^ checker results diff --git a/src/Microdown-BookTester/MicAnalysisReportWriter.class.st b/src/Microdown-BookTester/MicAnalysisReportWriter.class.st index e8111e53..e98dd3aa 100644 --- a/src/Microdown-BookTester/MicAnalysisReportWriter.class.st +++ b/src/Microdown-BookTester/MicAnalysisReportWriter.class.st @@ -12,6 +12,26 @@ Class { #tag : 'Analysis' } +{ #category : 'instance creation' } +MicAnalysisReportWriter class >> reportForFolder: folderReference startingFrom: fileReference [ + + | reporter checker validator | + reporter := self new. + + checker := MicReferenceChecker new. + checker fileSystem: folderReference. + checker checkProject: fileReference. + + reporter addResults: checker results. + + validator := MicCodeBlockValidator new. + checker fileSystem: folderReference. + checker checkProject: fileReference. + + reporter addResults: validator results. + ^ reporter +] + { #category : 'adding' } MicAnalysisReportWriter >> addResults: aCollection [ diff --git a/src/Microdown-BookTester/MicBookTesterStrategy.class.st b/src/Microdown-BookTester/MicBookTesterStrategy.class.st deleted file mode 100644 index 48aa3109..00000000 --- a/src/Microdown-BookTester/MicBookTesterStrategy.class.st +++ /dev/null @@ -1,22 +0,0 @@ -Class { - #name : 'MicBookTesterStrategy', - #superclass : 'Object', - #instVars : [ - 'results' - ], - #category : 'Microdown-BookTester-Analysis', - #package : 'Microdown-BookTester', - #tag : 'Analysis' -} - -{ #category : 'hook' } -MicBookTesterStrategy class >> handleKey [ - - ^ self subclassResponsibility - -] - -{ #category : 'accessing' } -MicBookTesterStrategy >> results: aCollection [ - results := aCollection -] diff --git a/src/Microdown-BookTester/MicCodeBlockTesterStrategy.class.st b/src/Microdown-BookTester/MicCodeBlockTesterStrategy.class.st new file mode 100644 index 00000000..2f4f3011 --- /dev/null +++ b/src/Microdown-BookTester/MicCodeBlockTesterStrategy.class.st @@ -0,0 +1,37 @@ +" +I'm the root of book validation strategy. +A strategy is attached to a tag in a codeblock. + +For example, when a codeblock contains the example tag as defined below, then the CodeBlockValidator will execute the strategy associated with it (using handleKey). + +```example + +3 + 2 +>>> 5 + +``` + + +" +Class { + #name : 'MicCodeBlockTesterStrategy', + #superclass : 'Object', + #instVars : [ + 'results' + ], + #category : 'Microdown-BookTester-Analysis', + #package : 'Microdown-BookTester', + #tag : 'Analysis' +} + +{ #category : 'hook' } +MicCodeBlockTesterStrategy class >> handleKey [ + + ^ self subclassResponsibility + +] + +{ #category : 'accessing' } +MicCodeBlockTesterStrategy >> results: aCollection [ + results := aCollection +] diff --git a/src/Microdown-BookTester/MicCodeBlockValidator.class.st b/src/Microdown-BookTester/MicCodeBlockValidator.class.st index 95d98abc..8a39ae25 100644 --- a/src/Microdown-BookTester/MicCodeBlockValidator.class.st +++ b/src/Microdown-BookTester/MicCodeBlockValidator.class.st @@ -1,5 +1,12 @@ " -i visit code blocks and make sure that evaluation is correct +I visit code blocks and make sure that their 'evaluation' is correct. +I generate a list of analysis results (subclasses of `MicResult`) that then will be consumed by the `MicAnalysisReportBuilder`. +This evaluation is specified by a tag. + +- 'example' tag verifies that the code is returning the expected result. +- 'sync' verifies if the code is in sync with the one in the image. + +New code block validation can easily be added by adding subclasses to `MicCodeBlockTesterStrategy`. " Class { #name : 'MicCodeBlockValidator', @@ -7,7 +14,8 @@ Class { #instVars : [ 'strategies', 'results', - 'reportWriter' + 'reportWriter', + 'rootDirectory' ], #category : 'Microdown-BookTester-Analysis', #package : 'Microdown-BookTester', @@ -20,10 +28,23 @@ MicCodeBlockValidator class >> isAbstract [ ^ false ] +{ #category : 'main API' } +MicCodeBlockValidator >> checkProject: aFileReference [ + + | mainMic collector | + mainMic := Microdown parseFile: aFileReference. + collector := MicFileCollector new. + collector + rootDirectory: rootDirectory; + visit: mainMic. + collector visitedFiles do: [ :each | self start: each ]. + +] + { #category : 'initialization' } MicCodeBlockValidator >> collectStrategies [ - MicBookTesterStrategy allSubclasses do: [ :each | + MicCodeBlockTesterStrategy allSubclasses do: [ :each | | strat | strat := each new. strat results: results. @@ -36,6 +57,14 @@ MicCodeBlockValidator >> failedTests [ ^ results select: [ :each | each isFailed ] ] +{ #category : 'accessing' } +MicCodeBlockValidator >> fileSystem: aFileReference [ + + self deprecated: 'use rootDirectory' + transformWith: '`@receiver fileSystem: `@arg' -> '`@receiver rootDirectory: `@arg'. + self rootDirectory: aFileReference. +] + { #category : 'initialization' } MicCodeBlockValidator >> initialize [ @@ -77,6 +106,12 @@ MicCodeBlockValidator >> results: anObject [ results := anObject ] +{ #category : 'accessing' } +MicCodeBlockValidator >> rootDirectory: aFileReference [ + + rootDirectory := aFileReference +] + { #category : 'accessing' } MicCodeBlockValidator >> start: anObject [ anObject accept: self diff --git a/src/Microdown-BookTester/MicExampleTesterStrategy.class.st b/src/Microdown-BookTester/MicExampleTesterStrategy.class.st index c392bc69..a59c909c 100644 --- a/src/Microdown-BookTester/MicExampleTesterStrategy.class.st +++ b/src/Microdown-BookTester/MicExampleTesterStrategy.class.st @@ -1,6 +1,17 @@ +" +I'm responsible to validate that an example in a code block is correct. + +```example +3 + 2 +>>> 5 +``` + +The checking logic should probably be improved looking at the old book tester in old Pillar. +See [PDF explaining book tester](https://github.com/pillar-markup/BookTester/tree/main/ressources/OldBookTester) +" Class { #name : 'MicExampleTesterStrategy', - #superclass : 'MicBookTesterStrategy', + #superclass : 'MicCodeBlockTesterStrategy', #category : 'Microdown-BookTester-Analysis', #package : 'Microdown-BookTester', #tag : 'Analysis' diff --git a/src/Microdown-BookTester/MicBookTesterNullStrategy.class.st b/src/Microdown-BookTester/MicNullTesterStrategy.class.st similarity index 60% rename from src/Microdown-BookTester/MicBookTesterNullStrategy.class.st rename to src/Microdown-BookTester/MicNullTesterStrategy.class.st index 435668ce..71f78a54 100644 --- a/src/Microdown-BookTester/MicBookTesterNullStrategy.class.st +++ b/src/Microdown-BookTester/MicNullTesterStrategy.class.st @@ -2,22 +2,22 @@ When there is no tag other than none or language, does not verify the code block. " Class { - #name : 'MicBookTesterNullStrategy', - #superclass : 'MicBookTesterStrategy', + #name : 'MicNullTesterStrategy', + #superclass : 'MicCodeBlockTesterStrategy', #category : 'Microdown-BookTester-Analysis', #package : 'Microdown-BookTester', #tag : 'Analysis' } { #category : 'hook' } -MicBookTesterNullStrategy class >> handleKey [ +MicNullTesterStrategy class >> handleKey [ ^ #language ] { #category : 'main API' } -MicBookTesterNullStrategy >> verify: aMicCodeBlock [ +MicNullTesterStrategy >> verify: aMicCodeBlock [ diff --git a/src/Microdown-BookTester/MicReferenceChecker.class.st b/src/Microdown-BookTester/MicReferenceChecker.class.st index 7b88031c..178469d9 100644 --- a/src/Microdown-BookTester/MicReferenceChecker.class.st +++ b/src/Microdown-BookTester/MicReferenceChecker.class.st @@ -262,9 +262,9 @@ MicReferenceChecker >> results: anObject [ ] { #category : 'accessing' } -MicReferenceChecker >> rootDirectory: aFileReferemce [ +MicReferenceChecker >> rootDirectory: aFileReference [ - rootDirectory := aFileReferemce + rootDirectory := aFileReference ] { #category : 'internal' } diff --git a/src/Microdown-BookTester/MicSyncTesterStrategy.class.st b/src/Microdown-BookTester/MicSyncTesterStrategy.class.st index d2cc9793..5fd3233b 100644 --- a/src/Microdown-BookTester/MicSyncTesterStrategy.class.st +++ b/src/Microdown-BookTester/MicSyncTesterStrategy.class.st @@ -1,6 +1,6 @@ Class { #name : 'MicSyncTesterStrategy', - #superclass : 'MicBookTesterStrategy', + #superclass : 'MicCodeBlockTesterStrategy', #category : 'Microdown-BookTester-Analysis', #package : 'Microdown-BookTester', #tag : 'Analysis' diff --git a/src/Microdown-BrowserExtensions/Class.extension.st b/src/Microdown-BrowserExtensions/Class.extension.st index 6eb2d249..dd292093 100644 --- a/src/Microdown-BrowserExtensions/Class.extension.st +++ b/src/Microdown-BrowserExtensions/Class.extension.st @@ -53,10 +53,10 @@ Class >> documentExampleCode [ and: [ self documentExampleCodeSelector match: each selector match ] ] ifNone: [ ^ nil ]. - ^ (exampleMethod sourceCode lines + ^ ((exampleMethod sourceCode lines allButFirst "Remove method name" reject: [ :each | each trimLeft beginsWith: '<' ]) "Remove pragmas" - asStringWithCr + joinUsing: Character cr) trimmed ] diff --git a/src/Microdown-HTMLExporter-Tests/MicHTMLExporterTest.class.st b/src/Microdown-HTMLExporter-Tests/MicHTMLExporterTest.class.st index ad9cf2d4..7755fa65 100644 --- a/src/Microdown-HTMLExporter-Tests/MicHTMLExporterTest.class.st +++ b/src/Microdown-HTMLExporter-Tests/MicHTMLExporterTest.class.st @@ -38,14 +38,21 @@ MicHTMLExporterTest >> newLine: aNewLine [ newLine := aNewLine ] +{ #category : 'tests - paragraph' } +MicHTMLExporterTest >> newLines: aString [ + + ^ newLine, '
', aString, '
', newLine +] + { #category : 'utilities' } MicHTMLExporterTest >> parse: aString andCheckWeGet: aResultingString [ - | mic | - + | mic c | mic := parser parse: aString. writer visit: mic. - self assert: writer contents equals: aResultingString + c := writer contents. + self assert: c equals: aResultingString. + ^ c ] { #category : 'utilities' } @@ -58,11 +65,37 @@ MicHTMLExporterTest >> parser: aParser [ parser := aParser new ] +{ #category : 'tests - paragraph' } +MicHTMLExporterTest >> pharoPage [ + + ^ + '{ +"title" : "About Pharo", +"layout" : "index", +"publishDate" : "2025-06-01" +} + +# Pharo + +[Pharo](http://www.pharo.org) is a beautiful dynamically-typed reflective pure object-oriented language that we have been developing since 2008. +It is inspired by Smalltalk (I''m extremely grateful to Alan Kay and Dan Ingalls - they were so visionary and right). Now our vision for Pharo is to reinvent Smalltalk and produce a better system. +From that perspective, I''m used to say that Pharo is what we have and not what we want. +In essence, Pharo is the beginning of the journey and not the final goal. And you can change its future. + +You can check what companies are saying about it: [Video](https://youtu.be/6tdkKNX2g4s) + +There are many aspects I would like to see being explored either by us or by others. +If you want to explore some of the following aspects, please go and let us know. +I''m really interested in any topics that evolve Pharo into a better Pharo. + +' +] + { #category : 'tests - paragraph' } MicHTMLExporterTest >> testAccents [ - self parse: 'éà' andCheckWeGet: newLine, -'éà
' + self parse: 'éà' andCheckWeGet: (self newLines: +'éà') ] { #category : 'utilities' } @@ -100,8 +133,8 @@ MicHTMLExporterTest >> testFigure [ self parse: factory figureSample - andCheckWeGet: newLine , -'

Foo


Foo
' + self parse: factory paragraphSample andCheckWeGet: (self newLines: 'Foo') ] { #category : 'tests' } MicHTMLExporterTest >> testParagraphLongWithAccents [ - self parse: factory paragraphOnMultipleLinesSample andCheckWeGet: newLine , -'Je ne connais pas la peur, car la peur tue l''esprit. La peur est la petite mort qui conduit à l''oblitération totale. J''affonterai ma peur. Je lui permettrais de passer sur moi, au travers de moi. Et lorsqu''elle sera passée, je tournerai mon oeil interieur sur son chemin. Et là où elle sera passée, il n''y aura plus rien, rien que moi.
' + self parse: factory paragraphOnMultipleLinesSample andCheckWeGet: (self newLines: +'Je ne connais pas la peur, car la peur tue l''esprit. La peur est la petite mort qui conduit à l''oblitération totale. J''affonterai ma peur. Je lui permettrais de passer sur moi, au travers de moi. Et lorsqu''elle sera passée, je tournerai mon oeil interieur sur son chemin. Et là où elle sera passée, il n''y aura plus rien, rien que moi.') ] { #category : 'tests - formats' } MicHTMLExporterTest >> testParagraphNestedSample [ - self parse: factory paragraphNestedSample andCheckWeGet: newLine , -'this is a paragraph
' + self parse: factory paragraphNestedSample andCheckWeGet: (self newLines: +'this is a paragraph') ] { #category : 'tests - formats' } @@ -240,22 +273,33 @@ MicHTMLExporterTest >> testParagraphWithBold [ self parse: factory paragraphBoldSample - andCheckWeGet: newLine , -'this is a paragraph
' + andCheckWeGet: (self newLines: +'this is a paragraph') ] { #category : 'tests' } MicHTMLExporterTest >> testParagraphWithItalic [ - self parse: factory paragraphItalicSample andCheckWeGet: newLine , -'this is a paragraph
' + self parse: factory paragraphItalicSample andCheckWeGet: (self newLines: +'this is a paragraph') ] { #category : 'tests - formats' } MicHTMLExporterTest >> testParagraphWithMonospace [ - self parse: factory paragraphMonospaceSample andCheckWeGet: newLine , -'this is a paragraph
paragraph')
+]
+
+{ #category : 'tests - paragraph' }
+MicHTMLExporterTest >> testPharoPage [
+
+ self parse: self pharoPage andCheckWeGet: newLine, 'Pharo is a beautiful dynamically-typed reflective pure object-oriented language that we have been developing since 2008.
It is inspired by Smalltalk (I''m extremely grateful to Alan Kay and Dan Ingalls - they were so visionary and right). Now our vision for Pharo is to reinvent Smalltalk and produce a better system.
From that perspective, I''m used to say that Pharo is what we have and not what we want.
In essence, Pharo is the beginning of the journey and not the final goal. And you can change its future.
You can check what companies are saying about it: Video
', newLine, newLine, + +'There are many aspects I would like to see being explored either by us or by others.
If you want to explore some of the following aspects, please go and let us know.
I''m really interested in any topics that evolve Pharo into a better Pharo.
Foo
Pharo is cool
' , newLine + , (self wrapP: 'Pharo is cool'), newLine , 'this is a code blu blu' , newLine
]
@@ -140,7 +139,7 @@ MicHTMLVisitorTest >> testCreateAnchorWithLink [
| result |
self assert: writer contents equals: String empty.
result := writer convertMicString: '[Pharo Website](http://pharo.org target=blank&rel=bookmark)'.
- self assert: result trimBoth equals: ''.
+ self assert: result trimBoth , newLine equals: (self wrapP: 'Pharo Website').
]
{ #category : 'tests' }
@@ -154,11 +153,11 @@ MicHTMLVisitorTest >> testCreateAnnotationCompound [
this is another string'.
self
- assert: result trimBoth
+ assert: result trimBoth, newLine
equals: 'Body of annotated block' - , newLine , '
this is another string
' + , newLine , (self wrapP: 'this is another string') ] { #category : 'tests' } @@ -183,7 +182,7 @@ MicHTMLVisitorTest >> testCreateCitation [ self assert: writer contents equals: String empty. result := writer convertMicString: '{!citation|ref=Duca99a!}'. - self assert: result trimBoth equals: 'Duca99a
'. + self assert: result trimBoth, newLine equals: (self wrapP: 'Duca99a'). ] @@ -194,10 +193,106 @@ MicHTMLVisitorTest >> testCreateItalic [ self assert: writer contents equals: String empty. result := writer convertMicString: '_Text with italic_'. - self assert: result trimBoth equals: 'Text with italic
'. + self assert: result trimBoth, newLine equals: (self wrapP: 'Text with italic'). + +] + +{ #category : 'tests' } +MicHTMLVisitorTest >> testRawParagraphDivWithArgs [ + + | result source | + self assert: writer contents equals: String empty. + source := +'', +'We use the <div> tag to group two paragraphs for applying a background to the text, and to add color to this', newLine, newLine, +'', newLine, +'word', newLine, +'', newLine, +'we place it within <span> tag.', +'
', newLine, +'', newLine, +'Pay attention, that the <div> tag is a block-level element, so a line break is placed before and after it.', newLine, +'
', newLine, +'', +'We use the <div> tag to group two paragraphs for applying a background to the text, and to add color to this
', newLine, newLine, +'', newLine, +'word
', newLine, newLine, +'', newLine, +'we place it within <span> tag.
', +'', newLine, newLine, +'', newLine, +'
Pay attention, that the <div> tag is a block-level element, so a line break is placed before and after it.
', newLine, newLine, +'', newLine, +'', newLine, 'some text', newLine, '
', newLine, +'and', newLine, '', newLine, (self wrapP: 'some text'), newLine, '
', newLine, +(self wrapP: 'and'), newLine, '', aString , '
', newLine +] + { #category : 'accessing' } MicHTMLVisitorTest >> writer: aWriter [ writer := aWriter new diff --git a/src/Microdown-HTMLExporter/MicHTMLVisitor.class.st b/src/Microdown-HTMLExporter/MicHTMLVisitor.class.st index 2270094f..ad4f3066 100644 --- a/src/Microdown-HTMLExporter/MicHTMLVisitor.class.st +++ b/src/Microdown-HTMLExporter/MicHTMLVisitor.class.st @@ -93,6 +93,11 @@ MicHTMLVisitor class >> serializeToHTMLDoc: aMicrodownString withStyle: aStyleNa ] +{ #category : 'accessing' } +MicHTMLVisitor class >> writerName [ + ^ #html +] + { #category : 'initialization' } MicHTMLVisitor >> canvasClass [ @@ -159,11 +164,16 @@ MicHTMLVisitor >> crlfAsNewLine [ canvas crlfAsNewLine ] -{ #category : 'as yet unclassified' } +{ #category : 'accessing' } MicHTMLVisitor >> doNotIgnoreMetaData [ ignoresMetaData := false ] +{ #category : 'accessing' } +MicHTMLVisitor >> folderName [ + ^ #html +] + { #category : 'accessing' } MicHTMLVisitor >> ignoreMetaData [ ignoresMetaData := true @@ -185,6 +195,12 @@ MicHTMLVisitor >> lfAsNewLine [ canvas lfAsNewLine ] +{ #category : 'accessing' } +MicHTMLVisitor >> mainDocumentTemplateName [ + + ^ 'template' +] + { #category : 'visiting - list' } MicHTMLVisitor >> metaDataFromAssociations: aDictionary [ "Write the receiver's metadata from aDictionary" @@ -209,6 +225,22 @@ MicHTMLVisitor >> stream: aStream [ canvas := self canvasClass on: stream ] +{ #category : 'templating' } +MicHTMLVisitor >> templateForConfiguration: aConfiguration [ + | inputFile templateName | + configuration := aConfiguration. + inputFile := configuration inputFile. + + (configuration hasProperty: #mainDocument) + ifFalse: [ ^ configuration propertyAt: self mainDocumentTemplateName ifAbsent: [ 'main.mustache' ] ]. + + templateName := inputFile fullName + = ((configuration baseDirectory resolve: configuration mainDocument) , 'pillar') fullName + ifTrue: [ self mainDocumentTemplateName ] + ifFalse: [ self chapterTemplateName ]. + ^ configuration propertyAt: templateName +] + { #category : 'initialization' } MicHTMLVisitor >> usedNewLine [ "Return the encoded new line. Useful for tests." @@ -458,7 +490,8 @@ MicHTMLVisitor >> visitParagraph: aParagraph [ canvas newLine. canvas tag name: 'p'; - with: [ super visitParagraph: aParagraph ] + with: [ super visitParagraph: aParagraph. ]. + canvas newLine. ] { #category : 'visiting' } @@ -474,6 +507,29 @@ MicHTMLVisitor >> visitQuote: aQuote [ with: [ super visitQuote: aQuote ] ] +{ #category : 'visiting - html extensions' } +MicHTMLVisitor >> visitRaw: aParagraph [ + + canvas raw: aParagraph bodyString. + canvas newLine +] + +{ #category : 'visiting - html extensions' } +MicHTMLVisitor >> visitRawParagraph: aParagraph [ + + canvas + newLine; + raw: '<' , aParagraph label. + aParagraph hasArguments + ifTrue: [ canvas space; raw: aParagraph argumentString ]. + canvas raw: '>' . + + aParagraph children do: [ :each | each accept: self ]. + canvas + newLine; + raw: aParagraph lineStopMarkup. +] + { #category : 'visiting - inline elements' } MicHTMLVisitor >> visitStrike: aStrike [ @@ -565,6 +621,13 @@ MicHTMLVisitor >> visitUnorderedListItem: anUnorderedListItem [ ] +{ #category : 'writing' } +MicHTMLVisitor >> write: aMicElement [ + "for now for integration with Pillar." + self visit: aMicElement. + ^ self contents +] + { #category : 'visiting' } MicHTMLVisitor >> writeCounter: aCounter [ diff --git a/src/Microdown-LaTeXExporter-Tests/MicAbstractLaTexWriterTest.class.st b/src/Microdown-LaTeXExporter-Tests/MicAbstractLaTexWriterTest.class.st index 877d8809..f45bfdc8 100644 --- a/src/Microdown-LaTeXExporter-Tests/MicAbstractLaTexWriterTest.class.st +++ b/src/Microdown-LaTeXExporter-Tests/MicAbstractLaTexWriterTest.class.st @@ -76,10 +76,12 @@ MicAbstractLaTexWriterTest >> newLine: aNewLine [ { #category : 'tests - formats' } MicAbstractLaTexWriterTest >> parse: aString andCheckWeGet: aResultingString [ - | mic | + | mic c | mic := parser parse: aString. writer visit: mic. - self assert: writer contents equals: aResultingString + c := writer contents. + self assert: c equals: aResultingString. + ^ c ] { #category : 'tests - formats' } diff --git a/src/Microdown-LaTeXExporter/MicDocumentWriter.class.st b/src/Microdown-LaTeXExporter/MicDocumentWriter.class.st index e81d7d80..1a8ac12c 100644 --- a/src/Microdown-LaTeXExporter/MicDocumentWriter.class.st +++ b/src/Microdown-LaTeXExporter/MicDocumentWriter.class.st @@ -70,7 +70,19 @@ MicDocumentWriter >> visit: aMicElement [ { #category : 'writing' } MicDocumentWriter >> write: aMicElement [ - "for now for integration with Pillar." + "Pillar API. + Notice that Pillar is doing the resolution of paths before calling write: + + So there is no need to define write: to call such explicit phase + as includeFilesAndVisit: does it + + includeFilesAndVisit: ast + MicFileIncluder new expandAllInputOf: ast. + self visit: ast. + ^ self contents + + " + self visit: aMicElement. ^ self contents ] diff --git a/src/Microdown-LaTeXExporter/MicLaTeXWriter.class.st b/src/Microdown-LaTeXExporter/MicLaTeXWriter.class.st index a124a611..c953b602 100644 --- a/src/Microdown-LaTeXExporter/MicLaTeXWriter.class.st +++ b/src/Microdown-LaTeXExporter/MicLaTeXWriter.class.st @@ -85,6 +85,17 @@ MicLaTeXWriter >> getStringForAll: aCollection [ ^ visitor contents ] +{ #category : 'public api' } +MicLaTeXWriter >> includeFilesAndVisit: ast [ + "Includes all the input file and convert to LaTeX the resulting document. + Note that to be correctly included the file includer requires ast to know their fromFile. + Please use parseFile: to correctly set that information or set it manually." + + MicFileIncluder new expandAllInputOf: ast. + self visit: ast. + ^ self contents +] + { #category : 'visiting-document' } MicLaTeXWriter >> includeGraphicsFor: aFigure [ diff --git a/src/Microdown-Pharo-Tools/MicElement.extension.st b/src/Microdown-Pharo-Tools/MicElement.extension.st index 14a67581..1445312a 100644 --- a/src/Microdown-Pharo-Tools/MicElement.extension.st +++ b/src/Microdown-Pharo-Tools/MicElement.extension.st @@ -14,3 +14,18 @@ Yes microdown is cool') inspect String streamContents: [ :stream | each displayStringOn: stream ] ]; yourself ] + +{ #category : '*Microdown-Pharo-Tools' } +MicElement >> inspectionMicTree: aBuilder [ + " + (MicroDownParser parse: '# hello +Yes microdown is cool') inspect + " +
+{{{contents}}}
+
+'
+]
+
{ #category : 'helpers' }
MicTemplatedWriterTest >> createTemplateFileAt: aPath withContents: contents [
| templateFileReference |
+
templateFileReference := textDocument templateDirectory resolve: aPath.
templateFileReference parent ensureCreateDirectory.
templateFileReference writeStreamDo: [ :stream | stream nextPutAll: contents ].
@@ -47,18 +64,22 @@ MicTemplatedWriterTest >> createTemplateFileAt: aPath withContents: contents [
MicTemplatedWriterTest >> setUp [
super setUp.
+ fileSystem := FileSystem memory.
textDocument := MicTextDocumentMaker new
- baseDirectory: FileSystem memory;
+ baseDirectory: fileSystem;
yourself.
+ self addTemplateFiles.
]
-{ #category : 'tests-templatefiles' }
-MicTemplatedWriterTest >> testWriteAnchorUsesAnchorTemplate [
-
- self
- assertTemplate: 'todo.mustache'
- writesValue: 'annotated paragraph'
- forNode: (PRAnnotatedParagraph withAll: #() annotation: 'todo')
+{ #category : 'tests-setup' }
+MicTemplatedWriterTest >> testDirectory [
+
+ self flag: #comeBack.
+ "it sucks but I'm always lost in file API"
+ self
+ assert: textDocument templateDirectory printString
+ equals: 'memory:///mic'.
+ self assert: (fileSystem / 'codeBlock.mustache') exists
]
{ #category : 'tests-templatefiles' }
@@ -85,8 +106,11 @@ MicTemplatedWriterTest >> testWriteCodeBlockUsesCodeBlockTemplate [
self
assertTemplate: MicTemplatedWriter codeBlockTemplateFileName
- writesValue: 'codeBlockTemplate'
- forNode: (PRCodeblock content: '^ self')
+ writesValue: '
+
+^ self
+'
+ forNode: (MicCodeBlock new body: '^ self'; yourself)
]
{ #category : 'tests-templatefiles' }
@@ -98,24 +122,6 @@ MicTemplatedWriterTest >> testWriteCommentedLineUsesCommentedLineTemplate [
forNode: (PRCommentedLine content: 'some comment')
]
-{ #category : 'tests-templatefiles' }
-MicTemplatedWriterTest >> testWriteDataItemUsesDataItemTemplate [
-
- self
- assertTemplate: MicTemplatedWriter dataItemTemplateFileName
- writesValue: 'dataitem'
- forNode: PRDataItem new
-]
-
-{ #category : 'tests-templatefiles' }
-MicTemplatedWriterTest >> testWriteDefinitionListUsesDefinitionListTemplate [
-
- self
- assertTemplate: MicTemplatedWriter definitionListTemplateFileName
- writesValue: 'definitionList'
- forNode: PRDefinitionList new
-]
-
{ #category : 'tests-templatefiles' }
MicTemplatedWriterTest >> testWriteEmptyParagraphsUsesEmptyParagraphTemplate [
@@ -167,7 +173,7 @@ MicTemplatedWriterTest >> testWriteFigureUsesFigureTemplate [
self
assertTemplate: MicTemplatedWriter figureTemplateFileName
writesValue: 'figure'
- forNode: (PRFigure reference: 'bla.png')
+ forNode: (MicFigureBlock new reference: 'bla.png')
]
{ #category : 'tests-templatefiles' }
@@ -176,18 +182,18 @@ MicTemplatedWriterTest >> testWriteHeaderUsesHeaderTemplate [
self
assertTemplate: MicTemplatedWriter headerTemplateFileName
writesValue: 'aHeader'
- forNode: (PRHeader new
+ forNode: (MicHeaderBlock new
level: 2;
- add: (PRText content: 'foo'))
+ add: (MicTextBlock new bodyString: 'foo'; yourself))
]
{ #category : 'tests-templatefiles' }
MicTemplatedWriterTest >> testWriteHorizontalRuleUsesHorizontalRuleTemplate [
self
- assertTemplate: MicTemplatedWriter horizontalRuleTemplateFileName
+ assertTemplate: MicTemplatedWriter horizontalLineTemplateFileName
writesValue: '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='
- forNode: PRHorizontalRule new
+ forNode: MicHorizontalLineBlock new
]
{ #category : 'tests-templatefiles' }
@@ -205,16 +211,9 @@ MicTemplatedWriterTest >> testWriteItalicUsesItalicTemplate [
self
assertTemplate: MicTemplatedWriter italicTemplateFileName
writesValue: 'italicTemplate'
- forNode: (PRItalicFormat with: (PRText content: 'Bar'))
-]
-
-{ #category : 'tests-templatefiles' }
-MicTemplatedWriterTest >> testWriteLineBreakUsesLineBreakTemplate [
-
- self
- assertTemplate: MicTemplatedWriter lineBreakTemplateFileName
- writesValue: 'line break'
- forNode: PRLineBreak new
+ forNode: (MicItalicFormatBlock new
+ children: { (MicTextBlock new bodyString: 'Bar') };
+ yourself )
]
{ #category : 'tests-templatefiles' }
@@ -223,7 +222,7 @@ MicTemplatedWriterTest >> testWriteListItemUsesListItemTemplate [
self
assertTemplate: MicTemplatedWriter listItemTemplateFileName
writesValue: 'list item'
- forNode: PRListItem new
+ forNode: MicListItemBlock new
]
{ #category : 'tests-templatefiles' }
@@ -241,7 +240,7 @@ MicTemplatedWriterTest >> testWriteMonospaceUsesMonospaceTemplate [
self
assertTemplate: MicTemplatedWriter monospaceTemplateFileName
writesValue: 'monospace'
- forNode: (PRMonospaceFormat with: (PRText content: 'Bar'))
+ forNode: (MicMonospaceFormatBlock new bodyString: 'Bar')
]
{ #category : 'tests-templatefiles' }
@@ -283,7 +282,7 @@ MicTemplatedWriterTest >> testWriteOrderedListUsesOrderedListTemplate [
self
assertTemplate: MicTemplatedWriter orderedListTemplateFileName
writesValue: 'ordered list'
- forNode: PROrderedList new
+ forNode: MicOrderedListBlock new
]
{ #category : 'tests-templatefiles' }
@@ -304,15 +303,6 @@ MicTemplatedWriterTest >> testWritePreformattedUsesPreformattedTemplate [
forNode: (PRPreformatted with: (PRText content: 'Bar'))
]
-{ #category : 'tests-templatefiles' }
-MicTemplatedWriterTest >> testWriteSectionUsesSectionTemplate [
-
- self
- assertTemplate: MicTemplatedWriter sectionTemplateFileName
- writesValue: 'section'
- forNode: PRSection new
-]
-
{ #category : 'tests-templatefiles' }
MicTemplatedWriterTest >> testWriteTextInsideEnvironmentLooksUpOutsideEnvironment [
@@ -332,9 +322,9 @@ MicTemplatedWriterTest >> testWriteTextInsideEnvironmentUsesTemplateInsideEnviro
self
assertTemplatePath: (Path * 'card' / 'paragraph.mustache')
writesValue: 'Paragraph in card'
- forNode: ((PREnvironment named: 'card')
- add: (PRParagraph new
- add: (PRText content: 'Foo');
+ forNode: ((MicEnvironmentBlock named: 'card')
+ add: (MicParagraphBlock new
+ add: (MicTextBlock content: 'Foo');
yourself);
yourself)
]
diff --git a/src/Microdown-Tests/MicEnvironmentBlockTest.class.st b/src/Microdown-Tests/MicEnvironmentBlockTest.class.st
index b1058982..92ab58d7 100644
--- a/src/Microdown-Tests/MicEnvironmentBlockTest.class.st
+++ b/src/Microdown-Tests/MicEnvironmentBlockTest.class.st
@@ -294,6 +294,57 @@ environment, else we force writer to enter a new line to declare the end of
the paragraph.'.
]
+{ #category : 'tests' }
+MicEnvironmentBlockTest >> testEnvironmentWithSameNestedElementAsParent [
+ "'
+?>
+'"
+
+ | source root env environmentName |
+ environmentName := 'slide'.
+ source := EnvironmentOpeningBlockMarkup , environmentName , String cr
+ , EnvironmentOpeningBlockMarkup , environmentName
+ , String cr , EnvironmentClosingBlockMarkup , String cr
+ , EnvironmentClosingBlockMarkup , String cr.
+ root := parser parse: source.
+
+ self assert: root children size equals: 1.
+ env := root children first.
+ self assert: (env isKindOf: MicSlideBlock).
+
+ self assert: env children first class equals: MicSlideBlock
+]
+
+{ #category : 'tests' }
+MicEnvironmentBlockTest >> testEnvironmentWithSameNestedElementAsParentWithBody [
+ "'
+?>
+'"
+
+ | source root env environmentName |
+ environmentName := 'slide'.
+ source := EnvironmentOpeningBlockMarkup , environmentName , String cr,
+'- item 1
+- item 2
+
+'
+ , EnvironmentOpeningBlockMarkup , environmentName
+ , String cr , '## Here is a slide', String cr, EnvironmentClosingBlockMarkup , String cr
+ , EnvironmentClosingBlockMarkup , String cr.
+ root := parser parse: source.
+
+ self assert: root children size equals: 1.
+ env := root children first.
+ self assert: (env isKindOf: MicSlideBlock).
+
+ self assert: env children first class equals: MicUnorderedListBlock.
+ self assert: env children second class equals: MicSlideBlock.
+]
+
{ #category : 'tests - extensions' }
MicEnvironmentBlockTest >> testExtensionClassWithSpaceAndArgIsCreated [
diff --git a/src/Microdown-Tests/MicFigureBlockTest.class.st b/src/Microdown-Tests/MicFigureBlockTest.class.st
index 38b70d13..dbd8ca7d 100644
--- a/src/Microdown-Tests/MicFigureBlockTest.class.st
+++ b/src/Microdown-Tests/MicFigureBlockTest.class.st
@@ -145,6 +145,14 @@ MicFigureBlockTest >> testFigureCaptionIsReifiedWithNewFormat [
self assert: (fig arguments at: #width) equals: '666'
]
+{ #category : 'tests' }
+MicFigureBlockTest >> testFigureNoCaption [
+
+ | figure |
+ figure := MicFigureBlock new reference: 'bla.png'.
+ self shouldnt: [ figure printString ] raise: Error
+]
+
{ #category : 'tests' }
MicFigureBlockTest >> testHasArguments [
| figure |
diff --git a/src/Microdown-Tests/MicMetaDataBlockTest.class.st b/src/Microdown-Tests/MicMetaDataBlockTest.class.st
index 1fff52a8..2244e4cc 100644
--- a/src/Microdown-Tests/MicMetaDataBlockTest.class.st
+++ b/src/Microdown-Tests/MicMetaDataBlockTest.class.st
@@ -40,6 +40,21 @@ MicMetaDataBlockTest >> testAtKeyPut [
self assert: (metadata atKey: 'title') equals: 'Pilote'.
]
+{ #category : 'tests - parsing' }
+MicMetaDataBlockTest >> testAtNoKey [
+
+ | source root metadata |
+ source := '{ }'.
+ root := parser parse: source.
+ metadata := root children first.
+ self assert: metadata body size equals: 0.
+ source := '{
+ }'.
+ root := parser parse: source.
+ metadata := root children first.
+ self assert: metadata body size equals: 0.
+]
+
{ #category : 'tests' }
MicMetaDataBlockTest >> testCorrectJSONMetaDataProducesDictionary [
diff --git a/src/Microdown-Tests/MicMicrodownSnippetFactory.class.st b/src/Microdown-Tests/MicMicrodownSnippetFactory.class.st
index 17898013..6c81e734 100644
--- a/src/Microdown-Tests/MicMicrodownSnippetFactory.class.st
+++ b/src/Microdown-Tests/MicMicrodownSnippetFactory.class.st
@@ -858,6 +858,16 @@ a{{Foo}}b
'
]
+{ #category : 'rawParagraph' }
+MicMicrodownSnippetFactory >> rawParagraphSimpleDiv [
+
+ ^ '+This is a paragraph started normally with
+
+') children first. + self assert: mic class equals: MicRawParagraphBlock. + self assert: mic label equals: 'p'. + self assert: mic children first class equals: MicParagraphBlock + +] + +{ #category : 'tests' } +MicRawParagraphBlockTest >> testRawParagraphCanBeNested [ | children | children := (parser parse: '+No idea what it is :) +
') children. + self assert: children size equals: 1. + self assert: children first class equals: MicRawParagraphBlock. + self assert: children first label equals: 'p'. + +] + +{ #category : 'tests' } +MicRawParagraphBlockTest >> testRawParagraphForPNoSpace [ + | children | + children := (parser parse: 'WeDoNotLikeSpace +No idea what it is :) +
') children. + self assert: children size equals: 1. + self assert: children first class equals: MicRawParagraphBlock. + self assert: children first label equals: 'p'. + +] + +{ #category : 'tests' } +MicRawParagraphBlockTest >> testRawParagraphForPNoSpace2 [ + | children newLine | + newLine := Character cr asString. + children := (MicrodownParser new parse: '', newLine, +'We use the <div> tag to group two paragraphs for applying a background to the text, and to add color to this', newLine, +'', newLine, +'word', newLine, +'', newLine, +'we place it within <span> tag.', +'
', newLine, +'', newLine, +'Pay attention, that the <div> tag is a block-level element, so a line break is placed before and after it.', newLine, +'
', newLine, +'WeDoNotLikeSpace +No idea what it is :) +
') children. + self assert: children size equals: 1. + self assert: children first class equals: MicRawParagraphBlock. + self assert: children first label equals: 'p'. + ] { #category : 'tests' } @@ -74,6 +171,6 @@ MicRawParagraphBlockTest >> testThereIsNoValidationIfThetagStartWithAKnowHtml [ mic := (parser parse: '> hasArguments [
+ ^ argumentsString isNotEmpty
]
-{ #category : 'handle' }
-MicRawParagraphBlock >> extractFirstLineFrom: line [
- "we cannot know in advance the markup so we have to guess and store it for closing."
+{ #category : 'parse support' }
+MicRawParagraphBlock >> initialize [
- label := line allButFirst copyUpToSubstring: '>'
-
+ super initialize.
+ argumentsString := ''
]
{ #category : 'accessing' }
@@ -41,3 +72,12 @@ MicRawParagraphBlock >> lineStopMarkup [
^ '', label, '>'
]
+
+{ #category : 'printing' }
+MicRawParagraphBlock >> printOn: aStream [
+
+ super printOn: aStream.
+ aStream << '(' ;
+ << label ;
+ << ')'
+]
diff --git a/src/Microdown/MicRootBlock.class.st b/src/Microdown/MicRootBlock.class.st
index 146a8167..7d8affe2 100644
--- a/src/Microdown/MicRootBlock.class.st
+++ b/src/Microdown/MicRootBlock.class.st
@@ -4,11 +4,34 @@ I am the root of the markup tree.
Class {
#name : 'MicRootBlock',
#superclass : 'MicAbstractBlock',
+ #instVars : [
+ 'debugId'
+ ],
+ #classVars : [
+ 'DebugId'
+ ],
+ #classInstVars : [
+ 'debugId'
+ ],
#category : 'Microdown-Model',
#package : 'Microdown',
#tag : 'Model'
}
+{ #category : 'accessing' }
+MicRootBlock class >> nextDebugId [
+
+ DebugId ifNil: [ DebugId := 0].
+ DebugId := DebugId + 1.
+ ^ DebugId
+]
+
+{ #category : 'accessing' }
+MicRootBlock class >> resetDebugId [
+
+ DebugId := 0
+]
+
{ #category : 'visiting' }
MicRootBlock >> accept: aVisitor [
^ aVisitor visitRoot: self
@@ -32,6 +55,17 @@ MicRootBlock >> canConsumeLine: line [
^ true
]
+{ #category : 'debugging' }
+MicRootBlock >> debugId [
+ ^ debugId
+]
+
+{ #category : 'debugging' }
+MicRootBlock >> debugIdGenerator [
+
+ ^ self class nextDebugId
+]
+
{ #category : 'accessing' }
MicRootBlock >> fromFile [
^ self propertyAt: #file ifAbsent: [ 'fakedFile' ]
@@ -67,6 +101,13 @@ MicRootBlock >> indent [
^0
]
+{ #category : 'initialization' }
+MicRootBlock >> initialize [
+
+ super initialize.
+ debugId := self class nextDebugId.
+]
+
{ #category : 'hooks' }
MicRootBlock >> massageLine: aLine [
"In some cases an element may want to massage the line such as removing leading tab. By default we delegate to the parent because environments may contain nodes such as code block and this is this nesting that will determine what should be done with the tab. In such a case the environment should remov the tabs. Here on the root we do nothing special."
@@ -81,6 +122,15 @@ MicRootBlock >> metaDataElement [
^ children first
]
+{ #category : 'printing' }
+MicRootBlock >> printOn: aStream [
+
+ super printOn: aStream.
+ debugId ifNotNil: [
+ aStream << '[ id:'; <