[squeak-dev] Clashing semantics for #asCollection between Stream parser(S) and MaClientServer
Levente Uzonyi
leves at caesar.elte.hu
Tue Aug 13 00:47:24 UTC 2019
Hi Tim,
On Mon, 12 Aug 2019, tim Rowledge wrote:
> I just loaded the Xtreams and Levente's GoogleWikiCompiler into an image that already had Chris' MaClientServer package.
>
> Running the GoogleWikiCompiler example failed! Oh noes!
>
> Turns out that in GoogleWikiCompiler>LinkShort: the use of
> address, '.html'
> to merger a collection of characters with the string '.html' relies on the implementation semantics of #asCollection to leave a String as a String - after all, it's a collection of characters, right?
>
> However, Chris has changed that for MaClientServer such the String is returned as
> Array with: theString
> which doesn't play nice with the above.
>
> I'm not entirely sure I like either approach really; #($a $b $c) , 'foo' doesn't seem like such a great thing to do, especially if you can't guarantee what the actual state of the 'address' object is (that's a bigger issue around the parser behaviour) BUT 'foo' asCollection -> #( 'foo') doesn't seem quite nice either. I could sort of appreciate 'foo' asCollection -> #($f $o $o) I suppose.
>
> The immediate solution within the context of the swiki parsing is to carefully make sure the address is actually a string, so no major issue for me today, but this does indicate a potentially problematic perplexity when mixing xtreams and client server packages.
If MaClientServer implements String >> #asCollection, then that's a
mistake, which breaks #,.
I came to the conclusion that without a proper html generator,
GoogleWikiCompiler cannot create correct output.
I have attached a version of GoogleWikiCompiler (attached), which uses our
internal tool: StreamingHtmlCanvas (also attached) to generate html.
Yes, that's another dependency, but that's how things go, isn't it? :)
Also, I had to convert the address variable to a string in links actions.
I think you've done the same in your image.
Levente
>
> tim
> --
> tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
> Fractured Idiom:- VISA LA FRANCE - Don't leave chateau without it
-------------- next part --------------
A non-text attachment was scrubbed...
Name: StreamingHtmlCanvas-klub.33.mcz
Type: application/zip
Size: 14368 bytes
Desc:
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20190813/3e25b305/attachment.zip>
-------------- next part --------------
PEGActor subclass: #GoogleWikiCompiler
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'GoogleWikiCompiler'!
!GoogleWikiCompiler commentStamp: '<historical>' prior: 0!
This actor is used to convert text with wiki mark-up into an XML document with xhtml tags.
Shared Variables
Anchor <NodeTag>
Break <NodeTag>
Division <NodeTag>
Heading1 <NodeTag>
Heading2 <NodeTag>
Heading3 <NodeTag>
Heading4 <NodeTag>
Href <NodeTag>
ListItem <NodeTag>
OrderedList <NodeTag>
Paragraph <NodeTag>
Preformatted <NodeTag>
Span <NodeTag>
Style <NodeTag>
Table <NodeTag>
TableBody <NodeTag>
TableData <NodeTag>
TableHead <NodeTag>
TableHeading <NodeTag>
TableRow <NodeTag>
UnorderedList <NodeTag>
!
!GoogleWikiCompiler methodsFor: 'Lexical' stamp: 'ul 8/10/2019 22:17'!
Bold: flow
<action: 'Bold' arguments: #(2)>
^GoogleWikiDomNode strong: flow! !
!GoogleWikiCompiler methodsFor: 'Lexical' stamp: 'ul 8/10/2019 14:58'!
Escape: escape
<action: 'Escape'>
^escape first! !
!GoogleWikiCompiler methodsFor: 'Lexical' stamp: 'ul 8/10/2019 22:31'!
Italic: flow
<action: 'Italic' arguments: #(2)>
^GoogleWikiDomNode em: flow! !
!GoogleWikiCompiler methodsFor: 'Lexical' stamp: 'ul 8/11/2019 21:51'!
LinkFull: flow address: address
<action: 'LinkFull' arguments: #(2 3)>
^GoogleWikiDomNode a
attributes: { 'href' -> (address as: String) };
children: flow;
yourself! !
!GoogleWikiCompiler methodsFor: 'Lexical' stamp: 'ul 8/11/2019 21:50'!
LinkShort: address
<action: 'LinkShort' arguments: #(2)>
^GoogleWikiDomNode a
attributes: { 'href' -> ((address as: String), '.html') };
children: address;
yourself! !
!GoogleWikiCompiler methodsFor: 'Lexical' stamp: 'ul 8/10/2019 22:37'!
Underline: flow
<action: 'Underline' arguments: #(2)>
^GoogleWikiDomNode span
attributes: { 'style' -> 'text-decoration: underline' };
children: flow;
yourself! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:17'!
Code: text
<action: 'Code' arguments: #(2)>
^GoogleWikiDomNode code: text! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 15:01'!
Empty
<action: 'Empty' arguments: #()>
^nil! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:30'!
Heading1: flow
<action: 'Heading1' arguments: #(3)>
^GoogleWikiDomNode h1: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:31'!
Heading2: flow
<action: 'Heading2' arguments: #(3)>
^GoogleWikiDomNode h2: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:31'!
Heading3: flow
<action: 'Heading3' arguments: #(3)>
^GoogleWikiDomNode h3: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:31'!
Heading4: flow
<action: 'Heading4' arguments: #(3)>
^GoogleWikiDomNode h4: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:33'!
ListItem: bullets flow: flow
<action: 'Bullet1' arguments: #(2 3)>
<action: 'Bullet2' arguments: #(2 3)>
<action: 'Bullet3' arguments: #(2 3)>
<action: 'Hash1' arguments: #(2 3)>
<action: 'Hash2' arguments: #(2 3)>
<action: 'Hash3' arguments: #(2 3)>
^GoogleWikiDomNode li: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:33'!
OrderedList: bullets
<action: 'OrderedList'>
^GoogleWikiDomNode ol: bullets! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:34'!
OrderedListN: bullets
<action: 'OrderedList2'>
<action: 'OrderedList3'>
^GoogleWikiDomNode li: (GoogleWikiDomNode ol: bullets)! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:34'!
Page: lines
<action: 'Page'>
^GoogleWikiDomNode div: lines! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:34'!
Paragraph: flow
<action: 'Paragraph'>
^GoogleWikiDomNode p: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:35'!
Preformatted: text
<action: 'Code' arguments: #(2)>
^GoogleWikiDomNode pre: text! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:36'!
Table: header rows: rows
<action: 'Table' arguments: #(1 2)>
^GoogleWikiDomNode table: {
GoogleWikiDomNode thead: header.
GoogleWikiDomNode tbody: rows }! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:36'!
TableCell: flow
<action: 'Cell'>
^GoogleWikiDomNode td: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:36'!
TableHeadingCell: flow
<action: 'HeadingCell'>
^GoogleWikiDomNode th: flow! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:36'!
TableRow: cells
<action: 'TableRow' arguments: #(3)>
<action: 'HeadingRow' arguments: #(3)>
^GoogleWikiDomNode tr: cells! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:37'!
UnorderedList: bullets
<action: 'UnorderedList'>
^GoogleWikiDomNode ul: bullets! !
!GoogleWikiCompiler methodsFor: 'Structural' stamp: 'ul 8/10/2019 22:37'!
UnorderedListN: bullets
<action: 'UnorderedList2'>
<action: 'UnorderedList3'>
^GoogleWikiDomNode li: (GoogleWikiDomNode ul: bullets)! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
GoogleWikiCompiler class
instanceVariableNames: ''!
!GoogleWikiCompiler class methodsFor: 'utilities' stamp: 'ul 8/10/2019 23:40'!
process: input
"Convert input into an xhtml XML document.
"
" input <ReadStream> text with wiki markup
^ <GoogleWikiDomNode>
"
"
self process: 'Single paragraph with *bold* and _italic_ text and a [link]' reading
"
^self parser
parse: 'Page'
stream: input
actor: self new! !
!GoogleWikiCompiler class methodsFor: 'examples' stamp: 'ul 8/10/2019 23:36'!
example
" self example "
| input output |
input := 'Single paragraph with *bold* and _italic_ text and a [link]' reading.
output := self process: input.
^output! !
!GoogleWikiCompiler class methodsFor: 'accessing' stamp: 'ul 8/10/2019 23:45'!
parser
^PEGParser parserPEG
parse: 'Grammar'
stream: PEGParser grammarWiki reading
actor: PEGParserParser new! !
Object subclass: #GoogleWikiDomNode
instanceVariableNames: 'tag attributes children'
classVariableNames: ''
poolDictionaries: ''
category: 'GoogleWikiCompiler'!
!GoogleWikiDomNode methodsFor: 'converting' stamp: 'ul 8/11/2019 19:40'!
asString
^StreamingHtmlCanvas render: [ :html | self renderOn: html ]! !
!GoogleWikiDomNode methodsFor: 'rendering' stamp: 'ul 8/11/2019 19:41'!
renderChildNodes: childNodes of: element on: html
childNodes ifNil: [ ^self ].
childNodes class == self class ifTrue: [ ^element with: childNodes ].
childNodes isString ifTrue: [ ^element with: childNodes ].
childNodes isCharacter ifTrue: [ ^element with: childNodes ].
childNodes isCollection ifTrue: [
^childNodes do: [ :each | self renderChildNodes: each of: element on: html ] ].
self error: 'Unexpected child nodes'! !
!GoogleWikiDomNode methodsFor: 'rendering' stamp: 'ul 8/11/2019 21:50'!
renderChildNodes: childNodes on: html
childNodes ifNil: [ ^self ].
childNodes class == self class ifTrue: [ ^childNodes renderOn: html ].
childNodes isString ifTrue: [ ^html text: childNodes ].
childNodes isCharacter ifTrue: [ ^html text: childNodes ].
childNodes isCollection ifTrue: [
^childNodes do: [ :each |
self renderChildNodes: each on: html ] ].
self error: 'Unexpected child nodes'! !
!GoogleWikiDomNode methodsFor: 'rendering' stamp: 'ul 8/11/2019 21:49'!
renderOn: html
| element |
element := html perform: tag.
attributes ifNotNil: [
attributes do: [ :association |
element
addAttribute: association key
value: association value ] ].
element with: [ self renderChildNodes: children on: html ]! !
!GoogleWikiDomNode methodsFor: 'accessing' stamp: 'ul 8/10/2019 22:15'!
attributes: aCollectionOfAssociations
attributes := aCollectionOfAssociations! !
!GoogleWikiDomNode methodsFor: 'accessing' stamp: 'ul 8/10/2019 23:38'!
children: anObject
children := anObject! !
!GoogleWikiDomNode methodsFor: 'accessing' stamp: 'ul 8/10/2019 22:15'!
tag: aSymbol
tag := aSymbol! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
GoogleWikiDomNode class
instanceVariableNames: ''!
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:15'!
a
^self new
tag: #a;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:17'!
code: children
^self new
tag: #code;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:34'!
div: children
^self new
tag: #div;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:31'!
em: children
^self new
tag: #em;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:30'!
h1: children
^self new
tag: #h1;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:31'!
h2: children
^self new
tag: #h2;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:31'!
h3: children
^self new
tag: #h3;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:31'!
h4: children
^self new
tag: #h4;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:32'!
li: children
^self new
tag: #li;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:33'!
ol: children
^self new
tag: #ol;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:34'!
p: children
^self new
tag: #p;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
pre: children
^self new
tag: #pre;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:37'!
span
^self new
tag: #span;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:17'!
strong: children
^self new
tag: #strong;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
table: children
^self new
tag: #table;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
tbody: children
^self new
tag: #tbody;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
td: children
^self new
tag: #td;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
th: children
^self new
tag: #th;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
thead: children
^self new
tag: #thead;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:35'!
tr: children
^self new
tag: #tr;
children: children;
yourself! !
!GoogleWikiDomNode class methodsFor: 'instance creation' stamp: 'ul 8/10/2019 22:33'!
ul: children
^self new
tag: #ul;
children: children;
yourself! !
More information about the Squeak-dev
mailing list
|