[ENH]Html table (third version)

Karl Ramberg karl.ramberg at chello.se
Mon Sep 3 18:31:20 UTC 2001


Lex Spoon wrote:
> 
> Oh man, this thread is so painful to read.  It's almost enough to make
> me want to document this stuff.  :)  Although actually, some of it is
> documented on the Scamper swiki page (or, some page nearby to it.  I
> don't have Internet access to check the exact location right now.)

Well, reading code and adding to is is a sweet pain:-) 
> 
> Close tags are *not* required.  If they were then lists wouldn't work,
> because people hardly ever put in the </li>'s.  In fact, Scamper copes
> not only with omitted close tags, but with lots of erroneous HTML, as
> well.  This is why it uses a hand-written parser instead of a much more
> elegant SGML parser.  
I'm really impressed of the parser. It's basically one method, and it 
handles dreadfull html really good.

> (A nice thing about XML is a social one: it's so
> verbose and obscure that nobody wants to write it by hand, and so it's
> socially acceptible for parser's to just dump even slightly erroneous
> input on the floor.)
> 
> The mayContain: idea is crucial for both of these, and the parsing
> problem people saw is surely because one or more of the various
> HtmlTable class's has an incorrect mayContain: method.  It's worth
> spending a few minutes getting these #mayContain: methods to something
> reasonable, instead of just returning true all the time -- it helps with
> making reasonable parses of bad HTML, and it helps when processing the
> HTML after it's parsed, because you know, e.g., that TABLE's only
> contain TR's.

My problem ocurred when TD not could contain TABLES, therefor I changed
the mayContain to return true and got into all kind of truble.
I fixed this in the third version I posted and it works the way it
should 
now. 
> 
> Okay, those little bits aside, here is a skeleton design for adding
> tables.  I'll leave out the details of  building the table morph itself
> -- frankly, I don't even know exactly how!  :)
> 
> The core idea is to make outputStream be a stack, ie "outputStreams"
> instead of "outputStream".  Add an #outputStream method that returns the
> top element of outputStreams, update all users of the outputStream ivar
> to use the #outputStream method, and then add some methods like:
> 
>         #startNewOutputStream
>         #endCurrentOutputStream
> 
> (Here would be a good time to run regression tests.  Ah well, too bad
> there aren't any.)
> 
> Now, to format a table, add a addToFormatter: method to HtmlTable like
> this:
> 
> addToFormatter: formatter
>         | tm |
>         tm := "insert your code to make a table morph".
>         self subEntities do: [ :rowEntity |
>                 tm startNewRow.
>                 rowEntity subEntities do: [ :cell |
>                         formatter startNewOutputStream.
>                         cell addToFormatter: formatter.
>                         tm addCell: formatter formattedText.
>                         formatted endCurrentOutputStream ] ].
>         formatter addMorph: tm
> 
> Note, critically, that #formattedText should return the text of the
> *current* output stream, not of of the whole document.  This will
> probably happen automatically, but be aware of this as you read the
> above code.

Here is what I have done:
I add tables as new morph to formatter. I add rows as submorphs
to the last table in the formatter. (The layout is done with the 
TableLayout stuff added in 3.1alpha)
And at last the cell is added with this code:

addToFormatter: formatter 
	| data nuDocument nuFormatter m |
	data _ TableDataMorph new. "adds the new cell and sets up it's layout"
	data color: Color transparent.
	data borderColor: Color black.
	data borderWidth: 1.
	data layoutPolicy: TableLayout new.
	data listDirection: #leftToRight.
	data wrapCentering: #topLeft.
	data hResizing: #spaceFill.
	data vResizing: #spaceFill.
	data layoutInset: 0.
	formatter addTableDataMorph: data." add cell to last table's last row!"
	
	nuFormatter _ HtmlFormatter preferredFormatterClass new. "set up a new  formatter"
	nuFormatter browser: formatter browser.
	nuFormatter baseUrl: formatter baseUrl.
	1 to: (contents size) do:[:i| nuDocument _ contents at: i. 
			nuDocument addToFormatter: nuFormatter. ]. " feed the formatter with
whatever is present"
	
	data addMorphBack: nuFormatter textMorph. "add the textMorph made from
the new formatter to the cell"
	((m _ nuFormatter incompleteMorphs size) > 0)
		ifTrue:[ 1 to: m do: [:i| formatter incompleteMorphs add: (nuFormatter
incompleteMorphs at:i)]].
      "make sure images get updatet"
> 
> And that's it.  Now you just have to figure out how to make TableMorph's
> at all!
My problem now is that the layout policy in squeak does not handle 
row spans and column spans the way html tables does, as far as I know ;-)
Any way, I think I will change stuff around a little. 
Hopefully there is no need for a seperate row morph, and by removing that
there will be a way to get the cells in a table layout to wrap and 
deal with row spans and colspans. Feedback on this is wanted !
 
> By the way, here are two other tricks people will be interested in, once
> you start playing with tables.
>This stuff I have not looked into. My apprach is the Morphic Layout Way:-)
> First, you can get tables to resize horizontally by adding some sort of
> widthProportion instance variable to TextAnchor (TextAnchor is the
> subclass of TextAttribute that Text uses to deal with embedded morphs).
> Then, TextAnchor>>emphasizeScanner can resize the morph before doing its
> normal thing, if this instance variable has been set.  Bolot and I put
> together something like this once upon a time, but it got lost.  I leave
> figuring out the width of a CharacterScanner as an excercise for those
> who have a lot of time.
> 
> Second, you can add a TextAlignment attribute that allows centered text,
> but this is a tad more work.  You must make all uses of "textStyle
> alignment" in CharacterScaner+subclasses use the "alignment" instance
> variable, instead.  The rest is really easy: add an #allignment: method
> in TextAlignment that sets the alignment, and make
> TextAlignment>>emphasizeScanner: set the alignment on the supplied
> formatter.
> 
> Cheers!  Like Je77, I'm really excited to see people playing with this
> -- tables would make Scamper much nicer to use!
> 
> By the way, frames aren't too far away, once we have tables -- one could
> use the same table morph that tables use, but with some sort of
> "DownloadingHtmlMorph" in the cells.   DownloadingHtmlMorph will look
> like DownloadingImageMorph, except that it downloads and displays HTML
> instead of images.
There is allready a WebPageMorph that is perfect for the 
task! Once the row span col span stuff is worked out I'll 
look into it.
> My apologies for not reading any of the specific table packages people have
> posted.  The above fixes all of the problems people have mentioned having, though, and
> so unless everyone is burned out now I'll wait until someone has a more complete
> solution.
> 
You as everybody else are welcome to jump in at any time:-)

Karl




More information about the Squeak-dev mailing list