Thread: [Structuredtext-develop] Re: wanting to use restructuredtext in a zope product
Status: Pre-Alpha
Brought to you by:
goodger
From: tav <ta...@es...> - 2002-04-10 04:26:19
|
>>>>> DG == "David Goodger" <go...@us...> wrote: tav> i ran into restructuredtext a few weeks back, and finding it to be tav> way cooler than the zope stx, decided to use it as the main render tav> format in the xnet product that i have been hacking. DG> Sounds good, but I don't understand "render format". You don't DG> mean you *output* reStructuredText, do you? my apologies. let me explain. an xt_object renders itself according to the formats specified in the xt_render_types list. and i'd like to have 'restx_to_html' (restructuredtext to html) be the default render type. so, content would be stored as restructuredtext and be output as html... DG> I looked at your CVS but I don't see an overview of what you're DG> doing. Is there one? ah, there is no overview document ;p however the xt_object class, where a lot of the action occurs, is fairly well documented: http://cvs.espnow.com/xnet/xnet/xt_object/xt_object.py?rev=HEAD&content-type =text/vnd.viewcvs-markup specifically, start out from __call__() and work down to render_apply() tav> i ran into two main problems in using it "out of the box": DG> It is all very experimental at this point, so usage anecdotes DG> are welcome, thanks. glad to help, and thanks in turn for a wonderful product. tav> [snip : rant about xhtml compatability] tav> ... so i took your html.py writer and did a quick adaptation of it: tav> http://cvs.espnow.com/xnet/xnet/contrib/xhtml.py DG> I see that your app is only interested in the tags between DG> "<body>" and "</body>", exclusive. That's a useful DG> distinction, when integrating with a wrapper system. yea, my personal needs are to simply convert content from one format to another... the presentation is handled by fancy zope page templates. DG> XHTML is on my list of things to investigate. I may modify DG> the HTML writer to output XHTML as you have done. that'd be great, and if self.output could be controlled by a variable as to whether it included the headers/footers, that'd be even better. tav> the second problem was with how you "output". the way tav> the publish() system was setup, one could only output to a tav> file or stdout. DG> The publish function (Publisher class) is a facade, a flat DG> front-end to the components of the system, meant to provide DG> enough functionality for 80% of clients. I'm only adding DG> functionality to the system as it is required, and yours is the DG> first case where a return value is required, instead of writing DG> to a file/stream. It may be a case of a new type of DG> "distribution", which I've thought about but haven't DG> implemented yet. a new type of distribution? DG> I would like to support such usage in a generic form, but I'm DG> not sure how yet. Please send me your patched files, so I can DG> see exactly what you mean. nothing spectacular. i simply added a couple of returns in core.py and in writers/__init__.py and finally, in writers/xhtml.py. here are the diffs: --------------------------- --- /home/services/zope/misc/stx/dps/dps/core.py Thu Feb 7 02:02:02 2002 +++ core.py Fri Mar 22 05:45:09 2002 @@ -53,7 +53,8 @@ def publish(self, source, destination): document = self.reader.read(source, self.parser) - self.writer.write(document, destination) + # tav : added a return + return self.writer.write(document, destination) def publish(source=None, destination=None, @@ -70,4 +71,5 @@ pub.setparser(parsername) if writer is None: pub.setwriter(writername) - pub.publish(source, destination) + # tav : added a return + return pub.publish(source, destination) --------------------------- --- /home/services/zope/misc/stx/dps/dps/writers/__init__.py Thu Mar 7 04:00:18 2002 +++ __init__.py Fri Mar 22 05:48:27 2002 @@ -18,6 +18,7 @@ import sys from dps import languages from dps.transforms import universal +from types import StringType # tav : see recordfile() class Writer: @@ -53,7 +54,7 @@ self.destination = destination self.transform() self.translate() - self.record() + return self.record() # tav : added a return def transform(self): """Run all of the transforms defined for this Writer.""" @@ -86,6 +87,9 @@ if hasattr(self.destination, 'write'): destination.write(output) elif self.destination: + # tav : added a return output for text.. + if type(self.destination) == StringType: + return output open(self.destination, 'w').write(output) else: sys.stdout.write(output) tav> i patched some of your functions and methods with tav> 'returns' so that the following would work: tav> http://cvs.espnow.com/xnet/xnet/xt_object/render/restx_to_html.py DG> What does ``destination='here'`` mean? Is "here" a DG> throwaway file, or is your patch treating the "here" value DG> specially? as you can see above, when `destination` is a string, recordfile() returns the output instead of writing it to a file or stdout. tav> and, now, i have ran into a third problem... i'd like to mix tav> html and rstx in my original text. DG> That's the purpose of the ".. raw::" directive, not yet DG> implemented. But this should be used only sparingly. I do DG> not intend to allow HTML mixed into reStructuredText DG> without explicit marking. aieee! DG> What are you trying to do? Why mix in HTML? Perhaps DG> there's a better way to do it. Make up a minimal DG> example and I'll take a look. well, there are numerous applications that i'd like to use xt_objects in... from intranets to wikis to weblogs... and, i'd like to use restx as a replacement for the rather incomplete and inconsistent stx in zope. an example usecase would be in a blogging app, where the user might be comfortable with basic html, e.g.: ------------ I had a <b>few ideas</b> for new blogs: - The Bullshit Blog - A community moderated blog rating other blogs ... - The Bookmark Blog - A sidebar blog (similar to BoingBoing's <a href="foo.com">Guestbar blog</a>) ... ------------ in the above example, the user is aware of basic markup such as <b>bold</bold> and <a>anchor</a> tags, but not much else, such as lists, etc ... which is where restx would come in very handy. how does stx co-exist with html? can restx not adapt such a practise? it strikes me that with the exception of the anchor tag, it is actually pretty easy to get html and restx to co-exist. simply apply a reverse of the encode() method on the returned output. (i am sure there are other notable obstacles, but none come to mind right now). however, the anchor tag is very problematic, as: <a href="http://cvs.espnow.com/xnet">xnet cvs</a> would get parsed and converted to: <p><a href="<a class="referencehref="http://cvs.espnow.com/xnet">http://cvs.espnow.com/xnet </a>">xnet cvs</a></p> not pretty. could states.py be adapted to cater for such a situation? DG> BTW, please post to Doc-SIG or the project mailing DG> list in future. doc-sig seems rather inappropriate, so am mailing the restructured-develop list. apologies to those on the list if this mail makes little sense. ;p -- best regards, tav ta...@es... |
From: David G. <go...@us...> - 2002-04-12 02:58:11
|
tav wrote: [re the output of the HTML writer] > if self.output could be controlled by a variable as to whether it > included the headers/footers, that'd be even better. I think I'll keep the document parts separate to some extent, within the Writer object, but leave the access up to client subclasses. In other words, I'll provide the internals, but leave the interface up to you (for now, at least). The "Publisher" class (& "publish()" front-end) are facades, meant to provide convenient access to typical functionality. They are not meant to provide arbitrary functionality. If you want something different, subclass components; you can pass instances of your subclasses to "publish()". > tav> the second problem was with how you "output". the way > tav> the publish() system was setup, one could only output to a > tav> file or stdout. > > DG> The publish function (Publisher class) is a facade, a flat > DG> front-end to the components of the system, meant to provide > DG> enough functionality for 80% of clients. I'm only adding > DG> functionality to the system as it is required, and yours is > DG> the first case where a return value is required, instead of > DG> writing to a file/stream. It may be a case of a new type of > DG> "distribution", which I've thought about but haven't > DG> implemented yet. > > a new type of distribution? "Distributors" are an abstraction I've been mulling over. They're what HappyDoc calls "docsets" (I think). You can distribute the output in multiple ways: - As a single, monolithic file. - As a hierarchy of files & directories. - As a data structure (monolithic or hierarchical). - Others. Each of these types of output would be generated by a different "Distributor" object. I'm not yet sure if it will be useful (or feasible) to keep distributors separate from writers. I'm not worrying about it for now; I still have plenty of research of related projects (HappyDoc etc.) to do first, to see how the problem has been attacked there. > i simply added a couple of returns in core.py and in > writers/__init__.py and finally, in writers/xhtml.py. I looked over them, and I think you can simplify life greatly if you rethink your approach. Instead of inserting "return" statements all over the place, take advantage of the interface, which allows for three types of "destination": (a) a file-like object, which is written directly; (b) a path to a file, which is opened and then written; or (c) `None`, which implies `sys.stdout`. You can get a return value by passing a file-like object as in (a). A StringIO object would do the trick. I may rethink the interface so you don't need StringIO, but not the way you've outlined: > --- /home/services/zope/misc/stx/dps/dps/writers/__init__.py ... > @@ -86,6 +87,9 @@ > if hasattr(self.destination, 'write'): > destination.write(output) > elif self.destination: > + # tav : added a return output for text.. > + if type(self.destination) == StringType: > + return output > open(self.destination, 'w').write(output) > else: > sys.stdout.write(output) ... > as you can see above, when `destination` is a string, recordfile() > returns the output instead of writing it to a file or stdout. Implemented this way, I wouldn't be able write to a file by passing a path (which is a string), which defeats the purpose of the interface as written. [example of mixed HTML & reSructuredText omitted] > how does stx co-exist with html? Classic StructuredText doesn't treat HTML specially, that I recall. StructuredTextNG does; its rules_ specify: - SGML text is ignored and outputed as is. .. _rules: http://dev.zope.org/Members/jim/StructuredTextWiki/StructuredTextNGRules There's a comment by Guido on that page: The rule that SGML (you mean HTML?) text is passed through unchanged is evil, because now we get all sorts of unpredictable interactions between ST and HTML. Plus it's hard to quote examples of HTML markup, which occur very frequently when talking about Zope... I concur wholeheartedly. > can restx not adapt such a practise? No! Or at least, not by me! I'd strongly advise against it, but I can't stop you from trying. > the anchor tag is very problematic, as: > > <a href="http://cvs.espnow.com/xnet">xnet cvs</a> > > would get parsed and converted to: > > <p><a href="<a > class="referencehref="http://cvs.espnow.com/xnet">http://cvs.e > spnow.com/xnet > </a>">xnet cvs</a></p> > > not pretty. All kinds of special-casing would have to be done, and the result would be a quagmire of ambiguity. No thanks. -- David Goodger go...@us... Open-source projects: - Python Docstring Processing System: http://docstring.sourceforge.net - reStructuredText: http://structuredtext.sourceforge.net - The Go Tools Project: http://gotools.sourceforge.net |
From: tav <ta...@es...> - 2002-04-12 09:16:19
|
>>>>> DG == "David Goodger" <go...@us...> wrote: DG> I think I'll keep the document parts separate to some DG> extent, within the Writer object, but leave the access DG> up to client subclasses. ah, nice plan. tav> i simply added a couple of returns in core.py and [snip] DG> I looked over them, and I think you can simplify life greatly DG> if you rethink your approach. Instead of inserting "return" DG> statements all over the place, take advantage of the DG> interface, which allows for three types of "destination": DG> (a) a file-like object, which is written directly; DG> (b) a path to a file, which is opened and then written; or DG> (c) `None`, which implies `sys.stdout`. DG> You can get a return value by passing a file-like object as DG> in (a). A StringIO object would do the trick. i appreciate the interface, and in fact using a tempfile or a stringio object was how i was going to approach it inittially. however, it seemed like pointless overhead, given my singular application. DG> I may rethink the interface so you don't need DG> StringIO, but not the way you've outlined: could you elaborate on how you see it working without a file-like object? and, re the way that i have done it. please pay no heed. it was a quick hack for my needs, and i wasn't suggesting that such a crude approach be taken in the codebase. tav> can restx not adapt such a practise? DG> No! Or at least, not by me! you seem pretty set on this point... can you at least accomodate for a decode() method in the XHTMLTransformer class? tav> the anchor tag is very problematic, as: tav> [snip : example] DG> All kinds of special-casing would have to be done, DG> and the result would be a quagmire of ambiguity. hmz. how could i go about disabling protocol recognition then? i.e. conversion of http://foo.com into a url. thanks btw. -- best regards, tav ta...@es... |
From: David G. <go...@us...> - 2002-04-12 23:52:23
|
> DG> I may rethink the interface so you don't need > DG> StringIO, but not the way you've outlined: tav wrote: > could you elaborate on how you see it working without a file-like object? No, because I don't know yet! :-) [re mixing HTML & reStructuredText] > tav> can restx not adapt such a practise? > > DG> No! Or at least, not by me! > > you seem pretty set on this point... can you at least accomodate for a > decode() method in the XHTMLTransformer class? No, I can't see adding broken functionality to the project. Why don't you just write a decode() function for yourself, and run the processed string through it? > hmz. how could i go about disabling protocol recognition then? i.e. > conversion of http://foo.com into a url. In the short-term, specific case you give, a backslash should do it: \http://foo.com. In the general case, I plan to make the parser modular somehow (don't ask me how, yet), so clients can enable and disable individual construct recognition. It might be as simple as subclassing, or it might be more dynamic. I haven't given it much concrete thought. After the merge (reStructuredText + DPS ==> Docutils), this weekend or next, I want to work on a PEP Reader component, which will require such functionality. I'll know more once that's done. > thanks btw. You're welcome, and thanks for the feedback. -- David Goodger go...@us... Open-source projects: - Python Docstring Processing System: http://docstring.sourceforge.net - reStructuredText: http://structuredtext.sourceforge.net - The Go Tools Project: http://gotools.sourceforge.net |
From: tav <ta...@es...> - 2002-04-13 13:15:17
|
>>>>> DG == "David Goodger" <go...@us...> wrote: tav> could you elaborate on how you see it working without a tav> file-like object? DG> No, because I don't know yet! :-) hehe, fair enough. tav> you seem pretty set on this point... can you at least accomodate tav> for a decode() method in the XHTMLTransformer class? DG> No, I can't see adding broken functionality to the project. DG> Why don't you just write a decode() function for yourself, and DG> run the processed string through it? ah, that's what i do now, and i don't mind doing that. however, i feel that there would be lots of users of restructuredtext, who would appreciate such a method... tav> hmz. how could i go about disabling protocol recognition then? tav> i.e. conversion of http://foo.com into a url. DG> In the short-term, specific case you give, a backslash should DG> do it: \http://foo.com. is there some method that i can alter that will permanently disable the protocol recognition? if you could enlighten me on the protocol disabling, i shalt be a very happy mariner. =) DG> In the general case, I plan to make the parser modular DG> somehow (don't ask me how, yet), so clients can enable and DG> disable individual construct recognition. very nice. if i someday manage to get my head round states.py, i'd love to help out. DG> After the merge (reStructuredText + DPS ==> Docutils), this DG> weekend or next, I want to work on a PEP Reader component, DG> which will require such functionality. I'll know more once DG> that's done. good luck. -- best regards, tav ta...@es... |