commit 5d097cade4b0708744c37199c80ae3e7bd9db288 Author: Offray Luna Date: Sun Sep 12 15:30:21 2021 -0500 Starting PetitCommonMark extraction from Jan Kurs PhD thesis. diff --git a/.project b/.project new file mode 100644 index 0000000..27a16e7 --- /dev/null +++ b/.project @@ -0,0 +1,3 @@ +{ + 'srcDirectory' : 'software' +} \ No newline at end of file diff --git a/software/.properties b/software/.properties new file mode 100644 index 0000000..ad0471d --- /dev/null +++ b/software/.properties @@ -0,0 +1,3 @@ +{ + #format : #tonel +} \ No newline at end of file diff --git a/software/PetitMarkdown/CMBlockVisitor.class.st b/software/PetitMarkdown/CMBlockVisitor.class.st new file mode 100644 index 0000000..b089608 --- /dev/null +++ b/software/PetitMarkdown/CMBlockVisitor.class.st @@ -0,0 +1,48 @@ +Class { + #name : 'CMBlockVisitor', + #superclass : 'CMVisitor', + #instVars : [ + 'inlineParser' + ], + #category : 'PetitMarkdown-Visitors' +} + +{ #category : 'initialization' } +CMBlockVisitor >> initialize [ + inlineParser := PPCommonMarkInlinesParser new. +] + +{ #category : 'as yet unclassified' } +CMBlockVisitor >> visitLinkRefDef: node [ + inlineParser registerLinkRefDef: node. + ^ super visitLinkRefDef: node +] + +{ #category : 'as yet unclassified' } +CMBlockVisitor >> visitParagraph: node [ + | result text | + self assert: (node children anySatisfy: [ :e | e isLine ]). + text := Character cr join: (node children collect: [:e | e text]). + + result := inlineParser parse: (text trimRight). + ^ PPCMParagraph new + addChildren: result; + yourself +] + +{ #category : 'as yet unclassified' } +CMBlockVisitor >> visitPlainLine: node [ + | result | + self assert: node text isString. + result := inlineParser parse: node text. + ^ PPCMLine new + addChildren: result; + yourself +] + +{ #category : 'as yet unclassified' } +CMBlockVisitor >> visitPlainText: node [ + ^ PPCMText new + text: node text; + yourself +] diff --git a/software/PetitMarkdown/CMHTMLVisitor.class.st b/software/PetitMarkdown/CMHTMLVisitor.class.st new file mode 100644 index 0000000..483ba78 --- /dev/null +++ b/software/PetitMarkdown/CMHTMLVisitor.class.st @@ -0,0 +1,458 @@ +Class { + #name : 'CMHTMLVisitor', + #superclass : 'CMVisitor', + #instVars : [ + 'links', + 'shouldEscape', + 'tight', + 'shouldHtmlSpecChars' + ], + #category : 'PetitMarkdown-Visitors' +} + +{ #category : 'support' } +CMHTMLVisitor >> encodeEntities: text [ + ^ PPCommonMarkUtils instance encodeEntities: text +] + +{ #category : 'escape' } +CMHTMLVisitor >> escape: string [ + | retval regex | + self shouldEscape ifFalse: [ ^ string ]. + + retval := string. + retval := retval copyReplaceAll: '\\' with: '\'. + + "Remove backlashes, \! -> !" + regex := '\\[!#$%''()*+,-./:;=?@^_`{|}~]' asRegex. + retval := regex copy: retval translatingMatchesUsing: [ :match | match second asString ]. + + retval := retval copyReplaceAll: '\[' with: '['. + retval := retval copyReplaceAll: '\]' with: ']'. + retval := retval copyReplaceAll: '\\' with: '\'. + + ^ retval +] + +{ #category : 'escape' } +CMHTMLVisitor >> forbidEscape [ + shouldEscape push: false +] + +{ #category : 'support' } +CMHTMLVisitor >> forbidHtmlSpecChars [ + shouldHtmlSpecChars push: false +] + +{ #category : 'initialization' } +CMHTMLVisitor >> initialize [ + super initialize. + links := IdentityDictionary new. + shouldEscape := Stack with: true. + shouldHtmlSpecChars := Stack with: true. +] + +{ #category : 'string operations' } +CMHTMLVisitor >> removeLeadingEmptyLines: collection [ + | retval | + collection isEmpty ifTrue: [ ^ collection ]. + + retval := collection copy. + [retval first text = ''] whileTrue: [ + retval removeFirst + ]. + + ^ retval +] + +{ #category : 'string operations' } +CMHTMLVisitor >> removeTrailingEmptyLines: collection [ + | retval | + collection isEmpty ifTrue: [ ^ collection ]. + + retval := collection copy. + [retval last text = ''] whileTrue: [ + retval removeLast + ]. + + ^ retval +] + +{ #category : 'escape' } +CMHTMLVisitor >> restoreEscape [ + shouldEscape pop +] + +{ #category : 'string operations' } +CMHTMLVisitor >> restoreHtmlSpecChars [ + shouldHtmlSpecChars pop +] + +{ #category : 'escape' } +CMHTMLVisitor >> shouldEscape [ + ^ shouldEscape top +] + +{ #category : 'support' } +CMHTMLVisitor >> shouldHtmlSpecChars [ + ^ shouldHtmlSpecChars top +] + +{ #category : 'string operations' } +CMHTMLVisitor >> trimLeadingEmptyLines: string [ + | retval | + retval := string. + + [retval beginsWith: String cr] whileTrue: [ + retval := retval copyFrom: 2 to: retval size. + ]. + + ^ retval +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitBlockQuote: node [ + | stream content | + stream := WriteStream on: ''. + stream nextPut: Character cr. + stream nextPutAll: '
'. + + content := node child accept: self. + content := content trimRight. + + stream nextPutAll: content. + stream nextPut: Character cr. + stream nextPutAll: '
'. + ^ stream contents. +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitContainer: node [ + | parts concat | + parts := node children collect: [ :child | + child accept: self + ]. + + concat := (parts reject: [ :e | e = '' ]) inject: '' into: [ :string :e | string, e ]. + ^ concat + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitDelegate: node [ + | parts | + parts := node children collect: [ :child | + child accept: self + ]. + + ^ String cr join: parts + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitDocument: node [ + ^ self trimLeadingEmptyLines: (self visitContainer: node) + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitEmphasize: node [ + | retval | + retval:= WriteStream on: ''. + + retval nextPutAll: ''. + node children do: [ :child | + retval nextPutAll: (child accept: self) + ]. + + retval nextPutAll: ''. + ^ retval contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitFencedCode: node [ + | stream | + stream := WriteStream on: ''. + + stream nextPut: Character cr. + stream nextPutAll: '
.
+
+	self forbidEscape.
+	(node children) do: [ :child |
+		stream nextPutAll: (child accept: self).
+		stream nextPut:  Character cr.
+	].
+	self restoreEscape.
+
+	stream nextPutAll: '
'. + ^ stream contents. +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitHRule: node [ + ^ String cr, '
' +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitHardBreak: node [ + ^ '
' + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitHeader: node [ + ^ String cr, '', + (node title accept: self) trim, + '' +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitHtml: node [ + ^ node text + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitHtmlBlock: node [ + | parts | + self forbidEscape. + self forbidHtmlSpecChars. + parts := node children collect: [ :child | + child accept: self + ]. + self restoreHtmlSpecChars. + self restoreEscape. + +" ^ String cr join: parts " + ^ parts inject: '' into: [ :string :e | string, String cr, e ] + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitIndentedCode: node [ + | stream | + stream := WriteStream on: ''. + + stream nextPut: Character cr. + stream nextPutAll: '
'.
+
+	self forbidEscape.
+	(self removeTrailingEmptyLines: (self removeLeadingEmptyLines: node children)) do: [ :child |
+		stream nextPutAll: (child accept: self).
+		stream nextPut:  Character cr.
+	].
+	self restoreEscape.
+
+	stream nextPutAll: '
'. + ^ stream contents. +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitInlinedCode: node [ + | code code2 | + code := node code. + + code := code copyReplaceAll: (String cr) with: (String space). + code := code. + + code2 := code. + [ + code := code2. + code2 := code copyReplaceAll: ' ' with: ' ' + ] doWhileFalse: [ code2 = code ]. + + ^ '', code trim , '' +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitLine: node [ + | stream | + stream := WriteStream on: ''. + + node children do: [ :child | + stream nextPutAll: (child accept: self). + ]. + ^ stream contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitLink: node [ + | stream | + stream := WriteStream on: ''. + stream nextPutAll: ''. + stream nextPutAll: (node label accept: self). + stream nextPutAll: ''. + + ^ stream contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitLinkRef: node [ + | stream ref | + stream := WriteStream on: ''. + + ref := links at: node label text asLowercase asSymbol. + + stream nextPutAll: ''. + stream nextPutAll: (self escape: node label text). + stream nextPutAll: ''. + + ^ stream contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitLinkRefDef: node [ + links at: node label text asLowercase asSymbol ifAbsentPut: node. + ^ '' + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitLinkRefDefPlaceholder: node [ + ^ '' + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitList: node [ + | stream tag tmp start | + stream := WriteStream on: ''. + + tmp := tight. + tight := node isTight. + start := ''. + + (node type = #ordered) ifTrue: [ + tag := 'ol'. + (node start = 1) ifFalse: [ start := ' start="', node start asString, '"' ] + ] ifFalse: [ + tag := 'ul' + ]. + + stream nextPut: Character cr. + stream nextPut: $<. + stream nextPutAll: tag. + stream nextPutAll: start. + stream nextPut: $>. + + node children do: [ :child | + child isBlankLine ifFalse: [ + stream nextPutAll: (child accept: self). + ] + ]. + + stream nextPut: Character cr. + stream nextPutAll: '. + + tight := tmp. + ^ stream contents + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitListItem: node [ + | stream nodeChildren | + stream := WriteStream on: ''. + nodeChildren := node child children reject: [:e | e isBlankLine ]. + + stream nextPut: Character cr. + stream nextPutAll: '
  • '. + nodeChildren do: [ :child | + (child isParagraph and: [ tight ]) ifTrue: [ + child children do: [ :ch | stream nextPutAll: (ch accept: self) ] + ] ifFalse: [ + stream nextPutAll: (child accept: self). + ] + ]. + (nodeChildren isEmpty or: + [nodeChildren last isParagraph and: [tight]]) ifFalse: [ + stream nextPut: Character cr + ]. + stream nextPutAll: '
  • '. + + ^ stream contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitNode: node [ + ^ '' + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitParagraph: node [ + | stream | + stream := WriteStream on: ''. + stream nextPut: Character cr. + stream nextPutAll: '

    '. + node children do: [ :child | + stream nextPutAll: (child accept: self) + ]. + stream nextPutAll: '

    '. + + ^ stream contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitPlainLine: node [ + ^ self error: 'should not happen' + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitPlainText: node [ + ^ self error: 'should not happen' + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitSoftBreak: node [ + ^ String cr + +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitStrong: node [ + | retval | + retval:= WriteStream on: ''. + + retval nextPutAll: ''. + node children do: [ :child | + retval nextPutAll: (child accept: self) + ]. + + retval nextPutAll: ''. + ^ retval contents +] + +{ #category : 'visiting' } +CMHTMLVisitor >> visitText: node [ + ^ node text + +] diff --git a/software/PetitMarkdown/CMVisitor.class.st b/software/PetitMarkdown/CMVisitor.class.st new file mode 100644 index 0000000..7404114 --- /dev/null +++ b/software/PetitMarkdown/CMVisitor.class.st @@ -0,0 +1,99 @@ +Class { + #name : 'CMVisitor', + #superclass : 'Object', + #category : 'PetitMarkdown-Visitors' +} + +{ #category : 'as yet unclassified' } +CMVisitor >> visitBlockQuote: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitContainer: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitDocument: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitFencedCode: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitHRule: node [ + ^ node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitHeader: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitHtml: node [ + ^ node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitHtmlBlock: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitIndentedCode: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitLine: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitLinkRefDef: node [ + ^ node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitLinkRefDefPlaceholder: node [ + ^ node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitList: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitListItem: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitNode: node [ + ^ node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitParagraph: node [ + ^ self visitWhatever: node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitText: node [ + ^ node +] + +{ #category : 'as yet unclassified' } +CMVisitor >> visitWhatever: node [ + node children do: [ :child | + node replace: child + with: (child accept: self) + ]. + ^ node +] diff --git a/software/PetitMarkdown/PPCMBlockQuote.class.st b/software/PetitMarkdown/PPCMBlockQuote.class.st new file mode 100644 index 0000000..8475958 --- /dev/null +++ b/software/PetitMarkdown/PPCMBlockQuote.class.st @@ -0,0 +1,25 @@ +Class { + #name : 'PPCMBlockQuote', + #superclass : 'PPCMDelegateNode', + #instVars : [ + 'code', + 'infoString' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMBlockQuote >> accept: visitor [ + ^ visitor visitBlockQuote: self +] + +{ #category : 'visiting' } +PPCMBlockQuote >> initialize [ + super initialize. + children := Array new: 1. +] + +{ #category : 'testing' } +PPCMBlockQuote >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMContainer.class.st b/software/PetitMarkdown/PPCMContainer.class.st new file mode 100644 index 0000000..0ef4765 --- /dev/null +++ b/software/PetitMarkdown/PPCMContainer.class.st @@ -0,0 +1,10 @@ +Class { + #name : 'PPCMContainer', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMContainer >> accept: visitor [ + ^ visitor visitContainer: self +] diff --git a/software/PetitMarkdown/PPCMDelegateNode.class.st b/software/PetitMarkdown/PPCMDelegateNode.class.st new file mode 100644 index 0000000..b06e632 --- /dev/null +++ b/software/PetitMarkdown/PPCMDelegateNode.class.st @@ -0,0 +1,92 @@ +Class { + #name : 'PPCMDelegateNode', + #superclass : 'PPCMNode', + #instVars : [ + 'children' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMDelegateNode >> accept: visitor [ + ^ visitor visitDelegate: self +] + +{ #category : 'accessing' } +PPCMDelegateNode >> addChild: node [ + self assert: node isCommonMarkNode. + + self children add: node. +] + +{ #category : 'accessing' } +PPCMDelegateNode >> addChildFirst: node [ + self assert: node isCommonMarkNode. + + self children addFirst: node. +] + +{ #category : 'accessing' } +PPCMDelegateNode >> addChildren: nodes [ + nodes do: [ :node | self addChild: node ] +] + +{ #category : 'enumerating' } +PPCMDelegateNode >> allChildren [ + | retval | + retval := OrderedCollection new. + self children do: [ :child | retval addAll: child allChildren ]. + ^ retval +] + +{ #category : 'accessing' } +PPCMDelegateNode >> child [ + self assert: children size = 1. + ^ children first +] + +{ #category : 'accessing' } +PPCMDelegateNode >> child: whatever [ + children at: 1 put: whatever +] + +{ #category : 'accessing' } +PPCMDelegateNode >> children [ + ^ children +] + +{ #category : 'accessing' } +PPCMDelegateNode >> children: whatever [ + children := whatever +] + +{ #category : 'accessing' } +PPCMDelegateNode >> firstChild [ + ^ children at: 1 +] + +{ #category : 'initialization' } +PPCMDelegateNode >> initialize [ + children := OrderedCollection new +] + +{ #category : 'replacing' } +PPCMDelegateNode >> replace: child with: anotherChild [ + children doWithIndex: [ :ch :index | + (ch == child) ifTrue: [ + children at: index put: anotherChild . + ^ true + ] + ]. + ^ false +] + +{ #category : 'accessing' } +PPCMDelegateNode >> secondChild [ + ^ children at: 2 +] + +{ #category : 'accessing' } +PPCMDelegateNode >> thirdChild [ + ^ children at: 3 +] diff --git a/software/PetitMarkdown/PPCMDocument.class.st b/software/PetitMarkdown/PPCMDocument.class.st new file mode 100644 index 0000000..1e15695 --- /dev/null +++ b/software/PetitMarkdown/PPCMDocument.class.st @@ -0,0 +1,15 @@ +Class { + #name : 'PPCMDocument', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMDocument >> accept: visitor [ + ^ visitor visitDocument: self +] + +{ #category : 'testing' } +PPCMDocument >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMEmphasize.class.st b/software/PetitMarkdown/PPCMEmphasize.class.st new file mode 100644 index 0000000..b58ee89 --- /dev/null +++ b/software/PetitMarkdown/PPCMEmphasize.class.st @@ -0,0 +1,10 @@ +Class { + #name : 'PPCMEmphasize', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMEmphasize >> accept: visitor [ + ^ visitor visitEmphasize: self +] diff --git a/software/PetitMarkdown/PPCMFencedCode.class.st b/software/PetitMarkdown/PPCMFencedCode.class.st new file mode 100644 index 0000000..4423f27 --- /dev/null +++ b/software/PetitMarkdown/PPCMFencedCode.class.st @@ -0,0 +1,34 @@ +Class { + #name : 'PPCMFencedCode', + #superclass : 'PPCMDelegateNode', + #instVars : [ + 'infoString' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMFencedCode >> accept: visitor [ + ^ visitor visitFencedCode: self +] + +{ #category : 'accessing' } +PPCMFencedCode >> code [ + "hackity hack, this should not be used except for tests..." + ^ String cr join: (self children collect: [ :e | e text ]) +] + +{ #category : 'accessing' } +PPCMFencedCode >> infoString [ + ^ infoString +] + +{ #category : 'accessing' } +PPCMFencedCode >> infoString: anObject [ + infoString := anObject +] + +{ #category : 'testing' } +PPCMFencedCode >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMHardBreak.class.st b/software/PetitMarkdown/PPCMHardBreak.class.st new file mode 100644 index 0000000..b269379 --- /dev/null +++ b/software/PetitMarkdown/PPCMHardBreak.class.st @@ -0,0 +1,10 @@ +Class { + #name : 'PPCMHardBreak', + #superclass : 'PPCMNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMHardBreak >> accept: visitor [ + ^ visitor visitHardBreak: self +] diff --git a/software/PetitMarkdown/PPCMHeader.class.st b/software/PetitMarkdown/PPCMHeader.class.st new file mode 100644 index 0000000..21fd3a4 --- /dev/null +++ b/software/PetitMarkdown/PPCMHeader.class.st @@ -0,0 +1,45 @@ +Class { + #name : 'PPCMHeader', + #superclass : 'PPCMDelegateNode', + #instVars : [ + 'level', + 'title' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMHeader >> accept: visitor [ + ^ visitor visitHeader: self +] + +{ #category : 'initialization' } +PPCMHeader >> initialize [ + super initialize. + children := Array new: 1. +] + +{ #category : 'accessing' } +PPCMHeader >> isBlockLevel [ + ^ true +] + +{ #category : 'accessing' } +PPCMHeader >> level [ + ^ level +] + +{ #category : 'accessing' } +PPCMHeader >> level: anObject [ + level := anObject +] + +{ #category : 'accessing' } +PPCMHeader >> title [ + ^ self child +] + +{ #category : 'accessing' } +PPCMHeader >> title: anObject [ + self children at: 1 put: anObject +] diff --git a/software/PetitMarkdown/PPCMHrule.class.st b/software/PetitMarkdown/PPCMHrule.class.st new file mode 100644 index 0000000..c79359e --- /dev/null +++ b/software/PetitMarkdown/PPCMHrule.class.st @@ -0,0 +1,23 @@ +Class { + #name : 'PPCMHrule', + #superclass : 'PPCMNode', + #instVars : [ + 'rule' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMHrule >> accept: visitor [ + ^ visitor visitHRule: self +] + +{ #category : 'accessing' } +PPCMHrule >> rule [ + ^ rule +] + +{ #category : 'accessing' } +PPCMHrule >> rule: anObject [ + rule := anObject +] diff --git a/software/PetitMarkdown/PPCMHtml.class.st b/software/PetitMarkdown/PPCMHtml.class.st new file mode 100644 index 0000000..6b349fb --- /dev/null +++ b/software/PetitMarkdown/PPCMHtml.class.st @@ -0,0 +1,23 @@ +Class { + #name : 'PPCMHtml', + #superclass : 'PPCMNode', + #instVars : [ + 'text' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMHtml >> accept: visitor [ + ^ visitor visitHtml: self +] + +{ #category : 'accessing' } +PPCMHtml >> text [ + ^ text +] + +{ #category : 'accessing' } +PPCMHtml >> text: anObject [ + text := anObject +] diff --git a/software/PetitMarkdown/PPCMHtmlBlock.class.st b/software/PetitMarkdown/PPCMHtmlBlock.class.st new file mode 100644 index 0000000..38bb80a --- /dev/null +++ b/software/PetitMarkdown/PPCMHtmlBlock.class.st @@ -0,0 +1,15 @@ +Class { + #name : 'PPCMHtmlBlock', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMHtmlBlock >> accept: visitor [ + ^ visitor visitHtmlBlock: self +] + +{ #category : 'as yet unclassified' } +PPCMHtmlBlock >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMIndentedCode.class.st b/software/PetitMarkdown/PPCMIndentedCode.class.st new file mode 100644 index 0000000..3f6b5e0 --- /dev/null +++ b/software/PetitMarkdown/PPCMIndentedCode.class.st @@ -0,0 +1,20 @@ +Class { + #name : 'PPCMIndentedCode', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMIndentedCode >> accept: visitor [ + ^ visitor visitIndentedCode: self +] + +{ #category : 'as yet unclassified' } +PPCMIndentedCode >> code [ + ^ self text +] + +{ #category : 'as yet unclassified' } +PPCMIndentedCode >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMInlinedCode.class.st b/software/PetitMarkdown/PPCMInlinedCode.class.st new file mode 100644 index 0000000..5e87f12 --- /dev/null +++ b/software/PetitMarkdown/PPCMInlinedCode.class.st @@ -0,0 +1,28 @@ +Class { + #name : 'PPCMInlinedCode', + #superclass : 'PPCMNode', + #instVars : [ + 'code' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMInlinedCode >> accept: visitor [ + ^ visitor visitInlinedCode: self +] + +{ #category : 'accessing' } +PPCMInlinedCode >> code [ + ^ code +] + +{ #category : 'accessing' } +PPCMInlinedCode >> code: anObject [ + code := anObject +] + +{ #category : 'accessing' } +PPCMInlinedCode >> text [ + ^ code +] diff --git a/software/PetitMarkdown/PPCMLine.class.st b/software/PetitMarkdown/PPCMLine.class.st new file mode 100644 index 0000000..0022b7e --- /dev/null +++ b/software/PetitMarkdown/PPCMLine.class.st @@ -0,0 +1,37 @@ +Class { + #name : 'PPCMLine', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMLine class >> empty [ + ^ PPCMLine new + addChild: (PPCMText empty); + yourself + +] + +{ #category : 'visiting' } +PPCMLine >> accept: visitor [ + ^ visitor visitLine: self +] + +{ #category : 'testing' } +PPCMLine >> isBlankLine [ + ^ self text = '' +] + +{ #category : 'testing' } +PPCMLine >> isLine [ + ^ true +] + +{ #category : 'visiting' } +PPCMLine >> text [ + | stream | + "hackity hack, this should not be used except for tests..." + stream := WriteStream on: ''. + children do: [ :child | stream nextPutAll: child text ]. + ^ stream contents +] diff --git a/software/PetitMarkdown/PPCMLink.class.st b/software/PetitMarkdown/PPCMLink.class.st new file mode 100644 index 0000000..8bd05fc --- /dev/null +++ b/software/PetitMarkdown/PPCMLink.class.st @@ -0,0 +1,45 @@ +Class { + #name : 'PPCMLink', + #superclass : 'PPCMNode', + #instVars : [ + 'label', + 'destination', + 'title' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMLink >> accept: visitor [ + ^ visitor visitLink: self +] + +{ #category : 'accessing' } +PPCMLink >> destination [ + ^ destination +] + +{ #category : 'accessing' } +PPCMLink >> destination: anObject [ + destination := anObject +] + +{ #category : 'accessing' } +PPCMLink >> label [ + ^ label +] + +{ #category : 'accessing' } +PPCMLink >> label: anObject [ + label := anObject +] + +{ #category : 'accessing' } +PPCMLink >> title [ + ^ title +] + +{ #category : 'accessing' } +PPCMLink >> title: anObject [ + title := anObject +] diff --git a/software/PetitMarkdown/PPCMLinkRef.class.st b/software/PetitMarkdown/PPCMLinkRef.class.st new file mode 100644 index 0000000..30c556b --- /dev/null +++ b/software/PetitMarkdown/PPCMLinkRef.class.st @@ -0,0 +1,23 @@ +Class { + #name : 'PPCMLinkRef', + #superclass : 'PPCMNode', + #instVars : [ + 'label' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMLinkRef >> accept: visitor [ + ^ visitor visitLinkRef: self +] + +{ #category : 'accessing' } +PPCMLinkRef >> label [ + ^ label +] + +{ #category : 'accessing' } +PPCMLinkRef >> label: anObject [ + label := anObject +] diff --git a/software/PetitMarkdown/PPCMLinkRefDef.class.st b/software/PetitMarkdown/PPCMLinkRefDef.class.st new file mode 100644 index 0000000..703a48b --- /dev/null +++ b/software/PetitMarkdown/PPCMLinkRefDef.class.st @@ -0,0 +1,50 @@ +Class { + #name : 'PPCMLinkRefDef', + #superclass : 'PPCMNode', + #instVars : [ + 'label', + 'destination', + 'title' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMLinkRefDef >> accept: visitor [ + ^ visitor visitLinkRefDef: self +] + +{ #category : 'accessing' } +PPCMLinkRefDef >> destination [ + ^ destination +] + +{ #category : 'accessing' } +PPCMLinkRefDef >> destination: anObject [ + destination := anObject +] + +{ #category : 'testing' } +PPCMLinkRefDef >> isBlockLevel [ + ^ true +] + +{ #category : 'accessing' } +PPCMLinkRefDef >> label [ + ^ label +] + +{ #category : 'accessing' } +PPCMLinkRefDef >> label: anObject [ + label := anObject +] + +{ #category : 'accessing' } +PPCMLinkRefDef >> title [ + ^ title +] + +{ #category : 'accessing' } +PPCMLinkRefDef >> title: anObject [ + title := anObject +] diff --git a/software/PetitMarkdown/PPCMLinkRefDefPlaceholder.class.st b/software/PetitMarkdown/PPCMLinkRefDefPlaceholder.class.st new file mode 100644 index 0000000..9b515de --- /dev/null +++ b/software/PetitMarkdown/PPCMLinkRefDefPlaceholder.class.st @@ -0,0 +1,15 @@ +Class { + #name : 'PPCMLinkRefDefPlaceholder', + #superclass : 'PPCMNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMLinkRefDefPlaceholder >> accept: visitor [ + ^ visitor visitLinkRefDefPlaceholder: self +] + +{ #category : 'as yet unclassified' } +PPCMLinkRefDefPlaceholder >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMList.class.st b/software/PetitMarkdown/PPCMList.class.st new file mode 100644 index 0000000..d97587b --- /dev/null +++ b/software/PetitMarkdown/PPCMList.class.st @@ -0,0 +1,89 @@ +Class { + #name : 'PPCMList', + #superclass : 'PPCMDelegateNode', + #instVars : [ + 'type', + 'start' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMList >> accept: visitor [ + ^ visitor visitList: self +] + +{ #category : 'accessing' } +PPCMList >> isBlockLevel [ + ^ true +] + +{ #category : 'as yet unclassified' } +PPCMList >> isLooseItem: item [ + | document size | + "empty item case" + (item children size == 0) ifTrue: [ ^ false ]. + + document := item child. + size := document children size. + + size < 3 ifTrue: [ ^ false ]. + + (1 to: size - 2) do: [ :idx | + ((document children at: idx) isBlockLevel and: + [(document children at: idx + 1) isBlankLine and: + [(document children at: idx + 2) isBlockLevel] ]) ifTrue: [ ^ true ] + ]. + ^ false +] + +{ #category : 'as yet unclassified' } +PPCMList >> isLooseList [ + | size | + size := children size. + + size < 3 ifTrue: [ ^ false ]. + + (1 to: size - 2) do: [ :idx | + ((children at: idx) isBlockLevel and: + [(children at: idx + 1) isBlankLine and: + [(children at: idx + 2) isBlockLevel] ]) ifTrue: [ ^ true ] + ]. + ^ false +] + +{ #category : 'as yet unclassified' } +PPCMList >> isTight [ + "blanks in the list?" + self isLooseList ifTrue: [ + ^ false + ]. + + "blanks in the items?" + self children do: [ :listItem | + (self isLooseItem: listItem) ifTrue: [ + ^ false + ] + ]. + ^ true +] + +{ #category : 'accessing' } +PPCMList >> start [ + ^ start +] + +{ #category : 'accessing' } +PPCMList >> start: anObject [ + start := anObject +] + +{ #category : 'accessing' } +PPCMList >> type [ + ^ type +] + +{ #category : 'accessing' } +PPCMList >> type: string [ + type := string +] diff --git a/software/PetitMarkdown/PPCMListItem.class.st b/software/PetitMarkdown/PPCMListItem.class.st new file mode 100644 index 0000000..d7f8723 --- /dev/null +++ b/software/PetitMarkdown/PPCMListItem.class.st @@ -0,0 +1,21 @@ +Class { + #name : 'PPCMListItem', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMListItem >> accept: visitor [ + ^ visitor visitListItem: self +] + +{ #category : 'as yet unclassified' } +PPCMListItem >> initialize [ + super initialize. + children := Array new: 1. +] + +{ #category : 'as yet unclassified' } +PPCMListItem >> isBlockLevel [ + ^ true +] diff --git a/software/PetitMarkdown/PPCMNode.class.st b/software/PetitMarkdown/PPCMNode.class.st new file mode 100644 index 0000000..6f63f2e --- /dev/null +++ b/software/PetitMarkdown/PPCMNode.class.st @@ -0,0 +1,67 @@ +Class { + #name : 'PPCMNode', + #superclass : 'Object', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMNode >> accept: visitor [ + ^ visitor visitNode: self +] + +{ #category : 'enumerating' } +PPCMNode >> allChildren [ + ^ Array with: self +] + +{ #category : 'accessing' } +PPCMNode >> children [ + ^ #() +] + +{ #category : 'gt' } +PPCMNode >> gtTreeViewIn: composite [ + + + composite tree + title: 'Tree'; + children: [:n | n children ]; + format: [:n| n name ifNil: [ n asString ] ifNotNil: [n name] ]; + shouldExpandToLevel: 6 +] + +{ #category : 'testing' } +PPCMNode >> isBlankLine [ + ^ false +] + +{ #category : 'testing' } +PPCMNode >> isBlockLevel [ + ^ false +] + +{ #category : 'testing' } +PPCMNode >> isCommonMarkNode [ + ^ true +] + +{ #category : 'testing' } +PPCMNode >> isLine [ + ^ false +] + +{ #category : 'testing' } +PPCMNode >> isParagraph [ + ^ false +] + +{ #category : 'replacing' } +PPCMNode >> replace: child with: anotherChild [ + ^ false +] + +{ #category : 'accessing' } +PPCMNode >> text [ + "hackity hack, this should not be used except for tests..." + ^ String cr join: (self children collect: [ :e | e text ]) +] diff --git a/software/PetitMarkdown/PPCMParagraph.class.st b/software/PetitMarkdown/PPCMParagraph.class.st new file mode 100644 index 0000000..78958e2 --- /dev/null +++ b/software/PetitMarkdown/PPCMParagraph.class.st @@ -0,0 +1,26 @@ +Class { + #name : 'PPCMParagraph', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMParagraph >> accept: visitor [ + ^ visitor visitParagraph: self +] + +{ #category : 'accessing' } +PPCMParagraph >> isBlockLevel [ + ^ true +] + +{ #category : 'testing' } +PPCMParagraph >> isParagraph [ + ^ true +] + +{ #category : 'accessing' } +PPCMParagraph >> text [ + "hackity hack, this should not be used except for tests..." + ^ String cr join: (self children collect: [ :e | e text ]) +] diff --git a/software/PetitMarkdown/PPCMPlainLine.class.st b/software/PetitMarkdown/PPCMPlainLine.class.st new file mode 100644 index 0000000..c1e1a09 --- /dev/null +++ b/software/PetitMarkdown/PPCMPlainLine.class.st @@ -0,0 +1,40 @@ +Class { + #name : 'PPCMPlainLine', + #superclass : 'PPCMNode', + #instVars : [ + 'text' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMPlainLine class >> empty [ + ^ self new + text: ''; + yourself +] + +{ #category : 'visiting' } +PPCMPlainLine >> accept: visitor [ + ^ visitor visitPlainLine: self +] + +{ #category : 'accessing' } +PPCMPlainLine >> isBlankLine [ + ^ self text = '' +] + +{ #category : 'accessing' } +PPCMPlainLine >> isLine [ + ^ true +] + +{ #category : 'visiting' } +PPCMPlainLine >> text [ + ^ text +] + +{ #category : 'visiting' } +PPCMPlainLine >> text: whatever [ + text := whatever +] diff --git a/software/PetitMarkdown/PPCMPlainText.class.st b/software/PetitMarkdown/PPCMPlainText.class.st new file mode 100644 index 0000000..6c1661f --- /dev/null +++ b/software/PetitMarkdown/PPCMPlainText.class.st @@ -0,0 +1,45 @@ +Class { + #name : 'PPCMPlainText', + #superclass : 'PPCMNode', + #instVars : [ + 'text' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMPlainText class >> empty [ + ^ self new + text: ''; + yourself +] + +{ #category : 'visiting' } +PPCMPlainText >> accept: visitor [ + ^ visitor visitPlainText: self +] + +{ #category : 'converting' } +PPCMPlainText >> asString [ + ^ text +] + +{ #category : 'printing' } +PPCMPlainText >> printOn: aStream [ + super printOn: aStream. + aStream nextPut: $(. + aStream nextPut: $'. + text isNil ifFalse: [ aStream nextPutAll: text ]. + aStream nextPut: $'. + aStream nextPut: $). +] + +{ #category : 'accessing' } +PPCMPlainText >> text [ + ^ text +] + +{ #category : 'accessing' } +PPCMPlainText >> text: anObject [ + text := anObject +] diff --git a/software/PetitMarkdown/PPCMSoftBreak.class.st b/software/PetitMarkdown/PPCMSoftBreak.class.st new file mode 100644 index 0000000..a00be2c --- /dev/null +++ b/software/PetitMarkdown/PPCMSoftBreak.class.st @@ -0,0 +1,10 @@ +Class { + #name : 'PPCMSoftBreak', + #superclass : 'PPCMNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMSoftBreak >> accept: visitor [ + ^ visitor visitSoftBreak: self +] diff --git a/software/PetitMarkdown/PPCMStrong.class.st b/software/PetitMarkdown/PPCMStrong.class.st new file mode 100644 index 0000000..5910211 --- /dev/null +++ b/software/PetitMarkdown/PPCMStrong.class.st @@ -0,0 +1,10 @@ +Class { + #name : 'PPCMStrong', + #superclass : 'PPCMDelegateNode', + #category : 'PetitMarkdown-AST' +} + +{ #category : 'visiting' } +PPCMStrong >> accept: visitor [ + ^ visitor visitStrong: self +] diff --git a/software/PetitMarkdown/PPCMText.class.st b/software/PetitMarkdown/PPCMText.class.st new file mode 100644 index 0000000..29755ee --- /dev/null +++ b/software/PetitMarkdown/PPCMText.class.st @@ -0,0 +1,55 @@ +Class { + #name : 'PPCMText', + #superclass : 'PPCMNode', + #instVars : [ + 'text' + ], + #category : 'PetitMarkdown-AST' +} + +{ #category : 'as yet unclassified' } +PPCMText class >> empty [ + ^ self new + text: ''; + yourself +] + +{ #category : 'comparing' } +PPCMText >> = anObject [ + ^ text = anObject +] + +{ #category : 'visiting' } +PPCMText >> accept: visitor [ + ^ visitor visitText: self +] + +{ #category : 'converting' } +PPCMText >> asString [ + ^ text +] + +{ #category : 'comparing' } +PPCMText >> hash [ + ^ text hash +] + +{ #category : 'printing' } +PPCMText >> printOn: aStream [ + super printOn: aStream. + aStream nextPut: $(. + aStream nextPut: $'. + text isNil ifFalse: [ aStream nextPutAll: text ]. + aStream nextPut: $'. + aStream nextPut: $). +] + +{ #category : 'accessing' } +PPCMText >> text [ + ^ text ifNil: [ '' ] +] + +{ #category : 'accessing' } +PPCMText >> text: anObject [ + text := anObject +] diff --git a/software/PetitMarkdown/PPCommonMarkBlockParser.class.st b/software/PetitMarkdown/PPCommonMarkBlockParser.class.st new file mode 100644 index 0000000..0bb04e5 --- /dev/null +++ b/software/PetitMarkdown/PPCommonMarkBlockParser.class.st @@ -0,0 +1,743 @@ +Class { + #name : 'PPCommonMarkBlockParser', + #superclass : 'PPCompositeParser', + #instVars : [ + 'space', + 'lineEnd', + 'linePrefix', + 'indentedCode', + 'fencedCode', + 'codeFirstFenceIndent', + 'newline', + 'codeFenceStart', + 'infoString', + 'prefix', + 'codeFenceStop', + 'codeFenceIndent', + 'codeLine', + 'prefixedEmptyLine', + 'documentEnd', + 'codeIndent', + 'emptyLine', + 'contentElement', + 'horizontalRule', + 'quoteBlock', + 'code', + 'list', + 'htmlBlock', + 'header', + 'linkRefDef', + 'paragraph', + 'document', + 'ATXHeader', + 'setextHeader', + 'setexLine', + 'setextHeaderUnderline', + 'listItem', + 'htmlTag', + 'plainLine', + 'quoteDedent', + 'quote', + 'listBegin', + 'listEmptyItem', + 'listEnd', + 'listOrderedMarker', + 'listBulletMarker', + 'listMarker', + 'listDoubleBlanks', + 'listBullet', + 'listContent', + 'listItemEnd', + 'quoteIndent', + 'paragraphLine', + 'lazyParagraphPrefix', + 'content', + 'linkLabel', + 'linkDestination', + 'linkTitle', + 'lineStart', + 'linkQuoteStart', + 'linkQuoteStop', + 'htmlBlockLine', + 'abstractLinkTitle' + ], + #category : 'PetitMarkdown-Parser' +} + +{ #category : 'headers' } +PPCommonMarkBlockParser >> ATXHeader [ + | begin end title | + begin := (($# asParser plus) setMax: 6). + end := ((space, $# asParser plus) optional trimRight: space), lineEnd. + + title := end negate plus flatten asPPCMPlainLine. + + ^ linePrefix, begin, (end not, space, title ==> #last) optional, end + + map: [ :_lp :level :_titleLine :_end | + | size titleLine | + size := level size. + titleLine := _titleLine ifNil: [ PPCMPlainLine empty ]. + + PPCMHeader new + level: size; + title: titleLine; + yourself + ] +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> abstractLinkTitle [ + ^ (space preceeds / lineStart), + linkQuoteStart, + ( (linkQuoteStop / (lineEnd, emptyLine)) not, + (('\' asParser, linkQuoteStop) / #any asParser) + ) plus flatten, + linkQuoteStop + + ==> [ :e | self decodeEntities: (self escape: (e third)) ] +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> code [ + ^ indentedCode / fencedCode +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> codeFenceIndent [ + ^ [ :context | + context codeFenceIndent parseOn: context + ] asParser +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> codeFenceStart [ + | tilde eh | + tilde := ($~ asParser min: 3) >=> [ :context :cc | + | retval | + retval := cc value. + retval isPetitFailure ifFalse: [ + context codeFence: ($~ asParser min: retval size). + ]. + retval + ]. + + eh := ($` asParser min: 3) >=> [ :context :cc | + | retval | + retval := cc value. + retval isPetitFailure ifFalse: [ + context codeFence: ($` asParser min: retval size). + ]. + retval + ]. + + ^ codeFirstFenceIndent, (tilde / eh) + +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> codeFenceStop [ + ^ ([ :context | + context codeFence parseOn: context + ] asParser trimRight: space), lineEnd and +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> codeFirstFenceIndent [ + ^ (space max: 3) >=> [ :context :cc | + | result | + result := cc value. + result isPetitFailure ifFalse: [ + context codeFenceIndent: (space max: result size). + ]. + result + ] +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> codeIndent [ + ^ ' ' asParser / Character tab asParser +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> codeLine [ + ^ newline negate star flatten + + map: [ :_text | + | textNode | + textNode := PPCMText new + text: (self encodeEntities: _text); + yourself. + + PPCMLine new + addChild: textNode; + yourself + ] +] + +{ #category : 'document' } +PPCommonMarkBlockParser >> content [ + ^ contentElement, + ((prefix, contentElement) nonEmpty ==> #second) star + + map: [ :first :rest | + | | + PPCMContainer new + addChild: first; + addChildren: rest; + yourself + ] +] + +{ #category : 'document' } +PPCommonMarkBlockParser >> contentElement [ + ^ + horizontalRule / + quoteBlock / + code / + list / + htmlBlock / + header / + linkRefDef / + paragraph / + ((emptyLine, lineEnd) ==> #first) +] + +{ #category : 'support' } +PPCommonMarkBlockParser >> decodeEntities: string [ + ^ PPCommonMarkUtils instance decodeEntities: string +] + +{ #category : 'document' } +PPCommonMarkBlockParser >> document [ + ^ ((prefix, contentElement) nonEmpty ==> #second) star + + map: [ :elems | + PPCMDocument new + addChildren: elems; + yourself + ] +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> documentEnd [ + ^ #eof asParser +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> emptyLine [ + ^ space star, #endOfLine asParser ==> [ :e | + PPCMPlainLine empty + ] +] + +{ #category : 'support' } +PPCommonMarkBlockParser >> encodeEntities: string [ + ^ PPCommonMarkUtils instance encodeEntities: string +] + +{ #category : 'support' } +PPCommonMarkBlockParser >> escape: string [ + ^ PPCommonMarkUtils instance escape: string +] + +{ #category : 'support' } +PPCommonMarkBlockParser >> escapeUrl: string [ + ^ PPCommonMarkUtils instance escapeUrl: string +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> fencedCode [ + ^ linePrefix and, codeFenceStart, infoString optional, lineEnd, + ( + (( + (prefix, linePrefix, codeFenceStop) not, prefix, codeFenceIndent, codeLine, lineEnd) ==> #fourth / + (prefixedEmptyLine, lineEnd ==> #first) + ) nonEmpty + ) star, + ((((prefix, linePrefix, codeFenceStop) / documentEnd), lineEnd) / prefix not) + + map: [ :_lp :_fenceStart :_info :_le :_code :_fenceStop | + PPCMFencedCode new + infoString: _info; + addChildren: _code; + yourself + ] +] + +{ #category : 'headers' } +PPCommonMarkBlockParser >> header [ + ^ ATXHeader / setextHeader +] + +{ #category : 'horizontal rule' } +PPCommonMarkBlockParser >> horizontalRule [ + | stars minus under | + stars := '*' asParser, (('*' asParser trim: space) min: 2). + minus := '-' asParser, (('-' asParser trim: space) min: 2). + under := '_' asParser, (('_' asParser trim: space) min: 2). + + ^ linePrefix, ((stars / minus / under) flatten), space star, lineEnd + map: [ :_prefix :_hrule :_space :_le | + PPCMHrule new + rule: _hrule; + yourself + ] + +] + +{ #category : 'html blocks' } +PPCommonMarkBlockParser >> htmlBlock [ + ^ (linePrefix, htmlTag) and, htmlBlockLine, lineEnd, + (prefix, (emptyLine not), htmlBlockLine, lineEnd ==> #third) star + + map: [ :_pred :_line :_le :_rest | + PPCMHtmlBlock new + addChild: _line; + addChildren: _rest; + yourself + ] +] + +{ #category : 'html blocks' } +PPCommonMarkBlockParser >> htmlBlockLine [ + ^ newline negate star flatten + + map: [ :_text | + | text | + text := PPCMText new + text: _text; + yourself. + + PPCMLine new + addChild: text; + yourself + ] +] + +{ #category : 'html blocks' } +PPCommonMarkBlockParser >> htmlTag [ + ^ '> indentedCode [ + ^ codeIndent, emptyLine not, codeLine, lineEnd, + ( + ((prefix, codeIndent, codeLine, lineEnd) ==> #third) / + ((prefix, emptyLine, lineEnd) nonEmpty ==> #second) + ) star + + map: [ :_cp :_pred :_first :_le :_rest | + PPCMIndentedCode new + addChild: _first; + addChildren: _rest; + yourself + ] +] + +{ #category : 'code' } +PPCommonMarkBlockParser >> infoString [ + ^ ((lineEnd / space / codeFenceStop / $` asParser) negate plus trimBlanks flatten), + (lineEnd / $` asParser) negate star ==> [:e | self decodeEntities: e first ] +] + +{ #category : 'paragraphs' } +PPCommonMarkBlockParser >> lazyParagraphPrefix [ + ^ (prefix, quoteIndent) not, + (quote / space) star +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> lineEnd [ + ^ newline / documentEnd +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> linePrefix [ + ^ ((PPPossessiveRepeatingParser on: (#blank asParser )) + setMax: 3; + yourself), + (#blank asParser not) + ==> #first +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> lineStart [ + ^ #startOfLine asParser +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> linkDestination [ + | parens escapedParen | + "TODO: fix?" + escapedParen := '\(' asParser / '\)' asParser. + + parens := PPDelegateParser new + name: 'parens'; + yourself. + "Parens cannot be nested!" + parens setParser: $( asParser, (($( asParser / $) asParser) not, (escapedParen / #any asParser)) star, $) asParser. + + ^ (($< asParser, ((($> asParser / newline) not, #any asParser) star) flatten, $> asParser) + ==> [ :e | self escapeUrl: (self escape: e second) ]) / + ((space / lineEnd / $) asParser) not, (parens / escapedParen / $( asParser negate)) plus flatten + ==> [ :e | self escapeUrl: (self escape: e) ] +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> linkLabel [ + | label | + label := ($] asParser not, ('\]' asParser / #any asParser)) star flatten. + + ^ $[ asParser, label, $] asParser + + map: [ :_start :_label :_end | + PPCMText new + text: (self escape: _label); + yourself + ] +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> linkQuoteStart [ + ^ PPFailingParser message: 'abstract quote start'. +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> linkQuoteStop [ + ^ PPFailingParser message: 'abstract quote stop' +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> linkRefDef [ + ^ (linePrefix, linkLabel, ':' asParser, (lineEnd optional trim: space), linkDestination, ((lineEnd optional trim: space), linkTitle ==> #second) optional, space star, lineEnd + + map: [ :_lp :_label :_semicolon :_ws1 :_dest :_title :_ws3 :_le | + PPCMLinkRefDef new + label: _label; + title: _title; + destination: _dest; + yourself. + ]) + + >=> [ :context :cc | + | retval | + retval := cc value. + retval isPetitFailure ifFalse: [ + context registerLink: retval. + retval := PPCMLinkRefDefPlaceholder new. + ]. + retval + ] +] + +{ #category : 'links' } +PPCommonMarkBlockParser >> linkTitle [ + ^ + ((abstractLinkTitle + where: linkQuoteStart is: $" asParser) + where: linkQuoteStop is: $" asParser) / + ((abstractLinkTitle + where: linkQuoteStart is: $' asParser) + where: linkQuoteStop is: $' asParser) / + ((abstractLinkTitle + where: linkQuoteStart is: $( asParser) + where: linkQuoteStop is: $) asParser) +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> list [ + ^ + listBegin, + listItem, + ( + (prefix, listItem ==> #second) / + "empty item is part of the list only if followed by normal item" + (listEmptyItem, (prefix, listItem) and ==> #first) + ) star, + listEnd + + map: [ :_start :_first :_rest :_end | + PPCMList new + type: _start second; + start: _start first; + addChild: _first; + addChildren: _rest; + yourself + ] +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listBegin [ + ^ (linePrefix, (listOrderedMarker / listBulletMarker)) and ==> #second >=> [ :context :cc | + | retval | + retval := cc value. + retval isPetitFailure ifFalse: [ + context listItemType: (retval third). + ]. + retval + ] + +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listBullet [ + ^ + "push content as spaces on the indent stack" + ( + (linePrefix, listMarker, space, linePrefix optional) flatten and + ==> [:e | self spaces: (e size)] + / + (linePrefix, listMarker, lineEnd) flatten and + ==> [:e | self spaces: (e size)] + ) pushAsParser, + "Consume marker and one space" + (linePrefix, listMarker, (space / lineEnd and)) +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listBulletMarker [ + ^ + ($- asParser / + $* asParser / + $+ asParser) + + "Start . type . parser to accept the same type" + ==> [ :e | { nil . #unordered . e asParser } ] +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listContent [ + ^ + contentElement, + ( + ((prefix, contentElement) nonEmpty ==> #second) / + "Empty line of the list content is part of the content only if followed by non-empty line" + ((prefixedEmptyLine, lineEnd, (prefix, contentElement) and) nonEmpty + ==> #first) + ) star + + map: [ :_first :_rest | + | | + PPCMContainer new + addChild: _first; + addChildren: _rest; + yourself + ] +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listDoubleBlanks [ + ^ + (prefixedEmptyLine, lineEnd) nonEmpty, + (prefixedEmptyLine, lineEnd) nonEmpty + +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listEmptyItem [ + ^ (listDoubleBlanks not, prefixedEmptyLine, lineEnd) nonEmpty ==> #second + +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listEnd [ + ^ [ :context | + context listItemStack pop + ] asParser + +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listItem [ + ^ horizontalRule not, listBullet, listContent, listItemEnd + + map: [ :_pred :_bullet :_content :_end | + PPCMListItem new + child: _content; + yourself + ] + + +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listItemEnd [ + ^ [ :context | context indentStack pop ] asParser +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listMarker [ + ^ [ :context | context listItemType parseOn: context ] asParser +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> listOrderedMarker [ + | dot bracket | + dot := #digit asParser plus flatten, $. asParser. + bracket := #digit asParser plus flatten, $) asParser. + + "Start . type . parser to accept the same type" + ^ (dot ==> [ :e | { e first asNumber . #ordered . dot } ]) / + (bracket ==> [ :e | { e first asNumber . #ordered . bracket } ]) + +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> newline [ + ^ #newline asParser +] + +{ #category : 'paragraphs' } +PPCommonMarkBlockParser >> paragraph [ + ^ linePrefix, (emptyLine) not, paragraphLine trimBlanks, lineEnd, + ( + (prefix / lazyParagraphPrefix), + (emptyLine / ATXHeader / horizontalRule / fencedCode / htmlBlock / list / quote) not, + paragraphLine trimBlanks, + lineEnd ==> #third + ) nonEmpty star + map: [ :_lp :_pred :_line :_end :_rest | + | para | + para := PPCMParagraph new. + para addChild: _line. + _rest do: [ :anotherLine | para addChild: anotherLine ]. + para + ] +] + +{ #category : 'paragraphs' } +PPCommonMarkBlockParser >> paragraphLine [ + ^ plainLine +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> plainLine [ + ^ newline negate star flatten + + map: [ :_text | + PPCMPlainLine new + text: _text; + yourself + ] +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> prefix [ + ^ #prefix asParser +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> prefixedEmptyLine [ + "empty line with appropriate number of quotes, but with arbitrary whitespaces" + ^ (quoteDedent not, (quote / space) star, #endOfLine asParser) ==> [ :e | PPCMPlainLine empty ] +] + +{ #category : 'quotes' } +PPCommonMarkBlockParser >> quote [ + ^ (linePrefix, $> asParser, space optional) flatten +] + +{ #category : 'quotes' } +PPCommonMarkBlockParser >> quoteBlock [ + ^ quoteIndent, + content, + quoteDedent + + map: [ :indent :_content :dedent | + PPCMBlockQuote new + child: _content; + yourself + ] +] + +{ #category : 'quotes' } +PPCommonMarkBlockParser >> quoteDedent [ + ^ (prefix not, quote pop) flatten +] + +{ #category : 'quotes' } +PPCommonMarkBlockParser >> quoteIndent [ + ^ (quote ==> [ :e | quote ]) pushAsParser +] + +{ #category : 'headers' } +PPCommonMarkBlockParser >> setexLine [ + ^ plainLine +] + +{ #category : 'headers' } +PPCommonMarkBlockParser >> setextHeader [ + ^ linePrefix, emptyLine not, setexLine, lineEnd, setextHeaderUnderline + + map: [ :_prefix :_predicates :_text :_nl :_underline | + PPCMHeader new + title: _text; + level: _underline; + yourself + ] +] + +{ #category : 'headers' } +PPCommonMarkBlockParser >> setextHeaderUnderline [ + | equal minus | + equal := '=' asParser plus ==> [:t | 1]. + minus := '-' asParser plus ==> [:t | 2]. + + ^ prefix, listItem not, linePrefix, ((equal / minus) trimRight: space), lineEnd ==> #fourth + +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> space [ + ^ Character space asParser +] + +{ #category : 'lists' } +PPCommonMarkBlockParser >> spaces: length [ + | retval | + retval := ''. + length timesRepeat: [ + retval := retval, ' '. + ]. + ^ retval +] + +{ #category : 'document' } +PPCommonMarkBlockParser >> start [ + ^ document >=> [ :context :cc | + | retval | + retval := cc value. + retval isPetitFailure ifFalse: [ + context links do: [ :link | + retval addChildFirst: link. + ] + ]. + retval + ] +] + +{ #category : 'initialization' } +PPCommonMarkBlockParser >> utils [ + ^ PPCommonMarkUtils instance +] + +{ #category : 'lines and whitespace' } +PPCommonMarkBlockParser >> whitespace [ + ^ #space asParser +] diff --git a/software/PetitMarkdown/PPCommonMarkBlockTest.class.st b/software/PetitMarkdown/PPCommonMarkBlockTest.class.st new file mode 100644 index 0000000..5f603d1 --- /dev/null +++ b/software/PetitMarkdown/PPCommonMarkBlockTest.class.st @@ -0,0 +1,732 @@ +Class { + #name : 'PPCommonMarkBlockTest', + #superclass : 'PPCompositeParserTest', + #instVars : [ + 'context', + 'quote', + 'string', + 'expected' + ], + #category : 'PetitMarkdown-Tests' +} + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> assert: something type: type [ + self assert: (something isKindOf: type). + +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> assertResult: expectedResult [ + self assert: expectedResult = result. + +" + (TextDiffBuilder from: result to: expectedResult) buildDisplayPatch. +" +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> context [ + ^ context +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> parse: input rule: rule to: expectedResult [ + self parse: input rule: rule. + self assert: expectedResult = result. + +" + (TextDiffBuilder from: result to: expectedResult) buildDisplayPatch. +" +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> parserClass [ + ^ PPCommonMarkBlockParser +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> setUp [ + context := PPContext new. + + quote := self parserInstanceFor: #quote +] + +{ #category : 'test-headers' } +PPCommonMarkBlockTest >> testATXHeader [ + self parse: '# foo' rule: #ATXHeader. + self assert: result title text = 'foo'. + + self parse: '# foo#' rule: #ATXHeader. + self assert: result title text = 'foo#'. + + self parse: '# foo #' rule: #ATXHeader. + self assert: result title text = 'foo'. +] + +{ #category : 'test-headers' } +PPCommonMarkBlockTest >> testATXHeader2 [ + self parse: '#' rule: #ATXHeader. + self assert: result title text = ''. + + self parse: '# ' rule: #ATXHeader. + self assert: result title text = ''. + + self parse: '# #' rule: #ATXHeader. + self assert: result title text = ''. + + self parse: '### ###' rule: #ATXHeader. + self assert: result title text = ''. +] + +{ #category : 'test-code' } +PPCommonMarkBlockTest >> testFencedCode [ + self parse: '``` +abc + +def +```' rule: #code. + self assert: result type: PPCMFencedCode. + self assert: result code = 'abc + +def'. +] + +{ #category : 'test-code' } +PPCommonMarkBlockTest >> testFencedCode2 [ + context := PPContext new. + context indentStack push: ' ' asParser. + self parse: '``` + abc + + def + ```' rule: #code. + + self assert: result type: PPCMFencedCode. + self assert: result code = 'abc + +def'. +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> testHorizontalRule [ + self parse: '***' rule: #horizontalRule. + + self parse: ' - - -' rule: #horizontalRule. +] + +{ #category : 'test-html blocks' } +PPCommonMarkBlockTest >> testHtmlBlock [ + self parse: ' +
    ' rule: #htmlBlock. + + self assert: result type: PPCMHtmlBlock. +] + +{ #category : 'test-code' } +PPCommonMarkBlockTest >> testIndentedCode [ + self parse: ' abc' rule: #code. + self assert: result type: PPCMIndentedCode. + self assert: result code = 'abc'. + + self parse: ' abc + def' rule: #code. + self assert: result code = 'abc + def'. + + self parse: ' this is a + code' rule: #code. + self assert: result code = 'this is a + code'. + + self parse: ' this is + + a code' rule: #code. + self assert: result code = ' this is + +a code'. + + self parse: ' this is + + a code +' rule: #code. + self assert: result code = ' this is + +a code'. + + + + + self parse: ' chunk1 + + chunk2 + + + + chunk3' rule: #code. + + self assert: result code = 'chunk1 + +chunk2 + + + +chunk3'. + + self parse: ' chunk1 + + chunk2' rule: #code. + self assert: result code = 'chunk1 + + chunk2'. +] + +{ #category : 'test-paragraph' } +PPCommonMarkBlockTest >> testLazyParagraphPrefix [ + self parse: '' rule: #lazyParagraphPrefix. + + context := PPContext new. + context indentStack push: quote. + self parse: '> ' rule: #lazyParagraphPrefix. + + context := PPContext new. + context indentStack push: quote. + self fail: '> >' rule: #lazyParagraphPrefix. + + context := PPContext new. + context indentStack push: quote. + context indentStack push: quote. + self parse: ' > >' rule: #lazyParagraphPrefix. + + +] + +{ #category : 'test-links' } +PPCommonMarkBlockTest >> testLinkRef [ + self parse: '[foo]' rule: #paragraph. + self assert: result type: PPCMParagraph. + self assert: result text = '[foo]'. +] + +{ #category : 'test-links' } +PPCommonMarkBlockTest >> testLinkRefDef [ + self parse: '[foo]: /url "title"' rule: #linkRefDef. + self assert: result type: PPCMLinkRefDefPlaceholder. + self assert: context links size = 1. + self assert: context links anyOne type: PPCMLinkRefDef. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testList [ + + context := PPContext new. + self parse: '- one' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 1. + self assert: result child text = 'one'. + + self assert: context indentStack isEmpty. + + context := PPContext new. + self parse: '- one +- two' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 2. + self assert: result firstChild text = 'one'. + self assert: result secondChild text = 'two'. + self assert: context indentStack isEmpty. + + context := PPContext new. + self parse: '- one + +- two' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 3. + self assert: result firstChild text trim = 'one'. + self assert: result thirdChild text = 'two'. + self assert: context indentStack isEmpty. + self assert: context indentStack isEmpty. + + context := PPContext new. + context indentStack push: quote. + self parse: '- one +>- two' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 2. + self assert: result firstChild text = 'one'. + self assert: result secondChild text = 'two'. + self assert: context indentStack size = 1. + + context := PPContext new. + self parse: '- one +- ' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 2. + self assert: result firstChild text = 'one'. + self assert: result secondChild text = ''. + self assert: context indentStack isEmpty. + +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testList2 [ + + context := PPContext new. + self parse: '1. one' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 1. + self assert: result child text = 'one'. + + self assert: context indentStack isEmpty. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListBullet [ + context := PPContext new. + context listItemType: $- asParser. + self parse: '- ' rule: #listBullet. + self assert: context indentStack size = 1. + self assert: context indentStack top literal = ' '. + + + context := PPContext new. + context listItemType: $- asParser. + self parse: ' - ' rule: #listBullet. + + self assert: context indentStack size = 1. + self assert: context indentStack top literal = ' '. + + context := PPContext new. + context listItemType: $- asParser. + parser := self parserInstanceFor: #listBullet. + self assert: parser parse: ' - ' end: 3. + + self assert: context indentStack size = 1. + self assert: context indentStack top literal = ' '. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListBullet2 [ + context := PPContext new. + context listItemType: $* asParser. + self fail: '- ' rule: #listBullet. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListContent [ + context := PPContext new. + context indentStack push: quote. + context indentStack push: ' ' asParser. + + self parse: 'one +> two' rule: #listContent. + + self assert: result text = 'one +two'. + + context := PPContext new. + context indentStack push: quote. + context indentStack push: ' ' asParser. + + self parse: 'one +> two' rule: #listContent. + + self assert: result text = 'one +two'. + + context := PPContext new. + context indentStack push: quote. + context indentStack push: ' ' asParser. + + self parse: '> one +> > two' rule: #listContent. + + self assert: result firstChild type: PPCMBlockQuote. + self assert: result firstChild text = 'one +two'. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListItem [ + + context := PPContext new. + context listItemType: $- asParser. + self parse: '- one' rule: #listItem. + + self assert: result type: PPCMListItem. + self assert: result text = 'one'. + self assert: context indentStack size = 0. + + context := PPContext new. + context listItemType: $- asParser. + context indentStack push: quote. + self parse: '- > one +> > two' rule: #listItem. + self assert: result type: PPCMListItem. + self assert: result child child type: PPCMBlockQuote. + self assert: result child child text = 'one +two'. + + + context := PPContext new. + context indentStack push: quote. + context listItemType: $- asParser. + self parse: '- > one +> +> > two' rule: #listItem. + self assert: result type: PPCMListItem. + self assert: result child children size = 3. + self assert: result child children first type: PPCMBlockQuote. + self assert: result child children third type: PPCMIndentedCode. + + context := PPContext new. + context listItemType: $- asParser. + + self parse: '- ' rule: #listItem. + self assert: result type: PPCMListItem. + self assert: result text = ''. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListItemCode [ + context := PPContext new. + context listItemType: $- asParser. + self parse: '- one' rule: #listItem. + self assert: result child child type: PPCMIndentedCode. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListItemEmpty [ + + context := PPContext new. + context listItemType: $- asParser. + self parse: '- ' rule: #listItem. + + self assert: result type: PPCMListItem. + self assert: result text = ''. + self assert: context indentStack size = 0. + + context := PPContext new. + context listItemType: $- asParser. + self parse: '-' rule: #listItem. + + self assert: result type: PPCMListItem. + self assert: result text = ''. + self assert: context indentStack size = 0. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListNested01 [ + + context := PPContext new. + self parse: '- one + - two' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 1. + self assert: result child child firstChild text = 'one'. + self assert: result child child secondChild type: PPCMList. + self assert: result child child secondChild child text = 'two'. + + self assert: context indentStack isEmpty. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListNested02 [ + + context := PPContext new. + self parse: '- one + - two + - three' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 1. + self assert: result child child firstChild text = 'one'. + self assert: result child child secondChild type: PPCMList. + self assert: result child child secondChild child child firstChild text = 'two'. + self assert: result child child secondChild child child secondChild type: PPCMList. + self assert: result child child secondChild child child secondChild text = 'three'. + + self assert: context indentStack isEmpty. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListNested03 [ + + context := PPContext new. + self parse: '- one + - two + - three + - four' rule: #list. + + self assert: result type: PPCMList. + self assert: result children size = 1. + self assert: result child child firstChild text = 'one'. + self assert: result child child secondChild type: PPCMList. + self assert: result child child secondChild firstChild child firstChild text = 'two'. + self assert: result child child secondChild firstChild child secondChild type: PPCMList. + self assert: result child child secondChild firstChild child secondChild text = 'three'. + self assert: result child child secondChild secondChild child firstChild text = 'four'. + + self assert: context indentStack isEmpty. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListNested04 [ + + context := PPContext new. + self parse: '- one + - two + - three + - four + + five' rule: #list. + self assert: result type: PPCMList. + self assert: result children size = 1. + self assert: result child child firstChild text = 'one'. + self assert: result child child secondChild type: PPCMList. + self assert: result child child secondChild firstChild child firstChild text = 'two'. + self assert: result child child secondChild firstChild child secondChild type: PPCMList. + self assert: result child child secondChild firstChild child secondChild text = 'three'. + self assert: result child child secondChild secondChild child firstChild text = 'four'. + self assert: result child child secondChild secondChild child thirdChild text = 'five'. + + self assert: context indentStack isEmpty. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListTight [ + + context := PPContext new. + self parse: '- one +- two' rule: #list. + + self assert: result type: PPCMList. + self assert: result isTight. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListTight2 [ + + context := PPContext new. + self parse: '- one + +- two' rule: #list. + + + self assert: result type: PPCMList. + self assert: result children size = 3. + self assert: result isTight not. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListTight3 [ + + context := PPContext new. + self parse: '- one + two' rule: #list. + + self assert: result type: PPCMList. + self assert: result isTight. +] + +{ #category : 'test-lists' } +PPCommonMarkBlockTest >> testListTight4 [ + + context := PPContext new. + self parse: '- one + + two' rule: #list. + + self assert: result type: PPCMList. + self assert: result isTight. +] + +{ #category : 'test-paragraph' } +PPCommonMarkBlockTest >> testParagraph [ + self parse: 'abc +def' rule: #paragraph. + self assert: result text = 'abc +def'. + + self parse: 'abc + def' rule: #paragraph. + self assert: result text = 'abc +def'. + + context := PPContext new. + context indentStack push: quote. + self parse: ' abc +def' rule: #paragraph. + self assert: result text = 'abc +def'. + + context := PPContext new. + context indentStack push: quote. + self parse: 'abc +> def' rule: #paragraph. + self assert: result text = 'abc +def'. +] + +{ #category : 'test-paragraph' } +PPCommonMarkBlockTest >> testParagraph2 [ + self parse: 'foo + # bar' rule: #paragraph. + self assert: result text = 'foo +# bar'. +] + +{ #category : 'as yet unclassified' } +PPCommonMarkBlockTest >> testPrefix [ + self parse: '' rule: #prefix. + + context := PPContext new. + context indentStack push: quote. + self parse: '> ' rule: #prefix + +] + +{ #category : 'test-quotes' } +PPCommonMarkBlockTest >> testQuote [ + self parse: '>' rule: #quote. + self assertResult: '>'. + + self parse: '> ' rule: #quote. + self assertResult: '> '. + + self fail: ('>', String cr) rule: #quote. +] + +{ #category : 'test-quotes' } +PPCommonMarkBlockTest >> testQuoteBlock [ + self parse: '> foo' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. + self assert: result children size = 1. + self assert: result child text = 'foo'. + + + context := PPContext new. + self parse: '> foo +> bar' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. + self assert: result children size = 1. + self assert: result child text = 'foo +bar'. + + context := PPContext new. + self parse: '>> foo +>> bar' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. + self assert: result child child type: PPCMBlockQuote. + self assert: result child child text = 'foo +bar'. + + context := PPContext new. + self parse: '># Foo' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. + self assert: result child child type: PPCMHeader. + self assert: result child child text = 'Foo'. + + context := PPContext new. + self parse: '> foo +> +> bar' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. + self assert: result child child type: PPCMIndentedCode. + + + context := PPContext new. + self parse: '>' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. + + + context := PPContext new. + self parse: '> +> +> ' rule: #quoteBlock. + self assert: result type: PPCMBlockQuote. +] + +{ #category : 'test-quotes' } +PPCommonMarkBlockTest >> testQuoteDedent [ + parser := self parserInstanceFor: #quoteDedent. + + context := PPContext new. + context indentStack push: quote. + self assert: parser parse: '' end: 0. + self assert: context indentStack size = 0. + self assert: parser fail: '' end: 0. + + context := PPContext new. + self assert: parser fail: ''. + + context := PPContext new. + context indentStack push: quote. + self assert: parser fail: '>' end: 0. + + context := PPContext new. + context indentStack push: quote. + context indentStack push: quote. + self assert: parser parse: ' > ' end: 0. + + context := PPContext new. + context indentStack push: quote. + context indentStack push: ' ' asParser. + self assert: parser fail: ' > ' end: 0. + + context := PPContext new. + context indentStack push: quote. + context indentStack push: quote. + context indentStack push: quote. + self assert: parser parse: ' > > ' end: 0. + + + context := PPContext new. + context indentStack push: quote. + context indentStack push: quote. + self assert: parser parse: '' end: 0. + self assert: parser parse: '' end: 0. + self assert: parser fail: '' end: 0. +] + +{ #category : 'test-quotes' } +PPCommonMarkBlockTest >> testQuoteIndent [ + parser := self parserInstanceFor: #quoteIndent. + + context := PPContext new. + self assert: parser parse: '>' end: 1. + self assert: context indentStack size = 1. + self assert: context indentStack top = quote. + + context := PPContext new. + self assert: parser parse: ' > ' end: 5. + + context := PPContext new. + self assert: parser parse: ' >' end: 3. + + context := PPContext new. + self assert: parser parse: ' >' end: 2. + + context := PPContext new. + self assert: parser fail: ' >'. + + context := PPContext new. + context indentStack push: quote. + self assert: parser parse: '>' end: 1. + self assert: context indentStack size = 2. + self assert: context indentStack top = quote. + + context := PPContext new. + context indentStack push: quote. + self assert: parser parse: '> > ' end: 2. + + context := PPContext new. + context indentStack push: quote. + self assert: parser parse: ' > > ' end: 3. +] + +{ #category : 'test-headers' } +PPCommonMarkBlockTest >> testSetextHeader [ + self parse: 'Foo +---' rule: #setextHeader. + self assert: result title text = 'Foo'. +] diff --git a/software/PetitMarkdown/PPCommonMarkInlineTest.class.st b/software/PetitMarkdown/PPCommonMarkInlineTest.class.st new file mode 100644 index 0000000..76188e5 --- /dev/null +++ b/software/PetitMarkdown/PPCommonMarkInlineTest.class.st @@ -0,0 +1,179 @@ +Class { + #name : 'PPCommonMarkInlineTest', + #superclass : 'PPCompositeParserTest', + #category : 'PetitMarkdown-Tests' +} + +{ #category : 'support' } +PPCommonMarkInlineTest >> assert: something type: type [ + self assert: (something isKindOf: type). + +] + +{ #category : 'support' } +PPCommonMarkInlineTest >> parserClass [ + ^ PPCommonMarkInlinesParser +] + +{ #category : 'support' } +PPCommonMarkInlineTest >> setUp [ + super setUp. + self parserInstance initialize. +] + +{ #category : 'test-paragraph' } +PPCommonMarkInlineTest >> testAmpersand [ + self parse: 'ab'. + self assert: result first text = 'ab'. + + self parse: 'a&b'. + self assert: result first text = 'a'. + self assert: result second text = '&'. + self assert: result third text = 'b'. + + self parse: 'a\&b'. + self assert: result first text = 'a'. + self assert: result second text = '&'. + self assert: result third text = 'b'. + + self parse: 'a&b'. + self assert: result first text = 'a'. + self assert: result second text = '&'. + self assert: result third text = 'b'. + + self parse: 'a\&b'. + self assert: result first text = 'a'. + self assert: result second text = '&'. + self assert: result third text = 'amp;b'. + +] + +{ #category : 'test-links' } +PPCommonMarkInlineTest >> testAutolink [ + self parse: '' rule: #autolink. + self assert: result type: PPCMLink. +] + +{ #category : 'test-emphasize' } +PPCommonMarkInlineTest >> testEmphasize [ + self parse: '*bar*' rule: #emphasize. + self assert: result type: PPCMEmphasize. + self assert: result text = 'bar'. +] + +{ #category : 'test-emphasize' } +PPCommonMarkInlineTest >> testEmphasize2 [ + self fail: '\*bar*' rule: #emphasize. + self fail: '*bar\*' rule: #emphasize. +] + +{ #category : 'tests' } +PPCommonMarkInlineTest >> testEscaped [ + | escaped | + escaped := self parserInstanceFor: #escaped. + parser := #any asParser, escaped, 'a' asParser. + + self assert: parser parse: '\a'. + self assert: parser fail: 'ba'. + + escaped := self parserInstanceFor: #escaped. + parser := #any asParser, #any asParser, escaped, 'a' asParser. + + self assert: parser parse: 'a\a'. + self assert: parser fail: '\\a'. +] + +{ #category : 'test-links' } +PPCommonMarkInlineTest >> testLinkDestination [ + self parse: '/url' rule: #linkDestination. + self assert: result = '/url'. + + self parse: '' rule: #linkDestination. + self assert: result = 'my%20url'. + +] + +{ #category : 'test-links' } +PPCommonMarkInlineTest >> testLinkInLabel [ + parser := self parserInstanceFor: #linkInLabel. + + self assert: parser parse: 'bar [baz](/uri)' end: 4. + self assert: parser parse: 'foo *[bar [baz](/uri)](/uri)*' end: 10. +] + +{ #category : 'test-links' } +PPCommonMarkInlineTest >> testLinkRef [ + parser := self parserInstanceFor: #linkRef. + + self assert: parser fail: '[foo]'. + +] + +{ #category : 'test-links' } +PPCommonMarkInlineTest >> testLinkRef2 [ + | refDef | + refDef := PPCMLinkRefDef new + label: 'foo'; + destination: 'url'; + title: 'title'; + yourself. + self parserInstance registerLinkRefDef: refDef. + parser := self parserInstanceFor: #linkRef. + + self assert: parser parse: '[foo]'. + +] + +{ #category : 'test-paragraph' } +PPCommonMarkInlineTest >> testParagraphBreak [ + self parse: 'foo +bar'. + self assert: result first type: PPCMText. + self assert: result first text = 'foo'. + self assert: result second type: PPCMSoftBreak. + self assert: result third type: PPCMText. + self assert: result third text = 'bar'. +] + +{ #category : 'test-paragraph' } +PPCommonMarkInlineTest >> testParagraphEscape [ + self parse: 'a *a*'. + self assert: result size = 2. + self assert: result second type: PPCMEmphasize. + + self parse: 'a \*a\*'. + self assert: result size = 4. + self assert: result first text = 'a '. + self assert: result second text = '*'. + self assert: result third text = 'a'. + self assert: result fourth text = '*'. +] + +{ #category : 'test-html' } +PPCommonMarkInlineTest >> testRawHtml [ + self parse: ''. + + self assert: result size = 2. + self assert: result first type: PPCMHtml. +] + +{ #category : 'test-emphasize' } +PPCommonMarkInlineTest >> testText [ + self parse: 'foo *bar*'. + self assert: result size = 2. + self assert: result first type: PPCMText. + self assert: result second type: PPCMEmphasize. +] + +{ #category : 'test-paragraph' } +PPCommonMarkInlineTest >> testText2 [ + self parse: '*bar*'. + self assert: result first type: PPCMEmphasize. + self assert: result first text = 'bar'. + + self parse: 'foo*bar*'. + self assert: result first type: PPCMText. + self assert: result second type: PPCMEmphasize. + self assert: result first text = 'foo'. + self assert: result second text = 'bar'. +] diff --git a/software/PetitMarkdown/PPCommonMarkInlinesParser.class.st b/software/PetitMarkdown/PPCommonMarkInlinesParser.class.st new file mode 100644 index 0000000..477cc17 --- /dev/null +++ b/software/PetitMarkdown/PPCommonMarkInlinesParser.class.st @@ -0,0 +1,866 @@ +Class { + #name : 'PPCommonMarkInlinesParser', + #superclass : 'PPCompositeParser', + #instVars : [ + 'starDelimiterRun', + 'underscoreDelimiterRun', + 'space', + 'newline', + 'leftDelimiterRun', + 'rightDelimiterRun', + 'emphasize', + 'link', + 'inlineCode', + 'punctuation', + 'emphasisR1', + 'emphasisR2', + 'strongR1', + 'strongR2', + 'delimiterRunSpace', + 'delimiterRun', + 'preceedingDelimiterRunSpace', + 'followingDelimiterRunSpace', + 'escaped', + 'hexadecimalEntity', + 'decimalEntity', + 'namedEntity', + 'lt', + 'gt', + 'quot', + 'copyEntity', + 'nbsp', + 'aelig', + 'ouml', + 'dcaron', + 'amp', + 'linkRef', + 'hardBreak', + 'entity', + 'linkLabel', + 'linkDestination', + 'linkTitle', + 'lineEnd', + 'inlines', + 'linkInLabel', + 'linkLabelContent', + 'lineStart', + 'emptyLine', + 'inlineCodeStart', + 'inlineCodeEnd', + 'documentEnd', + 'line', + 'linkRefDefs', + 'softBreak', + 'autolink', + 'escapedCharacter', + 'emailAutolink', + 'normalAutolink', + 'rawHtml', + 'rawHtmlAttribute', + 'autolinkScheme', + 'openTag', + 'closeTag', + 'rawHtmlComment', + 'processingInstruction', + 'htmlDeclaration', + 'cdata' + ], + #category : 'PetitMarkdown-Parser' +} + +{ #category : 'as yet unclassified' } +PPCommonMarkInlinesParser class >> ignoredNames [ + ^ super ignoredNames , #('linkRefDefs') +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> aelig [ + ^ 'Æ' asParser + + map: [ :r | + PPCMText new + text: 'Æ' + yourself + ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> amp [ + ^ '&' asParser / '&' asParser / '\&' asParser + + map: [ :r | + PPCMText new + text: '&' + yourself + ] +] + +{ #category : 'autolinks' } +PPCommonMarkInlinesParser >> autolink [ + ^ normalAutolink / emailAutolink +] + +{ #category : 'autolinks' } +PPCommonMarkInlinesParser >> autolinkScheme [ + ^ 'http' asParser / + 'irc' asParser / + 'mailto' asParser / + 'MAILTO' asParser +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> cdata [ + ^ ('' asParser negate star), ']]>' asParser) flatten + + map: [ :_html | + PPCMHtml new + text: _html + yourself + ] +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> closeTag [ + ^ ($< asParser, + $/ asParser, + #letter asParser, + (($> asParser) whileFalse: (#word asParser)), + (space optional), $> asParser) flatten + + map: [ :_html | + PPCMHtml new + text: _html + yourself + ] +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> codeInLabel [ + | brackets | + brackets := PPDelegateParser new + name: 'brackets'; + yourself. + + brackets setParser: + (escaped not, $[ asParser, + ((inlineCode / (escaped not, $] asParser)) whileFalse: (brackets / #any asParser)), + $] asParser optional). + + "while there is no link or ] -> consume brackets or any" + ^ (brackets, inlineCode) and. +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> copyEntity [ + ^ '©' asParser + + map: [ :r | + PPCMText new + text: '©' + yourself + ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> dcaron [ + ^ 'Ď' asParser + + map: [ :r | + PPCMText new + text: 'Ď' + yourself + ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> decimalEntity [ + ^ '&#' asParser, #digit asParser plus flatten, $; asParser + + map: [ :_prefix :_number :_end | + PPCMText new + text: (Character codePoint: _number asNumber) asString; + yourself + ] +] + +{ #category : 'support' } +PPCommonMarkInlinesParser >> decodeEntities: string [ + ^ PPCommonMarkUtils instance decodeEntities: string +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> delimiterRun [ + ^ starDelimiterRun / underscoreDelimiterRun +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> delimiterRunSpace [ + ^ space / newline +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> documentEnd [ + ^ #eof asParser +] + +{ #category : 'autolinks' } +PPCommonMarkInlinesParser >> emailAutolink [ + ^ $< asParser, + ( ($> asParser / space / $\ asParser / $@ asParser) negate plus, + $@ asParser, + ($> asParser / space / $\ asParser) negate plus + ) flatten, + $> asParser + + map: [ :start :content :end | + | label | + label := PPCMText new + text: (self encodeEntities: content); + yourself. + + PPCMLink new + destination: 'mailto:', (self escapeUrl: content); + label: label; + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> emphasisR1 [ + | start stop text children | + start := (leftDelimiterRun and, $* asParser, $* asParser not) wrapped name: 'start'; yourself. + stop := (rightDelimiterRun and, $* asParser, $* asParser not) wrapped name: 'stop'; yourself. + + text := (stop / emphasize / link / inlineCode / hardBreak) negate plus flatten asPPCMText. + children := (text / emphasize / link / inlineCode / hardBreak) star. + + + ^ start, children, stop + map: [ :_start :_children :_stop | + PPCMEmphasize new + addChildren: _children; + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> emphasisR2 [ + | start stop text children | + start := (leftDelimiterRun and, + ((rightDelimiterRun not) / (punctuation preceeds, rightDelimiterRun) and), + $_ asParser, $_ asParser not) wrapped name: 'start'; yourself. + stop := (rightDelimiterRun and, + ((leftDelimiterRun not) / (leftDelimiterRun, punctuation) and), + $_ asParser, $_ asParser not) wrapped name: 'stop'; yourself. + + text := (stop / emphasize / entity) negate plus flatten asPPCMText. + children := (text / emphasize / entity) star. + + + ^ start, children, stop + map: [ :_start :_children :_stop | + PPCMEmphasize new + addChildren: _children; + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> emphasize [ + ^ emphasisR1 / + emphasisR2 / + strongR1 / + strongR2 +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> emptyLine [ + ^ space star, #endOfLine asParser ==> [ :e | + PPCMLine empty + ] +] + +{ #category : 'support' } +PPCommonMarkInlinesParser >> encodeEntities: string [ + ^ PPCommonMarkUtils instance encodeEntities: string +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> entity [ + ^ hexadecimalEntity / decimalEntity / namedEntity +] + +{ #category : 'support' } +PPCommonMarkInlinesParser >> escape: string [ + ^ PPCommonMarkUtils instance escape: string +] + +{ #category : 'support' } +PPCommonMarkInlinesParser >> escapeUrl: string [ + ^ PPCommonMarkUtils instance escapeUrl: string +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> escaped [ +" ^ ('\\' asParser preceeds: 2) not, '\' asParser preceeds" + + "Might be a bit faster version:" + ^ [ :context | + (context position == 0) ifTrue: [ PPFailure new ] ifFalse: [ + context skip: -1. + context peek == $\ ifFalse: [ context skip: 1. PPFailure new ] + ifTrue: [ + (context position == 0) ifTrue: [ context skip: 1. #escaped ] ifFalse: [ + context skip: -1. + context peek == $\ ifTrue: [ context skip: 2. PPFailure new ] + ifFalse: [ context skip: 2. #escaped ] + ] + ] + ] + ] asParser +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> escapedCharacter [ + ^ $\ asParser, ( + $\ asParser / + $[ asParser / + $! asParser / + $# asParser / + $$ asParser / + $% asParser / + $' asParser / + $( asParser / + $) asParser / + $* asParser / + $+ asParser / + $, asParser / + $+ asParser / + $- asParser / + $. asParser / + $/ asParser / + $: asParser / + $; asParser / + $= asParser / + $? asParser / + $@ asParser / + $^ asParser / + $_ asParser / + $` asParser / + ${ asParser / + $| asParser / + $} asParser / + $~ asParser / + $] asParser + ) map: [ :_escape :_char | + PPCMText new + text: _char asString; + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> followingDelimiterRunSpace [ + ^ delimiterRunSpace and / #eof asParser + +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> gt [ + ^ '>' asParser / '\>' asParser / '>' asParser + + map: [ :r | + PPCMText new + text: '>' + yourself + ] +] + +{ #category : 'newlines' } +PPCommonMarkInlinesParser >> hardBreak [ + ^ ($\ asParser, newline and) / ((space min: 2), newline and) + ==> [ :e | PPCMHardBreak new ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> hexadecimalEntity [ + ^ '&#x' asParser, (#hex asParser) plus flatten, $; asParser + + map: [ :_prefix :_number :_end | + | text char | + char := Character codePoint: (Number readFrom: _number base: 16). + text := (char = $") ifTrue: [ '"' ] ifFalse: [ char asString ]. + + PPCMText new + text: text; + yourself + ] +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> htmlDeclaration [ + ^ ('' asParser negate star), '>' asParser) flatten + + map: [ :_html | + PPCMHtml new + text: _html + yourself + ] +] + +{ #category : 'intialization' } +PPCommonMarkInlinesParser >> initialize [ + super initialize. + linkRefDefs := IdentityDictionary new. +] + +{ #category : 'code' } +PPCommonMarkInlinesParser >> inlineCode [ + ^ inlineCodeStart, inlineCodeEnd negate star flatten, inlineCodeEnd + + map: [ :_begin :_content :_end | + PPCMInlinedCode new + code: (self encodeEntities: _content); + yourself + ] +] + +{ #category : 'code' } +PPCommonMarkInlinesParser >> inlineCodeEnd [ + ^ [ :context | + context inlineCodeEnd parseOn: context + ] asParser +] + +{ #category : 'code' } +PPCommonMarkInlinesParser >> inlineCodeStart [ + ^ ((escaped / $` asParser preceeds) not, ($` asParser plus)) flatten >=> [ :context :cc | + | result | + result := cc value. + result isPetitFailure ifFalse: [ + context inlineCodeEnd: (($` asParser preceeds) not, result asParser, $` asParser not). + ]. + result + ] +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> inlines [ + ^ emphasize / inlineCode / rawHtml / autolink / link / linkRef / hardBreak / softBreak / entity / escapedCharacter +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> leftDelimiterRun [ + | a | + a := delimiterRun, delimiterRunSpace not, #any asParser and. + + ^ (a, punctuation not) / ((preceedingDelimiterRunSpace / punctuation preceeds), a) +] + +{ #category : 'as yet unclassified' } +PPCommonMarkInlinesParser >> line [ + | text | + text := inlines negate plus flatten asPPCMText. + ^ (inlines / text) star +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> lineEnd [ + ^ newline / documentEnd +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> lineStart [ + ^ #startOfLine asParser +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> link [ + ^ linkLabel, $( asParser, linkDestination optional trimSpaces, linkTitle optional trim, $) asParser + + map: [ :_label :_open :_destination :_title :_close | + PPCMLink new + label: _label; + destination: _destination; + title: _title; + yourself + ] +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkDestination [ + | parens escapedParen | + + escapedParen := '\(' asParser / '\)' asParser. + + parens := PPDelegateParser new + name: 'parens'; + yourself. + "Parens cannot be nested!" + parens setParser: $( asParser, (($( asParser / $) asParser) not, (escapedParen / #any asParser)) star, $) asParser. + + ^ (($< asParser, ((($> asParser / newline) not, #any asParser) star) flatten, $> asParser) + ==> [ :e | self escapeUrl: (self escape: e second) ]) / + ((space / lineEnd / $) asParser) not, (parens / escapedParen / $( asParser negate)) plus flatten + ==> [ :e | self escapeUrl: (self escape: e) ] +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkInLabel [ + | brackets | + brackets := PPDelegateParser new + name: 'brackets'; + yourself. + + brackets setParser: + (escaped not, $[ asParser, + ((link / (escaped not, $] asParser)) whileFalse: (brackets / #any asParser)), + $] asParser optional). + + "while there is no link or ] -> consume brackets or any" + ^ ((link / $] asParser) whileFalse: (brackets / #any asParser)), + link and. +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkInLinkLabel [ + | brackets | + brackets := PPDelegateParser new + name: 'brackets'; + yourself. + + brackets setParser: + (escaped not, $[ asParser, + ((link / (escaped not, $] asParser)) whileFalse: (brackets / #any asParser)), + $] asParser optional). + + "while there is no link or ] -> consume brackets or any" + ^ (link / $] asParser) whileFalse: (brackets / #any asParser), + link and. +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkLabel [ + | brackets labelText | + brackets := PPDelegateParser new + name: 'brackets'; + yourself. + + brackets setParser: + (escaped not, $[ asParser, + ((escaped not, $] asParser) not, (brackets / #any asParser)) plus, + $] asParser) flatten asPPCMText. + + labelText := (inlines / brackets / (escaped not, $] asParser)) negate plus flatten asPPCMText. + + ^ ((escaped not, $[ asParser) wrapped, (linkInLabel not), + (inlines / brackets / labelText) plus, + $] asParser + + + map: [ :_open :_pred :_content :_close | + | retval | + retval := PPCMLine new + addChildren: _content; + yourself. + ]) "limitedBy: linkLabelContent" +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkLabelContent [ + | brackets | + brackets := PPDelegateParser new + name: 'brackets'; + yourself. + + brackets setParser: + (escaped not, $[ asParser, + ((escaped not, $] asParser) not, (brackets / #any asParser)) plus, + $] asParser). + + ^ brackets +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkRef [ + ^ linkLabel >=> [ :context :cc | + | retval memento | + memento := context position. + + retval := cc value. + retval isPetitFailure ifFalse: [ + (linkRefDefs includesKey: retval text asString asLowercase asSymbol) ifTrue: [ + retval := PPCMLinkRef new + label: retval; + yourself + ] ifFalse: [ + context position: memento. + retval := PPFailure message: 'label not registered!' context: context + ] + ]. + retval + ] + +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> linkTitle [ + ^ ((space preceeds / lineStart), + (($" asParser, + ((escaped not, $" asParser) / (lineEnd, emptyLine)) negate plus flatten, + $" asParser ==> #second) / + ($' asParser, + ((escaped not, $' asParser) / (lineEnd, emptyLine)) negate plus flatten, + $' asParser ==> #second) / + ($( asParser, + ($) asParser / (lineEnd, emptyLine)) negate plus flatten, + $) asParser ==> #second))) + + ==> [ :e | self decodeEntities: (self escape: (e second)) ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> lt [ + ^ '<' asParser / '\<' asParser / '<' asParser + + map: [ :r | + PPCMText new + text: '<' + yourself + ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> namedEntity [ + ^ lt / gt / quot / copyEntity / nbsp / aelig / ouml / dcaron / amp +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> nbsp [ + ^ ' ' asParser + + map: [ :r | + PPCMText new + text: ' ' + yourself + ] +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> newline [ + ^ #newline asParser +] + +{ #category : 'autolinks' } +PPCommonMarkInlinesParser >> normalAutolink [ + ^ + $< asParser, + (autolinkScheme, $: asParser, + ($> asParser / space) negate plus) flatten, + $> asParser + + map: [ :start :content :end | + | label | + label := PPCMText new + text: (self encodeEntities: content); + yourself. + + PPCMLink new + destination: (self escapeUrl: content); + label: label; + yourself + ] +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> openTag [ + ^ ($< asParser, + #letter asParser, + (($> asParser) whileFalse: (#word asParser / + space / + newline / + $= asParser / + $_ asParser / + $: asParser / + rawHtmlAttribute)), + ($/ asParser optional), $> asParser) flatten + + map: [ :_html | + PPCMHtml new + text: _html + yourself + ] +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> ouml [ + ^ 'ö' asParser + + map: [ :r | + PPCMText new + text: 'ö' + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> preceedingDelimiterRunSpace [ + ^ + delimiterRunSpace preceeds / + [:context | context position == 0 ifFalse: [ + PPFailure message: 'start of file not found' ] + ifTrue: [ #startOfFile ] + ] asParser +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> processingInstruction [ + ^ ('' asParser negate star), '?>' asParser) flatten + + map: [ :_html | + PPCMHtml new + text: _html + yourself + ] +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> punctuation [ + ^ $. asParser / + $" asParser / + $, asParser / + $- asParser / + $( asParser / + $) asParser / + $] asParser +] + +{ #category : 'entities' } +PPCommonMarkInlinesParser >> quot [ + ^ '"' asParser / '\"' asParser / '"' asParser + + map: [ :r | + PPCMText new + text: '"' + yourself + ] +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> rawHtml [ + ^ closeTag / openTag / rawHtmlComment / processingInstruction / cdata / htmlDeclaration +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> rawHtmlAttribute [ + | pairedBrackets | + pairedBrackets := PPDelegateParser new name: 'brackets'; yourself. + pairedBrackets setParser: ( $< asParser, + ($> asParser whileFalse: pairedBrackets / #any asParser), + $> asParser). + + ^ + ( + ($' asParser, ($' asParser whileFalse: (pairedBrackets / #any asParser)), $' asParser) / + ($" asParser, ($" asParser whileFalse: (pairedBrackets / #any asParser)), $" asParser) + ), + (($> asParser / space / newline) and ) + +] + +{ #category : 'raw html' } +PPCommonMarkInlinesParser >> rawHtmlComment [ + ^ ('' asParser) flatten + + map: [ :_html | + PPCMHtml new + text: _html + yourself + ] +] + +{ #category : 'links' } +PPCommonMarkInlinesParser >> registerLinkRefDef: node [ + linkRefDefs at: node label asString asLowercase asSymbol + put: node +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> rightDelimiterRun [ + | a | + a := (preceedingDelimiterRunSpace not), delimiterRun. + + ^ (punctuation preceeds not, a) / (a, (punctuation and / followingDelimiterRunSpace)) +] + +{ #category : 'newlines' } +PPCommonMarkInlinesParser >> softBreak [ + ^ space optional, Character cr asParser ==> [ :e | + PPCMSoftBreak new + ] +] + +{ #category : 'lines and whitespace' } +PPCommonMarkInlinesParser >> space [ + ^ Character space asParser +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> starDelimiterRun [ + ^ ($* asParser preceeds / escaped) not, $* asParser plus +] + +{ #category : 'as yet unclassified' } +PPCommonMarkInlinesParser >> start [ + ^ line +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> strongR1 [ + | start stop text children | + start := (leftDelimiterRun and, ($* asParser, $* asParser), $* asParser not) wrapped name: 'start'; yourself. + stop := (rightDelimiterRun and, ($* asParser, $* asParser), $* asParser not) wrapped name: 'stop'; yourself. + + text := (stop / emphasize / entity) negate plus flatten asPPCMText. + children := (text / emphasize / entity) star. + + + ^ start, children, stop + map: [ :_start :_children :_stop | + PPCMStrong new + addChildren: _children; + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> strongR2 [ + | start stop text children | + start := (leftDelimiterRun and, + ((rightDelimiterRun not) / (punctuation preceeds, rightDelimiterRun) and), + ($_ asParser, $_ asParser), $_ asParser not) wrapped name: 'start'; yourself. + stop := (rightDelimiterRun and, + ((leftDelimiterRun not) / (leftDelimiterRun, punctuation) and), + ($_ asParser, $_ asParser), $_ asParser not) wrapped name: 'stop'; yourself. + + text := (stop / emphasize) negate plus flatten asPPCMText. + children := (text / emphasize) star. + + + ^ start, children, stop + map: [ :_start :_children :_stop | + PPCMStrong new + addChildren: _children; + yourself + ] +] + +{ #category : 'emphasis' } +PPCommonMarkInlinesParser >> underscoreDelimiterRun [ + ^ ($_ asParser preceeds / escaped not), $_ asParser plus +] + +{ #category : 'support' } +PPCommonMarkInlinesParser >> utils [ + ^ PPCommonMarkUtils instance +] diff --git a/software/PetitMarkdown/PPCommonMarkSpecTest.class.st b/software/PetitMarkdown/PPCommonMarkSpecTest.class.st new file mode 100644 index 0000000..03d0f4f --- /dev/null +++ b/software/PetitMarkdown/PPCommonMarkSpecTest.class.st @@ -0,0 +1,5417 @@ +Class { + #name : 'PPCommonMarkSpecTest', + #superclass : 'PPCompositeParserTest', + #instVars : [ + 'expected', + 'input', + 'ast', + 'blockParser', + 'blockAst', + 'blockVisitor', + 'htmlVisitor' + ], + #category : 'PetitMarkdown-Tests' +} + +{ #category : 'as yet unclassified' } +PPCommonMarkSpecTest >> assertExample [ + | | + "Create block structure" + blockAst := blockParser parse: input. + + "Parse inlines of block" + ast := blockAst accept: blockVisitor. + + "Generate HTML" + result := ast accept: htmlVisitor. + self assert: expected = result. + + " + (TextDiffBuilder from: expected to: result) buildDisplayPatch. + " + + +] + +{ #category : 'as yet unclassified' } +PPCommonMarkSpecTest >> setUp [ + blockVisitor := CMBlockVisitor new. + htmlVisitor := CMHTMLVisitor new. + blockParser := PPCommonMarkBlockParser new. +] + +{ #category : 'tab expansion' } +PPCommonMarkSpecTest >> testExample001 [ + input := String tab, 'foo', String tab, 'baz', String tab, String tab, 'bim'. + expected := '
    foo baz     bim
    +
    '. + + true ifTrue: [ ^ self flag: 'tabstops not yet supported' ]. + self assertExample. +] + +{ #category : 'tab expansion' } +PPCommonMarkSpecTest >> testExample002 [ + input := 'a', String tab, 'a', String cr, ' ὐ', String tab, 'a'. + expected := '
    a   a
    +ὐ   a
    +
    '. + + true ifTrue: [ ^ self flag: 'tabstops not yet supported' ]. + self assertExample. +] + +{ #category : 'precedence' } +PPCommonMarkSpecTest >> testExample003 [ + input := '- `one +- two`'. + expected := '
      +
    • `one
    • +
    • two`
    • +
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample004 [ + input := '*** +--- +___'. + expected := '
    +
    +
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample004a [ + input := '***'. + expected := '
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample005 [ + input := '+++'. + expected := '

    +++

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample006 [ + input := '==='. + expected := '

    ===

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample007 [ + input := '-- +** +__'. + expected := '

    -- +** +__

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample008 [ + input := ' *** + *** + *** +'. + expected := '
    +
    +
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample009 [ + input := ' ***'. + expected := '
    ***
    +
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample010 [ + input := 'Foo + ***'. + expected := '

    Foo +***

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample011 [ + input := '_____________________________________'. + expected := '
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample012 [ + input := ' - - -'. + expected := '
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample013 [ + input := ' ** * ** * ** * **'. + expected := '
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample014 [ + input := '- - - -'. + expected := '
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample015 [ + input := '- - - - '. + expected := '
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample016 [ + input := '_ _ _ _ a + +a------ + +---a--- +'. + expected := '

    _ _ _ _ a

    +

    a------

    +

    ---a---

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample017 [ + input := ' *-*'. + expected := '-'. + + self flag: 'updated:'. + expected := '

    -

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample018 [ + input := '- foo +*** +- bar'. + expected := '
      +
    • foo
    • +
    +
    +
      +
    • bar
    • +
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample019 [ + input := 'Foo +*** +bar'. + expected := '

    Foo

    +
    +

    bar

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample020 [ + input := 'Foo +--- +bar'. + expected := '

    Foo

    +

    bar

    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample021 [ + input := '* Foo +* * * +* Bar'. + + expected := '
      +
    • Foo
    • +
    +
    +
      +
    • Bar
    • +
    '. + + self assertExample. +] + +{ #category : 'horizontal rules' } +PPCommonMarkSpecTest >> testExample022 [ + input := '- Foo +- * * *'. + + expected := '
      +
    • Foo
    • +
    • +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample023 [ + input := '# foo +## foo +### foo +#### foo +##### foo +###### foo'. + + expected := '

    foo

    +

    foo

    +

    foo

    +

    foo

    +
    foo
    +
    foo
    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample024 [ + input := '####### foo'. + + expected := '

    ####### foo

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample025 [ + input := '#5 bolt'. + + expected := '

    #5 bolt

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample026 [ + input := '\## foo'. + + expected := '

    ## foo

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample027 [ + input := '# foo *bar* \*baz\*'. + + expected := '

    foo bar *baz*

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample028 [ + input := '# foo '. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample029 [ + input := ' ### foo + ## foo + # foo'. + + expected := '

    foo

    +

    foo

    +

    foo

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample030 [ + input := ' # foo'. + + expected := '
    # foo
    +
    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample031 [ + input := 'foo + # bar'. + + expected := '

    foo +# bar

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample032 [ + input := '## foo ## + ### bar ###'. + + expected := '

    foo

    +

    bar

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample033 [ + input := '# foo ################################## +##### foo ##'. + + expected := '

    foo

    +
    foo
    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample034 [ + input := '### foo ### '. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample035 [ + input := '### foo ### b'. + + expected := '

    foo ### b

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample036 [ + input := '# foo#'. + + expected := '

    foo#

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample037 [ + input := '### foo \### +## foo #\## +# foo \#'. + + expected := '

    foo ###

    +

    foo ###

    +

    foo #

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample038 [ + input := '**** +## foo +****'. + + expected := '
    +

    foo

    +
    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample039 [ + input := 'Foo bar +# baz +Bar foo'. + + expected := '

    Foo bar

    +

    baz

    +

    Bar foo

    '. + + self assertExample. +] + +{ #category : 'ATX Headers' } +PPCommonMarkSpecTest >> testExample040 [ + input := '## +# +### ###'. + + expected := '

    +

    +

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample041 [ + input := 'Foo *bar* +========= + +Foo *bar* +---------'. + + expected := '

    Foo bar

    +

    Foo bar

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample042 [ + input := 'Foo +------------------------- + +Foo +='. + + expected := '

    Foo

    +

    Foo

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample043 [ + input := ' Foo +--- + + Foo +----- + + Foo + ==='. + + expected := '

    Foo

    +

    Foo

    +

    Foo

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample044 [ + input := ' Foo + --- + + Foo +---'. + + expected := '
    Foo
    +---
    +
    +Foo
    +
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample045 [ + input := 'Foo + ---- '. + + expected := '

    Foo

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample046 [ + input := 'Foo + ---'. + + expected := '

    Foo +---

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample047 [ + input := 'Foo += = + +Foo +--- - +'. + + expected := '

    Foo += =

    +

    Foo

    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample048 [ + input := 'Foo +-----'. + + expected := '

    Foo

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample049 [ + input := 'Foo\ +----'. + + expected := '

    Foo\

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample050 [ + input := '`Foo +---- +` + +'. + + expected := '

    `Foo

    +

    `

    +

    <a title="a lot

    +

    of dashes"/>

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample051 [ + input := '> Foo +---'. + + expected := '
    +

    Foo

    +
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample052 [ + input := '- Foo +---'. + + expected := '
      +
    • Foo
    • +
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample053 [ + input := 'Foo +Bar +--- + +Foo +Bar +==='. + + expected := '

    Foo +Bar

    +
    +

    Foo +Bar +===

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample054 [ + input := '--- +Foo +--- +Bar +--- +Baz'. + + expected := '
    +

    Foo

    +

    Bar

    +

    Baz

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample055 [ + input := ' +===='. + + expected := '

    ====

    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample056 [ + input := '--- +---'. + + expected := '
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample057 [ + input := '- foo +-----'. + + expected := '
      +
    • foo
    • +
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample058 [ + input := ' foo +---'. + + expected := '
    foo
    +
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample059 [ + input := '> foo +-----'. + + expected := '
    +

    foo

    +
    +
    '. + + self assertExample. +] + +{ #category : 'setext headears' } +PPCommonMarkSpecTest >> testExample060 [ + input := '\> foo +------'. + + expected := '

    > foo

    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample061 [ + input := ' a simple + indented code block'. + + expected := '
    a simple
    +  indented code block
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample062 [ + input := '
    + *hi* + + - one'. + + expected := '
    <a/>
    +*hi*
    +
    +- one
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample063 [ + input := ' chunk1 + + chunk2 + + + + chunk3'. + + expected := '
    chunk1
    +
    +chunk2
    +
    +
    +
    +chunk3
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample064 [ + input := ' chunk1 + + chunk2'. + + expected := '
    chunk1
    +  
    +  chunk2
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample065 [ + input := 'Foo + bar'. + + expected := '

    Foo +bar

    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample066 [ + input := ' foo +bar'. + + expected := '
    foo
    +
    +

    bar

    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample067 [ + input := '# Header + foo +Header +------ + foo +----'. + + expected := '

    Header

    +
    foo
    +
    +

    Header

    +
    foo
    +
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample068 [ + input := ' foo + bar'. + + expected := '
        foo
    +bar
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample069 [ + input := ' + + foo + '. + + expected := '
    foo
    +
    '. + + self assertExample. +] + +{ #category : 'indented code blocks' } +PPCommonMarkSpecTest >> testExample070 [ + input := ' foo +'. + + expected := '
    foo  
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample071 [ + input := '``` +< + > +```'. + + expected := '
    <
    + >
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample072 [ + input := '~~~ +< + > +~~~'. + + expected := '
    <
    + >
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample073 [ + input := '``` +aaa +~~~ +```'. + + expected := '
    aaa
    +~~~
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample074 [ + input := '~~~ +aaa +``` +~~~'. + + expected := '
    aaa
    +```
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample075 [ + input := '```` +aaa +``` +``````'. + + expected := '
    aaa
    +```
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample076 [ + input := '~~~~ +aaa +~~~ +~~~~'. + + expected := '
    aaa
    +~~~
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample077 [ + input := '```'. + + expected := '
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample078 [ + input := ' + +````` + +``` +aaa +'. + + expected := '
    
    +```
    +aaa
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample079 [ + input := '``` + + +``` +'. + + expected := '
    
    +  
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample080 [ + input := '``` +```'. + + expected := '
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample081 [ + input := ' ``` + aaa +aaa +```'. + + expected := '
    aaa
    +aaa
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample082 [ + input := ' ``` +aaa + aaa +aaa + ```'. + + expected := '
    aaa
    +aaa
    +aaa
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample083 [ + input := ' ``` + aaa + aaa + aaa + ```'. + + expected := '
    aaa
    + aaa
    +aaa
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample084 [ + input := ' ``` + aaa + ```'. + + expected := '
    ```
    +aaa
    +```
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample085 [ + input := '``` +aaa + ```'. + + expected := '
    aaa
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample086 [ + input := ' ``` +aaa + ```'. + + expected := '
    aaa
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample087 [ + input := '``` +aaa + ```'. + + expected := '
    aaa
    +    ```
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample088 [ + input := '``` ``` +aaa'. + + expected := '

    +aaa

    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample089 [ + input := '~~~~~~ +aaa +~~~ ~~'. + + expected := '
    aaa
    +~~~ ~~
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample090 [ + input := 'foo +``` +bar +``` +baz'. + + expected := '

    foo

    +
    bar
    +
    +

    baz

    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample091 [ + input := 'foo +--- +~~~ +bar +~~~ +# baz'. + + expected := '

    foo

    +
    bar
    +
    +

    baz

    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample092 [ + input := '```ruby +def foo(x) + return 3 +end +```'. + + expected := '
    def foo(x)
    +  return 3
    +end
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample093 [ + input := '~~~~ ruby startline=3 $%@#$ +def foo(x) + return 3 +end +~~~~~~~'. + + expected := '
    def foo(x)
    +  return 3
    +end
    +
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample094 [ + input := '````; +````'. + + expected := '
    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample095 [ + input := '``` aa ``` +foo'. + + expected := '

    aa +foo

    '. + + self assertExample. +] + +{ #category : 'fenced code blocks' } +PPCommonMarkSpecTest >> testExample096 [ + input := '``` +``` aaa +```'. + + expected := '
    ``` aaa
    +
    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample097 [ + input := ' + + + +
    + hi +
    + +okay.'. + + expected := ' + + + +
    + hi +
    +

    okay.

    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample098 [ + input := '
    + *hello* + +'. + + expected := '
    + *hello* + '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample099 [ + input := '
    + +*Markdown* + +
    '. + + expected := '
    +

    Markdown

    +
    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample100 [ + input := '
    +``` c +int x = 33; +```'. + + expected := '
    +``` c +int x = 33; +```'. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample101 [ + input := ''. + + expected := ''. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample102 [ + input := '''; +?>'. + + expected := '''; +?>'. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample103 [ + input := ''. + + expected := ''. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample104 [ + input := ' + + '. + + expected := ' +
    <!-- foo -->
    +
    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample105 [ + input := 'Foo +
    +bar +
    '. + + expected := '

    Foo

    +
    +bar +
    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample106 [ + input := '
    +bar +
    +*foo*'. + + expected := '
    +bar +
    +*foo*'. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample107 [ + input := '
    > testExample108 [ + input := '
    + +*Emphasized* text. + +
    '. + + expected := '
    +

    Emphasized text.

    +
    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample109 [ + input := '
    +*Emphasized* text. +
    '. + + expected := '
    +*Emphasized* text. +
    '. + + self assertExample. +] + +{ #category : 'html blocks' } +PPCommonMarkSpecTest >> testExample110 [ + input := ' + + + + + + + +
    +Hi +
    '. + + expected := ' + + + +
    +Hi +
    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample111 [ + input := '[foo]: /url "title" + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample112 [ + input := ' [foo]: + /url + ''the title'' + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample113 [ + input := '[Foo*bar\]]:my_(url) ''title (with parens)'' + +[Foo*bar\]]'. + + expected := '

    Foo*bar]

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample114 [ + input := '[Foo bar]: + +''title'' + +[Foo bar]'. + + expected := '

    Foo bar

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample115 [ + input := '[foo]: /url '' +title +line1 +line2 +'' + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample116 [ + input := '[foo]: /url ''title + +with blank line'' + +[foo]'. + + expected := '

    [foo]: /url ''title

    +

    with blank line''

    +

    [foo]

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample117 [ + input := '[foo]: +/url + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample118 [ + input := '[foo]: + +[foo]'. + + expected := '

    [foo]:

    +

    [foo]

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample119 [ + input := '[foo] + +[foo]: url'. + + expected := '[foo] + +[foo]: url'. + + true ifTrue: [ ^ self flag: 'links before definitions not yet supported' ]. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample120 [ + input := '[foo]: first +[foo]: second + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample121 [ + input := '[FOO]: /url + +[Foo]'. + + expected := '

    Foo

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample122 [ + input := '[ΑΓΩ]: /φου + +[αγω]'. + + expected := '

    αγω

    '. + true ifTrue: [ ^ self flag: 'escaping not yet supported...' ]. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample122a [ + input := '[ΑΓΩ]: /foo + +[αγω]'. + + expected := '

    αγω

    '. + + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample123 [ + input := '[foo]: /url'. + + expected := ''. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample124 [ + input := '[ +foo +]: /url +bar'. + + expected := '

    bar

    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample125 [ + input := '[foo]: /url "title" ok'. + + expected := '

    [foo]: /url "title" ok

    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample126 [ + input := ' [foo]: /url "title" + +[foo]'. + + expected := '
    [foo]: /url "title"
    +
    +

    [foo]

    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample127 [ + input := '``` +[foo]: /url +``` + +[foo] +'. + + expected := '
    [foo]: /url
    +
    +

    [foo]

    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample128 [ + input := 'Foo +[bar]: /baz + +[bar]'. + + expected := '

    Foo +[bar]: /baz

    +

    [bar]

    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample129 [ + input := '# [Foo] +[foo]: /url +> bar'. + + expected := '

    Foo

    +
    +

    bar

    +
    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample129a [ + input := '[foo]: /url +# [Foo] +> bar'. + + expected := '

    Foo

    +
    +

    bar

    +
    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample130 [ + input := '[foo]: /foo-url "foo" +[bar]: /bar-url + "bar" +[baz]: /baz-url + +[foo], +[bar], +[baz]'. + + expected := '

    foo, +bar, +baz

    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample131 [ + input := '[foo] + +> [foo]: /url'. + + expected := '

    foo

    +
    +
    '. + self assertExample. +] + +{ #category : 'link references' } +PPCommonMarkSpecTest >> testExample131a [ + input := '> [foo]: /url +[foo]'. + + expected := '
    +
    +

    foo

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample132 [ + input := 'aaa + +bbb'. + + expected := '

    aaa

    +

    bbb

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample133 [ + input := 'aaa +bbb + +ccc +ddd'. + + expected := '

    aaa +bbb

    +

    ccc +ddd

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample134 [ + input := 'aaa + + +bbb'. + + expected := '

    aaa

    +

    bbb

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample135 [ + input := ' aaa + bbb'. + + expected := '

    aaa +bbb

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample136 [ + input := 'aaa + bbb + ccc'. + + expected := '

    aaa +bbb +ccc

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample137 [ + input := ' aaa +bbb'. + + expected := '

    aaa +bbb

    '. + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample138 [ + input := ' aaa +bbb'. + + expected := '
    aaa
    +
    +

    bbb

    '. + + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testExample139 [ + input := 'aaa +bbb '. + + expected := '

    aaa
    +bbb

    '. + + self assertExample. +] + +{ #category : 'blank lines' } +PPCommonMarkSpecTest >> testExample140 [ + input := ' + +aaa + + +# aaa + + +'. + + expected := '

    aaa

    +

    aaa

    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample141 [ + input := '> # Foo +> bar +> baz'. + + expected := '
    +

    Foo

    +

    bar +baz

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample142 [ + input := '># Foo +>bar +> baz'. + + expected := '
    +

    Foo

    +

    bar +baz

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample143 [ + input := ' > # Foo + > bar + > baz'. + + expected := '
    +

    Foo

    +

    bar +baz

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample144 [ + input := ' > # Foo + > bar + > baz'. + + expected := '
    > # Foo
    +> bar
    +> baz
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample145 [ + input := '> # Foo +> bar +baz'. + + expected := '
    +

    Foo

    +

    bar +baz

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample146 [ + input := '> bar +baz +> foo'. + + expected := '
    +

    bar +baz +foo

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample147 [ + input := '> foo +---'. + + expected := '
    +

    foo

    +
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample148 [ + input := '> - foo +- bar'. + + expected := '
    +
      +
    • foo
    • +
    +
    +
      +
    • bar
    • +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample149 [ + input := '> foo + bar'. + + expected := '
    +
    foo
    +
    +
    +
    bar
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample150 [ + input := '> ``` +foo +```'. + + expected := '
    +
    +
    +

    foo

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample151 [ + input := '>'. + + expected := '
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample152 [ + input := '> +> +> '. + + expected := '
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample153 [ + input := '> +> foo +> '. + + expected := '
    +

    foo

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample154 [ + input := '> foo + +> bar'. + + expected := '
    +

    foo

    +
    +
    +

    bar

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample155 [ + input := '> foo +> bar'. + + expected := '
    +

    foo +bar

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample156 [ + input := '> foo +> +> bar'. + + expected := '
    +

    foo

    +

    bar

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample157 [ + input := 'foo +> bar'. + + expected := '

    foo

    +
    +

    bar

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample158 [ + input := '> aaa +*** +> bbb'. + + expected := '
    +

    aaa

    +
    +
    +
    +

    bbb

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample159 [ + input := '> bar +baz'. + + expected := '
    +

    bar +baz

    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample160 [ + input := '> bar + +baz'. + + expected := '
    +

    bar

    +
    +

    baz

    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample161 [ + input := '> bar +> +baz'. + + expected := '
    +

    bar

    +
    +

    baz

    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample162 [ + input := '> > > foo +bar'. + + expected := '
    +
    +
    +

    foo +bar

    +
    +
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample163 [ + input := '>>> foo +> bar +>>baz'. + + expected := '
    +
    +
    +

    foo +bar +baz

    +
    +
    +
    '. + + self assertExample. +] + +{ #category : 'block quotes' } +PPCommonMarkSpecTest >> testExample164 [ + input := '> code + +> not code'. + + expected := '
    +
    code
    +
    +
    +
    +

    not code

    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample165 [ + input := 'A paragraph +with two lines. + + indented code + +> A block quote.'. + + expected := '

    A paragraph +with two lines.

    +
    indented code
    +
    +
    +

    A block quote.

    +
    '. + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample166 [ + input := '1. A paragraph + with two lines. + + indented code + + > A block quote.'. + + expected := '
      +
    1. +

      A paragraph +with two lines.

      +
      indented code
      +
      +
      +

      A block quote.

      +
      +
    2. +
    '. + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample167 [ + input := '- one + + two'. + + expected := '
      +
    • one
    • +
    +

    two

    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample168 [ + input := '- one + + two'. + + expected := '
      +
    • +

      one

      +

      two

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample169 [ + input := ' - one + + two'. + + expected := '
      +
    • one
    • +
    +
     two
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample170 [ + input := ' - one + + two'. + + expected := '
      +
    • +

      one

      +

      two

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample171 [ + input := ' > > 1. one +>> +>> two'. + + expected := '
    +
    +
      +
    1. +

      one

      +

      two

      +
    2. +
    +
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample172 [ + input := '>>- one +>> + > > two'. + + expected := '
    +
    +
      +
    • one
    • +
    +

    two

    +
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample173 [ + input := '-one + +2.two'. + + expected := '

    -one

    +

    2.two

    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample174 [ + input := '- foo + + bar + +- foo + + + bar + +- ``` + foo + + + bar + ``` + +- baz + + + ``` + foo + + + bar + ```'. + + expected := '
      +
    • +

      foo

      +

      bar

      +
    • +
    • +

      foo

      +
    • +
    +

    bar

    +
      +
    • +
      foo
      +
      +
      +bar
      +
      +
    • +
    • +

      baz

      +
        +
      • +
        foo
        +
        +
        +bar
        +
        +
      • +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample175 [ + input := '1. foo + + ``` + bar + ``` + + baz + + > bam'. + + expected := '
      +
    1. +

      foo

      +
      bar
      +
      +

      baz

      +
      +

      bam

      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample176 [ + input := '- foo + + bar'. + + expected := '
      +
    • +

      foo

      +
      bar
      +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample177 [ + input := ' + + 10. foo + + bar'. + + expected := '
      +
    1. +

      foo

      +
      bar
      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample178 [ + input := ' indented code + +paragraph + + more code'. + + expected := '
    indented code
    +
    +

    paragraph

    +
    more code
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample179 [ + input := '1. indented code + + paragraph + + more code'. + + expected := '
      +
    1. +
      indented code
      +
      +

      paragraph

      +
      more code
      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample180 [ + input := '1. indented code + + paragraph + + more code'. + + expected := '
      +
    1. +
       indented code
      +
      +

      paragraph

      +
      more code
      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample181 [ + input := ' foo + +bar'. + + expected := '

    foo

    +

    bar

    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample182 [ + input := '- foo + + bar'. + + expected := '
      +
    • foo
    • +
    +

    bar

    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample183 [ + input := '- foo + + bar'. + + expected := '
      +
    • +

      foo

      +

      bar

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample184 [ + input := '- + foo +- + ``` + bar + ``` +- + baz'. + + expected := '
      +
    • foo
    • +
    • +
      bar
      +
      +
    • +
    • +
      baz
      +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample185 [ + input := '- foo +- +- bar'. + + expected := '
      +
    • foo
    • +
    • +
    • bar
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample186 [ + input := '- foo +- +- bar'. + + expected := '
      +
    • foo
    • +
    • +
    • bar
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample187 [ + input := '1. foo +2. +3. bar'. + + expected := '
      +
    1. foo
    2. +
    3. +
    4. bar
    5. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample188 [ + input := '*'. + + expected := '
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample189 [ + input := ' 1. A paragraph + with two lines. + + indented code + + > A block quote.'. + + expected := '
      +
    1. +

      A paragraph +with two lines.

      +
      indented code
      +
      +
      +

      A block quote.

      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample190 [ + input := ' 1. A paragraph + with two lines. + + indented code + + > A block quote.'. + + expected := '
      +
    1. +

      A paragraph +with two lines.

      +
      indented code
      +
      +
      +

      A block quote.

      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample191 [ + input := ' 1. A paragraph + with two lines. + + indented code + + > A block quote.'. + + expected := '
      +
    1. +

      A paragraph +with two lines.

      +
      indented code
      +
      +
      +

      A block quote.

      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample192 [ + input := ' 1. A paragraph + with two lines. + + indented code + + > A block quote.'. + + expected := '
    1.  A paragraph
    +    with two lines.
    +
    +        indented code
    +
    +    > A block quote.
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample193 [ + input := ' 1. A paragraph +with two lines. + + indented code + + > A block quote.'. + + expected := '
      +
    1. +

      A paragraph +with two lines.

      +
      indented code
      +
      +
      +

      A block quote.

      +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample194 [ + input := ' 1. A paragraph + with two lines.'. + + expected := '
      +
    1. A paragraph +with two lines.
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample195 [ + input := '> 1. > Blockquote +continued here.'. + + expected := '
    +
      +
    1. +
      +

      Blockquote +continued here.

      +
      +
    2. +
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample196 [ + input := '> 1. > Blockquote +> continued here.'. + + expected := '
    +
      +
    1. +
      +

      Blockquote +continued here.

      +
      +
    2. +
    +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample197 [ + input := '- foo + - bar + - baz'. + + expected := '
      +
    • foo +
        +
      • bar +
          +
        • baz
        • +
        +
      • +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample198 [ + input := '- foo + - bar + - baz'. + + expected := '
      +
    • foo
    • +
    • bar
    • +
    • baz
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample199 [ + input := '10) foo + - bar'. + + expected := '
      +
    1. foo +
        +
      • bar
      • +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample200 [ + input := '10) foo + - bar'. + + expected := '
      +
    1. foo
    2. +
    +
      +
    • bar
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample201 [ + input := '- - foo'. + + expected := '
      +
    • +
        +
      • foo
      • +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample202 [ + input := '1. - 2. foo'. + + expected := '
      +
    1. +
        +
      • +
          +
        1. foo
        2. +
        +
      • +
      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'list items' } +PPCommonMarkSpecTest >> testExample203 [ + input := '- # Foo +- Bar + --- + baz'. + + expected := '
      +
    • +

      Foo

      +
    • +
    • +

      Bar

      baz
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample204 [ + input := '- foo +- bar ++ baz'. + + expected := '
      +
    • foo
    • +
    • bar
    • +
    +
      +
    • baz
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample205 [ + input := '1. foo +2. bar +3) baz'. + + expected := '
      +
    1. foo
    2. +
    3. bar
    4. +
    +
      +
    1. baz
    2. +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample206 [ + input := 'Foo +- bar +- baz'. + + expected := '

    Foo

    +
      +
    • bar
    • +
    • baz
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample207 [ + input := 'The number of windows in my house is +14. The number of doors is 6.'. + + expected := '

    The number of windows in my house is

    +
      +
    1. The number of doors is 6.
    2. +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample208 [ + input := '- foo + +- bar + + +- baz'. + + expected := '
      +
    • +

      foo

      +
    • +
    • +

      bar

      +
    • +
    +
      +
    • baz
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample209 [ + input := '- foo + + + bar +- baz'. + + expected := '
      +
    • foo
    • +
    +

    bar

    +
      +
    • baz
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample210 [ + input := '- foo + - bar + - baz + + + bim'. + + expected := '
      +
    • foo +
        +
      • bar +
          +
        • baz
        • +
        +
      • +
      +
    • +
    +
      bim
    +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample211 [ + input := '- foo +- bar + + +- baz +- bim'. + + expected := '
      +
    • foo
    • +
    • bar
    • +
    +
      +
    • baz
    • +
    • bim
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample212 [ + input := '- foo + + notcode + +- foo + + + code'. + + expected := '
      +
    • +

      foo

      +

      notcode

      +
    • +
    • +

      foo

      +
    • +
    +
    code
    +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample213 [ + input := '- a + - b + - c + - d + - e + - f +- g +'. + + expected := '
      +
    • a
    • +
    • b
    • +
    • c
    • +
    • d
    • +
    • e
    • +
    • f
    • +
    • g
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample214 [ + input := '- a +- b + +- c'. + + expected := '
      +
    • +

      a

      +
    • +
    • +

      b

      +
    • +
    • +

      c

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample215 [ + input := '* a +* + +* c'. + + expected := '
      +
    • +

      a

      +
    • +
    • +
    • +

      c

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample216 [ + input := '- a +- b + + c +- d'. + + expected := '
      +
    • +

      a

      +
    • +
    • +

      b

      +

      c

      +
    • +
    • +

      d

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample217 [ + input := ' + +- a +- b + + [ref]: /url +- d'. + + expected := '
      +
    • +

      a

      +
    • +
    • +

      b

      +
    • +
    • +

      d

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample218 [ + input := '- a +- ``` + b + + + ``` +- c'. + + expected := '
      +
    • a
    • +
    • +
      b
      +
      +
      +
      +
    • +
    • c
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample219 [ + input := '- a + - b + + c +- d'. + + expected := '
      +
    • a +
        +
      • +

        b

        +

        c

        +
      • +
      +
    • +
    • d
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample220 [ + input := '* a + > b + > +* c'. + + expected := '
      +
    • a +
      +

      b

      +
      +
    • +
    • c
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample221 [ + input := '- a + > b + ``` + c + ``` +- d'. + + expected := '
      +
    • a +
      +

      b

      +
      +
      c
      +
      +
    • +
    • d
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample222 [ + input := '- a'. + + expected := '
      +
    • a
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample223 [ + input := '- a + - b'. + + expected := '
      +
    • a +
        +
      • b
      • +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample224 [ + input := '1. ``` + foo + ``` + + bar'. + + expected := '
      +
    1. +
      foo
      +
      +

      bar

      +
    2. +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample225 [ + input := '* foo + * bar + + baz'. + + expected := '
      +
    • +

      foo

      +
        +
      • bar
      • +
      +

      baz

      +
    • +
    '. + + self assertExample. +] + +{ #category : 'lists' } +PPCommonMarkSpecTest >> testExample226 [ + input := '- a + - b + - c + +- d + - e + - f'. + + expected := '
      +
    • +

      a

      +
        +
      • b
      • +
      • c
      • +
      +
    • +
    • +

      d

      +
        +
      • e
      • +
      • f
      • +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample227 [ + input := '`hi`lo`'. + + expected := '

    hilo`

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample228 [ + input := '\!\"\#\$\%\&\''\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~'. + + expected := '

    !"#$%&''()*+,-./:;<=>?@[\]^_`{|}~

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample229 [ + input := '\A\a\ \3\φ\«'. + + expected := '

    \A\a\ \3\φ\«

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample230 [ + input := '\*not emphasized* +\
    not a tag +\[not a link](/foo) +\`not code` +1\. not a list +\* not a list +\# not a header +\[foo]: /url "not a reference"'. + + expected := '

    *not emphasized* +<br/> not a tag +[not a link](/foo) +`not code` +1. not a list +* not a list +# not a header +[foo]: /url "not a reference"

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample231 [ + input := '\\*emphasis*'. + + expected := '

    \emphasis

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample232 [ + input := 'foo\ +bar'. + + expected := '

    foo
    +bar

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample233 [ + input := '`` \[\` ``'. + + expected := '

    \[\`

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample234 [ + input := ' \[\]'. + + expected := '
    \[\]
    +
    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample235 [ + input := '~~~ +\[\] +~~~'. + + expected := '
    \[\]
    +
    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample236 [ + input := ''. + + expected := '

    http://example.com?find=\*

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample237 [ + input := ''. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample238 [ + input := '[foo](/bar\* "ti\*tle")'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample239 [ + input := '[foo] + +[foo]: /bar\* "ti\*tle"'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample239a [ + input := '[foo]: /bar\* "ti\*tle" + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'backslash escapes' } +PPCommonMarkSpecTest >> testExample240 [ + input := '``` foo\+bar +foo +```'. + + expected := '
    foo
    +
    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample241 [ + input := '  & © Æ Ď'. + expected := '

    & © Æ Ď

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample242 [ + input := '# Ӓ Ϡ'. + expected := '

    # Ӓ Ϡ

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample243 [ + input := '" ആ ಫ'. + expected := '

    " ആ ಫ

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample244 [ + input := '  &x; &#; &#x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;'. + + expected := '

    &nbsp &x; &#; &#x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample245 [ + input := '©'. + + expected := '

    &copy

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample246 [ + input := '&MadeUpEntity;'. + + expected := '

    &MadeUpEntity;

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample247 [ + input := ''. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample248 [ + input := '[foo](/föö "föö")'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample249 [ + input := '[foo] + +[foo]: /föö "föö"'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample249a [ + input := '[foo]: /föö "föö" + +[foo]'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample250 [ + input := '``` föö +foo +```'. + + expected := '
    foo
    +
    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample251 [ + input := '`föö`'. + + expected := '

    f&ouml;&ouml;

    '. + + self assertExample. +] + +{ #category : 'entitites' } +PPCommonMarkSpecTest >> testExample252 [ + input := ' föfö'. + + expected := '
    f&ouml;f&ouml;
    +
    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample253 [ + input := '`foo`'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample254 [ + input := '`` foo ` bar ``'. + + expected := '

    foo ` bar

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample255 [ + input := '` `` `'. + + expected := '

    ``

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample256 [ + input := '`` +foo +``'. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample257 [ + input := '`foo bar + baz`'. + + expected := '

    foo bar baz

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample258 [ + input := '`foo `` bar`'. + + expected := '

    foo `` bar

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample259 [ + input := '`foo\`bar`'. + + expected := '

    foo\bar`

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample260 [ + input := '*foo`*`'. + + expected := '

    *foo*

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample261 [ + input := '[not a `link](/foo`)'. + + expected := '

    [not a link](/foo)

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample262 [ + input := '``'. + + expected := '

    <a href="">`

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample263 [ + input := '
    `'. + + expected := '

    `

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample264 [ + + input := '``'. + + expected := '

    <http://foo.bar.baz>`

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample265 [ + + input := '`'. + + expected := '

    http://foo.bar.`baz`

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample266 [ + + input := '```foo``'. + + expected := '

    ```foo``

    '. + + self assertExample. +] + +{ #category : 'code spans' } +PPCommonMarkSpecTest >> testExample267 [ + + input := '`foo'. + + expected := '

    `foo

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample268 [ + + input := '*foo bar*'. + + expected := '

    foo bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample269 [ + + input := 'a * foo bar*'. + + expected := '

    a * foo bar*

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample270 [ + + input := 'a*"foo"*'. + + expected := '

    a*"foo"*

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample271 [ + + input := '* a *'. + + expected := '

    * a *

    '. + + true ifTrue: [ ^ self flag: 'bad example? this is a list...' ]. + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample272 [ + + input := 'foo*bar*'. + + expected := '

    foobar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample273 [ + + input := '5*6*78'. + + expected := '

    5678

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample274 [ + + input := '_foo bar_'. + + expected := '

    foo bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample275 [ + + input := '_ foo bar_'. + + expected := '

    _ foo bar_

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample276 [ + + input := 'a_"foo"_'. + + expected := '

    a_"foo"_

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample277 [ + + input := 'foo_bar_'. + + expected := '

    foo_bar_

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample278 [ + + input := '5_6_78'. + + expected := '

    5_6_78

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample279 [ + + input := 'пристаням_стремятся_'. + + expected := '

    пристаням_стремятся_

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample280 [ + + input := 'aa_"bb"_cc'. + + expected := '

    aa_"bb"_cc

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample281 [ + + input := 'foo-_(bar)_'. + + expected := '

    foo-(bar)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample282 [ + + input := '_foo*'. + + expected := '

    _foo*

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample283 [ + + input := '*foo bar *'. + + expected := '

    *foo bar *

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample284 [ + + input := '*foo bar +*'. + + expected := '

    *foo bar

    +
      +
    • +
    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample285 [ + + input := '*(*foo)'. + + expected := '

    *(*foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample286 [ + + input := '*(*foo*)*'. + + expected := '

    (foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample287 [ + + input := '*foo*bar'. + + expected := '

    foobar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample288 [ + + input := '_foo bar _'. + + expected := '

    _foo bar _

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample289 [ + + input := '_(_foo)'. + + expected := '

    _(_foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample290 [ + + input := '_(_foo_)_'. + + expected := '

    (foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample291 [ + + input := '_foo_bar'. + + expected := '

    _foo_bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample292 [ + + input := '_пристаням_стремятся'. + + expected := '

    _пристаням_стремятся

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample293 [ + + input := '_foo_bar_baz_'. + + expected := '

    foo_bar_baz

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample294 [ + + input := '_(bar)_.'. + + expected := '

    (bar).

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample295 [ + + input := '**foo bar**'. + + expected := '

    foo bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample296 [ + + input := '** foo bar**'. + + expected := '

    ** foo bar**

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample297 [ + + input := 'a**"foo"**'. + + expected := '

    a**"foo"**

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample298 [ + + input := 'foo**bar**'. + + expected := '

    foobar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample299 [ + + input := '__foo bar__'. + + expected := '

    foo bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample300 [ + + input := '__ foo bar__'. + + expected := '

    __ foo bar__

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample301 [ + + input := '__ +foo bar__'. + + expected := '

    __ +foo bar__

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample302 [ + + input := 'a__"foo"__'. + + expected := '

    a__"foo"__

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample303 [ + + input := 'foo__bar__'. + + expected := '

    foo__bar__

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample304 [ + + input := '5__6__78'. + + expected := '

    5__6__78

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample305 [ + + input := 'пристаням__стремятся__'. + + expected := '

    пристаням__стремятся__

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample306 [ + + input := '__foo, __bar__, baz__'. + + expected := '

    foo, bar, baz

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample307 [ + + input := 'foo-_(bar)_'. + + expected := '

    foo-(bar)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample308 [ + + input := '**foo bar **'. + + expected := '

    **foo bar **

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample309 [ + + input := '**(**foo)'. + + expected := '

    **(**foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample310 [ + + input := '*(**foo**)*'. + + expected := '

    (foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample311 [ + + input := '**Gomphocarpus (*Gomphocarpus physocarpus*, syn. +*Asclepias physocarpa*)**'. + + expected := '

    Gomphocarpus (Gomphocarpus physocarpus, syn. +Asclepias physocarpa)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample312 [ + + input := '**foo "*bar*" foo**'. + + expected := '

    foo "bar" foo

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample313 [ + + input := '**foo**bar'. + + expected := '

    foobar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample314 [ + input := '__foo bar __'. + + expected := '

    __foo bar __

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample315 [ + input := '__(__foo)'. + + expected := '

    __(__foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample316 [ + input := '_(__foo__)_'. + + expected := '

    (foo)

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample317 [ + input := '__foo__bar'. + + expected := '

    __foo__bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample318 [ + input := '__пристаням__стремятся'. + + expected := '

    __пристаням__стремятся

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample319 [ + input := '__foo__bar__baz__'. + + expected := '

    foo__bar__baz

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample320 [ + input := '_(bar)_.'. + + expected := '

    (bar).

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample321 [ + input := '*foo [bar](/url)*'. + + expected := '

    foo bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample322 [ + input := '*foo +bar*'. + + expected := '

    foo +bar

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample323 [ + input := '_foo __bar__ baz_'. + + expected := '

    foo bar baz

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample324 [ + input := '_foo _bar_ baz_'. + + expected := '

    foo bar baz

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample325 [ + input := '__foo_ bar_'. + + expected := '

    foo bar

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample326 [ + input := '*foo *bar**'. + + expected := '

    foo bar

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample327 [ + input := '*foo **bar** baz*'. + + expected := '

    foo bar baz

    '. + + self assertExample. +] + +{ #category : 'emphasis' } +PPCommonMarkSpecTest >> testExample328 [ + input := '*foo**bar**baz*'. + + expected := '

    foobarbaz

    '. + + "JK: inline not yet implemented properly" + "self assertExample." +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample396 [ + input := '[link](/uri "title")'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample397 [ + input := '[link](/uri)'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample398 [ + input := '[link]()'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample399 [ + input := '[link](<>)'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample400 [ + input := '[link](/my uri)'. + + expected := '

    [link](/my uri)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample401 [ + input := '[link](
    )'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample402 [ + input := '[link](foo +bar)'. + + expected := '

    [link](foo +bar)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample403 [ + input := '[link]()'. + + expected := '

    [link]()

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample404 [ + input := '[link]((foo)and(bar))'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample405 [ + input := '[link](foo(and(bar)))'. + + expected := '

    [link](foo(and(bar)))

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample406 [ + input := '[link](foo(and\(bar\)))'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample407 [ + input := '[link]()'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample408 [ + input := '[link](foo\)\:)'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample409 [ + input := '[link](foo%20bä)'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample410 [ + input := '[link]("title")'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample411 [ + input := '[link](/url "title") +[link](/url ''title'') +[link](/url (title))'. + + expected := '

    link +link +link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample412 [ + input := '[link](/url "title \""")'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample413 [ + input := '[link](/url "title "and" title")'. + + expected := '

    [link](/url "title "and" title")

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample414 [ + input := '[link](/url ''title "and" title'')'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample415 [ + input := '[link]( /uri + "title" )'. + + expected := '

    link

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample416 [ + input := '[link] (/uri)'. + + expected := '

    [link] (/uri)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample417 [ + input := '[link [foo [bar]]](/uri)'. + + expected := '

    link [foo [bar]]

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample418 [ + input := '[link] bar](/uri)'. + + expected := '

    [link] bar](/uri)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample419 [ + input := '[link [bar](/uri)'. + + expected := '

    [link bar

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample420 [ + input := '[link \[bar](/uri)'. + + expected := '

    link [bar

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample421 [ + input := '[link *foo **bar** `#`*](/uri)'. + + expected := '

    link foo bar #

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample422 [ + input := '[![moon](moon.jpg)](/uri)'. + + expected := '

    moon

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample423 [ + input := '[foo [bar](/uri)](/uri)'. + + expected := '

    [foo bar](/uri)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample424 [ + input := '[foo *[bar [baz](/uri)](/uri)*](/uri)'. + + expected := '

    [foo [bar baz](/uri)](/uri)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample425 [ + input := '![[[foo](uri1)](uri2)](uri3)'. + + expected := '

    [foo](uri2)

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample426 [ + input := '*[foo*](/uri)'. + + expected := '

    *foo*

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample427 [ + input := '[foo *bar](baz*)'. + + expected := '

    foo *bar

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample428 [ + input := '*foo [bar* baz]'. + + expected := '

    foo [bar baz]

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample429 [ + input := '[foo '. + + expected := '

    [foo

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample430 [ + input := '[foo`](/uri)`'. + + expected := '

    [foo](/uri)

    '. + self assertExample. +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample431 [ + input := '[foo'. + + expected := '

    [foohttp://example.com/?search=](uri)

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample432 [ + input := '[foo][bar] + +[bar]: /url "title"'. + + expected := '

    foo

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'links' } +PPCommonMarkSpecTest >> testExample433 [ + input := '[link [foo [bar]]][ref] + +[ref]: /uri'. + + expected := '

    link [foo [bar]]

    '. + + self flag: 'JK: inline not yet implemented properly' + "self assertExample." +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample493 [ + input := ''. + + expected := '

    http://foo.bar.baz

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample494 [ + input := ''. + + expected := '

    http://foo.bar.baz/test?q=hello&id=22&boolean

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample495 [ + input := ''. + + expected := '

    irc://foo.bar:2233/baz

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample496 [ + input := ''. + + expected := '

    MAILTO:FOO@BAR.BAZ

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample497 [ + input := ''. + + expected := '

    <http://foo.bar/baz bim>

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample498 [ + input := ''. + + expected := '

    http://example.com/\[\

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample499 [ + input := ''. + + expected := '

    foo@bar.example.com

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample500 [ + input := ''. + + expected := '

    foo+special@Bar.baz-bar0.com

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample501 [ + input := ''. + + expected := '

    <foo+@bar.example.com>

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample502 [ + input := '<>'. + + expected := '

    <>

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample503 [ + input := ''. + + expected := '

    <heck://bing.bong>

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample504 [ + input := '< http://foo.bar >'. + + expected := '

    < http://foo.bar >

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample505 [ + input := ''. + + expected := '

    <foo.bar.baz>

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample506 [ + input := ''. + + expected := '

    <localhost:5001/foo>

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample507 [ + input := 'http://example.com'. + + expected := '

    http://example.com

    '. + + self assertExample. +] + +{ #category : 'autolinks' } +PPCommonMarkSpecTest >> testExample508 [ + input := 'foo@bar.example.com'. + + expected := '

    foo@bar.example.com

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample509 [ + input := ''. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample510 [ + input := ''. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample511 [ + input := ''. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample512 [ + input := '"'' +_boolean zoop:33=zoop:33 />'. + + expected := '

    "'' +_boolean zoop:33=zoop:33 />

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample513 [ + input := '<33> <__>'. + + expected := '

    <33> <__>

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample514 [ + input := '
    '. + + expected := '

    <a h*#ref="hi">

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample515 [ + input := '
    '. + + expected := '

    </a href="foo">

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample520 [ + input := 'foo '. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample521 [ + input := 'foo '. + + expected := '

    foo <!-- not a comment -- two hyphens -->

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample522 [ + input := 'foo foo --> + +foo '. + + expected := '

    foo <!--> foo -->

    +

    foo <!-- foo--->

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample523 [ + input := 'foo '. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample524 [ + input := 'foo '. + + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample525 [ + input := 'foo &<]]>'. + + expected := '

    foo &<]]>

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample526 [ + input := '
    '. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample527 [ + input := ''. + + expected := '

    '. + + self assertExample. +] + +{ #category : 'raw html' } +PPCommonMarkSpecTest >> testExample528 [ + input := ''. + + expected := '

    <a href=""">

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample529 [ + input := 'foo +baz'. + expected := '

    foo
    +baz

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample530 [ + input := 'foo\ +baz'. + expected := '

    foo
    +baz

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample531 [ + input := 'foo +baz'. + expected := '

    foo
    +baz

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample532 [ + input := 'foo + bar'. + expected := '

    foo
    +bar

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample533 [ + input := 'foo\ + bar'. + expected := '

    foo
    +bar

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample534 [ + input := '*foo +bar*'. + expected := '

    foo
    +bar

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample535 [ + input := '*foo\ +bar*'. + expected := '

    foo
    +bar

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample536 [ + input := '`code +span`'. + expected := '

    code span

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample537 [ + input := '`code\ +span`'. + expected := '

    code\ span

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample538 [ + input := '
    '. + expected := '

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample539 [ + input := ''. + expected := '

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample540 [ + input := 'foo\'. + expected := '

    foo\

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample541 [ + input := 'foo '. + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample542 [ + input := '### foo\'. + expected := '

    foo\

    '. + + self assertExample. +] + +{ #category : 'hard line breaks' } +PPCommonMarkSpecTest >> testExample543 [ + input := '### foo '. + expected := '

    foo

    '. + + self assertExample. +] + +{ #category : 'soft line breaks' } +PPCommonMarkSpecTest >> testExample544 [ + input := 'foo +baz'. + expected := '

    foo +baz

    '. + + self assertExample. +] + +{ #category : 'soft line breaks' } +PPCommonMarkSpecTest >> testExample545 [ + input := 'foo + baz'. + expected := '

    foo +baz

    '. + + self assertExample. +] + +{ #category : 'textual content' } +PPCommonMarkSpecTest >> testExample546 [ + input := 'hello $.;''there'. + expected := '

    hello $.;''there

    '. + + self assertExample. +] + +{ #category : 'textual content' } +PPCommonMarkSpecTest >> testExample547 [ + input := 'Foo χρῆν'. + expected := '

    Foo χρῆν

    '. + + self assertExample. +] + +{ #category : 'textual content' } +PPCommonMarkSpecTest >> testExample548 [ + input := 'Multiple spaces'. + expected := '

    Multiple spaces

    '. + + self assertExample. +] + +{ #category : 'as yet unclassified' } +PPCommonMarkSpecTest >> testExtra1 [ + input := '# Foo +bar'. + + expected := '

    Foo

    +

    bar

    '. + + self assertExample. +] + +{ #category : 'as yet unclassified' } +PPCommonMarkSpecTest >> testExtra2 [ + input := '- # Foo + bar'. + + expected := '
      +
    • +

      Foo

      bar
    • +
    '. + + self assertExample. +] + +{ #category : 'as yet unclassified' } +PPCommonMarkSpecTest >> testExtra3 [ + input := '*[foo]*'. + + expected := '

    [foo]

    '. + + self assertExample. +] + +{ #category : 'as yet unclassified' } +PPCommonMarkSpecTest >> testExtra4 [ + input := '*[foo)*]'. + + expected := '

    [foo)]

    '. + + self assertExample. +] + +{ #category : 'paragraphs' } +PPCommonMarkSpecTest >> testParagraphExtra1 [ + input := ' aaa +***'. + + expected := '

    aaa

    +
    '. + + self assertExample. +] diff --git a/software/PetitMarkdown/PPCommonMarkUtils.class.st b/software/PetitMarkdown/PPCommonMarkUtils.class.st new file mode 100644 index 0000000..3676df3 --- /dev/null +++ b/software/PetitMarkdown/PPCommonMarkUtils.class.st @@ -0,0 +1,72 @@ +Class { + #name : 'PPCommonMarkUtils', + #superclass : 'Object', + #classInstVars : [ + 'Instance' + ], + #category : 'PetitMarkdown-Parser' +} + +{ #category : 'as yet unclassified' } +PPCommonMarkUtils class >> instance [ + Instance isNil ifTrue: [ Instance := PPCommonMarkUtils new ]. + ^ Instance +] + +{ #category : 'as yet unclassified' } +PPCommonMarkUtils >> decodeEntities: string [ + | retval | + retval := string. + + retval := retval copyReplaceAll: 'ö' with: 'ö'. + retval := retval copyReplaceAll: '&' with: '&'. + retval := retval copyReplaceAll: '"' with: '"'. + + ^ retval +] + +{ #category : 'as yet unclassified' } +PPCommonMarkUtils >> encodeEntities: string [ + | retval | + retval := string. + + retval := retval copyReplaceAll: '&' with: '&'. + retval := retval copyReplaceAll: '"' with: '"'. + retval := retval copyReplaceAll: '>' with: '>'. + retval := retval copyReplaceAll: '<' with: '<'. + + ^ retval +] + +{ #category : 'as yet unclassified' } +PPCommonMarkUtils >> escape: string [ + | retval regex | + retval := string. + retval := retval copyReplaceAll: '\\' with: '\'. + + "Remove backlashes, \! -> !" + regex := '\\[!#$%''()*+,-./:;=?@^_`{|}~]' asRegex. + retval := regex copy: retval translatingMatchesUsing: [ :match | match second asString ]. + + retval := retval copyReplaceAll: '\"' with: '"'. + retval := retval copyReplaceAll: '\[' with: '['. + retval := retval copyReplaceAll: '\]' with: ']'. + retval := retval copyReplaceAll: '\\' with: '\'. + + ^ retval +] + +{ #category : 'as yet unclassified' } +PPCommonMarkUtils >> escapeUrl: string [ + | retval | + retval := string. + retval := retval copyReplaceAll: ' ' with: '%20'. + retval := retval copyReplaceAll: '"' with: '%22'. + retval := retval copyReplaceAll: '\' with: '%5C'. + retval := retval copyReplaceAll: '[' with: '%5B'. + retval := retval copyReplaceAll: '`' with: '%60'. + retval := retval copyReplaceAll: 'ä' with: '%C3%A4'. + retval := retval copyReplaceAll: 'ö' with: '%C3%B6'. + + ^ retval +] diff --git a/software/PetitMarkdown/PPContext.extension.st b/software/PetitMarkdown/PPContext.extension.st new file mode 100644 index 0000000..7feb9de --- /dev/null +++ b/software/PetitMarkdown/PPContext.extension.st @@ -0,0 +1,70 @@ +Extension { #name : 'PPContext' } + +{ #category : '*PetitMarkdown' } +PPContext >> codeFence [ + ^ self globalAt: #PPCMFence +] + +{ #category : '*PetitMarkdown' } +PPContext >> codeFence: fence [ + self globalAt: #PPCMFence put: fence +] + +{ #category : '*PetitMarkdown' } +PPContext >> codeFenceIndent [ + ^ self globalAt: #PPCMFenceIndent +] + +{ #category : '*PetitMarkdown' } +PPContext >> codeFenceIndent: indent [ + self globalAt: #PPCMFenceIndent put: indent +] + +{ #category : '*PetitMarkdown' } +PPContext >> inlineCodeEnd [ + ^ self globalAt: #inlineCodeEnd +] + +{ #category : '*PetitMarkdown' } +PPContext >> inlineCodeEnd: value [ + ^ self globalAt: #inlineCodeEnd put: value +] + +{ #category : '*PetitMarkdown' } +PPContext >> links [ + ^ self globalAt: #PPCMLinks ifAbsentPut: [ IdentitySet new ] +] + +{ #category : '*PetitMarkdown' } +PPContext >> listItemStack [ + ^ self propertyAt: #listItemStack ifAbsentPut: [ Stack new ] +] + +{ #category : '*PetitMarkdown' } +PPContext >> listItemType [ + self listItemStack ifEmpty: [ ^ PPFailingParser message: 'stack is empty' ]. + ^ self listItemStack top +] + +{ #category : '*PetitMarkdown' } +PPContext >> listItemType: value [ + self listItemStack push: value +] + +{ #category : '*PetitMarkdown' } +PPContext >> readLimit [ + ^ stream size +] + +{ #category : '*PetitMarkdown' } +PPContext >> readLimit: limit [ + stream readLimit: limit +] + +{ #category : '*PetitMarkdown' } +PPContext >> registerLink: node [ + self assert: node class == PPCMLinkRefDef. + (self links contains: [ :e | e label text asLowercase = node label text asLowercase ]) ifFalse: [ + self links add: node + ] +] diff --git a/software/PetitMarkdown/PPLimitParser.class.st b/software/PetitMarkdown/PPLimitParser.class.st new file mode 100644 index 0000000..4d08a1b --- /dev/null +++ b/software/PetitMarkdown/PPLimitParser.class.st @@ -0,0 +1,33 @@ +Class { + #name : 'PPLimitParser', + #superclass : 'PPDelegateParser', + #instVars : [ + 'limiter' + ], + #category : 'PetitMarkdown-Parser' +} + +{ #category : 'accessing' } +PPLimitParser >> limiter [ + ^ limiter +] + +{ #category : 'accessing' } +PPLimitParser >> limiter: anObject [ + limiter := anObject +] + +{ #category : 'as yet unclassified' } +PPLimitParser >> parseOn: aPPContext [ + | size position retval| + size := aPPContext readLimit. + position := aPPContext position. + + limiter parseOn: aPPContext. + aPPContext readLimit: aPPContext position. + aPPContext position: position. + + retval := parser parseOn: aPPContext. + aPPContext readLimit: size. + ^ retval +] diff --git a/software/PetitMarkdown/PPLimitParserTest.class.st b/software/PetitMarkdown/PPLimitParserTest.class.st new file mode 100644 index 0000000..be39c74 --- /dev/null +++ b/software/PetitMarkdown/PPLimitParserTest.class.st @@ -0,0 +1,28 @@ +Class { + #name : 'PPLimitParserTest', + #superclass : 'PPParserTest', + #instVars : [ + 'parser' + ], + #category : 'PetitMarkdown-Tests' +} + +{ #category : 'as yet unclassified' } +PPLimitParserTest >> testLimit [ + | limiter foo | + limiter := #any asParser max: 3. + foo := 'foo' asParser. + parser := foo limitedBy: limiter. + + self assert: parser parse: 'foo'. +] + +{ #category : 'as yet unclassified' } +PPLimitParserTest >> testLimit2 [ + | limiter foo | + limiter := #any asParser max: 2. + foo := 'foo' asParser. + parser := foo limitedBy: limiter. + + self assert: parser fail: 'foo'. +] diff --git a/software/PetitMarkdown/PPParser.extension.st b/software/PetitMarkdown/PPParser.extension.st new file mode 100644 index 0000000..e1aa504 --- /dev/null +++ b/software/PetitMarkdown/PPParser.extension.st @@ -0,0 +1,80 @@ +Extension { #name : 'PPParser' } + +{ #category : '*PetitMarkdown' } +PPParser >> asPPCMLine [ + ^ (self map: [ :elems | + PPCMLine new + children: elems; + yourself + ]) name: 'asPPCMLine'; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> asPPCMPlainLine [ + ^ (self map: [ :text | + PPCMPlainLine new + text: text; + yourself + ]) name: 'asPPCMPlainLine'; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> asPPCMPlainText [ + ^ (self map: [ :text | + PPCMPlainText new + text: text; + yourself + ]) name: 'asPPCMPlainText'; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> asPPCMText [ + ^ (self map: [ :text | + PPCMText new + text: text; + yourself + ]) name: 'asPPCMText'; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> limitedBy: limiter [ + ^ (PPLimitParser on: self) + limiter: limiter; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> preceeds [ + ^ (PPPreceedsParser on: self) + length: 1; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> preceeds: length [ + ^ (PPPreceedsParser on: self) + length: length; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> where: replacee is: replacement [ + ^ (PPReplaceParser on: self) + replacee: replacee; + replacement: replacement; + yourself +] + +{ #category : '*PetitMarkdown' } +PPParser >> whileFalse: parser [ + ^ (self not, parser) star +] + +{ #category : '*PetitMarkdown' } +PPParser >> whileFalse: condition consume: parser [ + ^ (condition not, parser) star +] diff --git a/software/PetitMarkdown/PPPreceedsParser.class.st b/software/PetitMarkdown/PPPreceedsParser.class.st new file mode 100644 index 0000000..f9b1666 --- /dev/null +++ b/software/PetitMarkdown/PPPreceedsParser.class.st @@ -0,0 +1,35 @@ +Class { + #name : 'PPPreceedsParser', + #superclass : 'PPDelegateParser', + #instVars : [ + 'length' + ], + #category : 'PetitMarkdown-Parser' +} + +{ #category : 'accessing' } +PPPreceedsParser >> length [ + ^ length +] + +{ #category : 'accessing' } +PPPreceedsParser >> length: anObject [ + length := anObject +] + +{ #category : 'as yet unclassified' } +PPPreceedsParser >> parseOn: aPPContext [ + | memento result | + (aPPContext position < length) ifTrue: [ + ^ PPFailure message: 'not enough space to preceed' context: aPPContext + ]. + + memento := aPPContext position. + + aPPContext skip: length negated. + result := parser parseOn: aPPContext. + + aPPContext position: memento. + ^ result + +] diff --git a/software/PetitMarkdown/PPPreceedsParserTest.class.st b/software/PetitMarkdown/PPPreceedsParserTest.class.st new file mode 100644 index 0000000..7e37928 --- /dev/null +++ b/software/PetitMarkdown/PPPreceedsParserTest.class.st @@ -0,0 +1,36 @@ +Class { + #name : 'PPPreceedsParserTest', + #superclass : 'PPParserTest', + #instVars : [ + 'parser' + ], + #category : 'PetitMarkdown-Tests' +} + +{ #category : 'as yet unclassified' } +PPPreceedsParserTest >> testLiteral [ + | foo | + foo := 'foo' asParser. + parser := foo, (foo preceeds: 3). + + self assert: parser parse: 'foo'. +] + +{ #category : 'as yet unclassified' } +PPPreceedsParserTest >> testLiteral2 [ + | foo | + foo := 'foo' asParser. + parser := foo, (foo preceeds: 2). + + self assert: parser fail: 'foo'. +] + +{ #category : 'as yet unclassified' } +PPPreceedsParserTest >> testLiteral3 [ + | foo bar | + foo := 'foo' asParser. + bar := 'bar' asParser. + parser := foo, (bar preceeds: 3). + + self assert: parser fail: 'foo'. +] diff --git a/software/PetitMarkdown/PPReplaceParser.class.st b/software/PetitMarkdown/PPReplaceParser.class.st new file mode 100644 index 0000000..9b373e6 --- /dev/null +++ b/software/PetitMarkdown/PPReplaceParser.class.st @@ -0,0 +1,60 @@ +" +Replaces replacee with the replacement and evaluates its child.The replacee is restored after the child is evaluated. + +WARNING: IMO does not work with memoization +" +Class { + #name : 'PPReplaceParser', + #superclass : 'PPDelegateParser', + #instVars : [ + 'replacee', + 'replacement' + ], + #category : 'PetitMarkdown-Parser' +} + +{ #category : 'as yet unclassified' } +PPReplaceParser >> children [ + ^ Array with: parser with: replacee with: replacement +] + +{ #category : 'as yet unclassified' } +PPReplaceParser >> parseOn: aPPContext [ + | tmp retval | + self assert: (replacee isKindOf: PPDelegateParser). + tmp := replacee children first. + + replacee setParser: replacement. + retval := parser parseOn: aPPContext. + replacee setParser: tmp. + + ^ retval +] + +{ #category : 'as yet unclassified' } +PPReplaceParser >> replace: aParser with: anotherParser [ + super replace: aParser with: anotherParser. + + (replacee == aParser) ifTrue: [ replacee := anotherParser ]. + (replacement == aParser) ifTrue: [ replacement := anotherParser ]. +] + +{ #category : 'accessing' } +PPReplaceParser >> replacee [ + ^ replacee +] + +{ #category : 'accessing' } +PPReplaceParser >> replacee: anObject [ + replacee := anObject +] + +{ #category : 'accessing' } +PPReplaceParser >> replacement [ + ^ replacement +] + +{ #category : 'accessing' } +PPReplaceParser >> replacement: anObject [ + replacement := anObject +] diff --git a/software/PetitMarkdown/PPReplaceParserTest.class.st b/software/PetitMarkdown/PPReplaceParserTest.class.st new file mode 100644 index 0000000..4643d30 --- /dev/null +++ b/software/PetitMarkdown/PPReplaceParserTest.class.st @@ -0,0 +1,38 @@ +Class { + #name : 'PPReplaceParserTest', + #superclass : 'PPParserTest', + #instVars : [ + 'parser' + ], + #category : 'PetitMarkdown-Tests' +} + +{ #category : 'as yet unclassified' } +PPReplaceParserTest >> test1 [ + | foo literal1 literal2 | + literal1 := 'foo' asParser. + literal2 := 'bar' asParser. + + foo := PPDelegateParser new + setParser: literal1; + yourself. + + parser := foo wrapped where: foo is: literal2. + + self assert: parser parse: 'bar'. +] + +{ #category : 'as yet unclassified' } +PPReplaceParserTest >> test2 [ + | foo literal1 literal2 | + literal1 := 'foo' asParser. + literal2 := 'bar' asParser. + + foo := PPDelegateParser new + setParser: literal1; + yourself. + + parser := (foo wrapped where: foo is: literal2), foo. + + self assert: parser parse: 'barfoo'. +] diff --git a/software/PetitMarkdown/PPStream.extension.st b/software/PetitMarkdown/PPStream.extension.st new file mode 100644 index 0000000..673d4df --- /dev/null +++ b/software/PetitMarkdown/PPStream.extension.st @@ -0,0 +1,6 @@ +Extension { #name : 'PPStream' } + +{ #category : '*PetitMarkdown' } +PPStream >> readLimit: limit [ + readLimit := limit +] diff --git a/software/PetitMarkdown/package.st b/software/PetitMarkdown/package.st new file mode 100644 index 0000000..bc15b21 --- /dev/null +++ b/software/PetitMarkdown/package.st @@ -0,0 +1 @@ +Package { #name : 'PetitMarkdown' }