From: David A. <da...@bo...> - 2004-06-20 03:15:58
|
I want to test all the code snippets in ReST files that are full of C++ examples. Some of the examples are of course only partials. I've been thinking about implementing a (parsed) literal block extraction writer plus something that processes comments beginning with, say, '@' by executing them as python code... but I don't want to reinvent the wheel. If there's something suitable already hanging around out there, please tell me so! Thanks, Dave -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: Aahz <aa...@py...> - 2004-06-21 14:35:53
|
On Sat, Jun 19, 2004, David Abrahams wrote: > > I want to test all the code snippets in ReST files that are full of > C++ examples. Some of the examples are of course only partials. I've > been thinking about implementing a (parsed) literal block extraction > writer plus something that processes comments beginning with, say, '@' > by executing them as python code... but I don't want to reinvent the > wheel. If there's something suitable already hanging around out > there, please tell me so! What I did was invent my own little ``include-output`` directive for external code -- I think code inside reST files should be kept to a minimum, so that the code is run every time the document is generated. See my sandbox if you're interested. -- Aahz (aa...@py...) <*> http://www.pythoncraft.com/ "Typing is cheap. Thinking is expensive." --Roy Smith, c.l.py |
From: David A. <da...@bo...> - 2004-06-21 18:14:30
|
Aahz <aa...@py...> writes: > On Sat, Jun 19, 2004, David Abrahams wrote: >> >> I want to test all the code snippets in ReST files that are full of >> C++ examples. Some of the examples are of course only partials. I've >> been thinking about implementing a (parsed) literal block extraction >> writer plus something that processes comments beginning with, say, '@' >> by executing them as python code... but I don't want to reinvent the >> wheel. If there's something suitable already hanging around out >> there, please tell me so! > > What I did was invent my own little ``include-output`` directive for > external code -- I think code inside reST files should be kept to a > minimum, so that the code is run every time the document is generated. > See my sandbox if you're interested. Nice, but not what I'm after. Your jobbies insert ReST into the document stream; I'm interested in extracting bits of ReST (in literal blocks) and sending them through compilers, etc. It looks like the .. raw:: litre do.whatever() directive is working pretty well, but I guess it would be a lot terser if I had a custom directive to work with: .. litre:: do.whatever() Maybe I'll look at your code for ways to do that. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: David A. <da...@bo...> - 2004-06-21 22:19:38
|
Aahz <aa...@py...> writes: > What I did was invent my own little ``include-output`` directive for > external code -- I think code inside reST files should be kept to a > minimum, so that the code is run every time the document is generated. > See my sandbox if you're interested. What I'm worried about with adding a directive is that it will trip up ordinary writers unless I go out of my way to make them aware of it. My litre tool uses raw becase that directive is ignored unless the format (litre) is recognized by the writer. I wish I was missing something here; please tell me I am! I'd like to make litre's intrusion on my ReST as minimal as possible. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: Aahz <aa...@py...> - 2004-06-22 00:18:42
|
On Mon, Jun 21, 2004, David Abrahams wrote: > Aahz <aa...@py...> writes: >> >> What I did was invent my own little ``include-output`` directive for >> external code -- I think code inside reST files should be kept to a >> minimum, so that the code is run every time the document is generated. >> See my sandbox if you're interested. > > What I'm worried about with adding a directive is that it will trip up > ordinary writers unless I go out of my way to make them aware of it. > My litre tool uses raw becase that directive is ignored unless the > format (litre) is recognized by the writer. I wish I was missing > something here; please tell me I am! I'd like to make litre's > intrusion on my ReST as minimal as possible. If that's your goal, make sure that the ``litre`` directive emits only elements found in nodes.py. IOW, make the ``litre`` directive a subclass of the ``literal`` directive. -- Aahz (aa...@py...) <*> http://www.pythoncraft.com/ "Typing is cheap. Thinking is expensive." --Roy Smith, c.l.py |
From: David A. <da...@bo...> - 2004-06-22 03:35:35
|
Aahz <aa...@py...> writes: > On Mon, Jun 21, 2004, David Abrahams wrote: >> Aahz <aa...@py...> writes: >>> >>> What I did was invent my own little ``include-output`` directive for >>> external code -- I think code inside reST files should be kept to a >>> minimum, so that the code is run every time the document is generated. >>> See my sandbox if you're interested. >> >> What I'm worried about with adding a directive is that it will trip up >> ordinary writers unless I go out of my way to make them aware of it. >> My litre tool uses raw becase that directive is ignored unless the >> format (litre) is recognized by the writer. I wish I was missing >> something here; please tell me I am! I'd like to make litre's >> intrusion on my ReST as minimal as possible. > > If that's your goal, make sure that the ``litre`` directive emits only > elements found in nodes.py. IOW, make the ``litre`` directive a > subclass of the ``literal`` directive. Aaaaahz! Very cute trick. But then, how will my writer recognize my litre-generated literal nodes? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: Aahz <aa...@py...> - 2004-06-22 03:47:19
|
On Mon, Jun 21, 2004, David Abrahams wrote: > Aahz <aa...@py...> writes: >> >> If that's your goal, make sure that the ``litre`` directive emits only >> elements found in nodes.py. IOW, make the ``litre`` directive a >> subclass of the ``literal`` directive. > > But then, how will my writer recognize my litre-generated literal > nodes? Why should it care how they were generated? -- Aahz (aa...@py...) <*> http://www.pythoncraft.com/ "Typing is cheap. Thinking is expensive." --Roy Smith, c.l.py |
From: David A. <da...@bo...> - 2004-06-22 23:26:09
|
David Abrahams <da...@bo...> writes: > compile(2); # compile the last two literal blocks together > > That is, *mlt*\ :sup:`-2`. However, if we want to get dimensions into the > type system these arrays won't do the trick: they're all > the same type! Instead we need types that *themselves* represent > sequences of numbers, so that two masses have the same type and a > mass is a different type from a length. > > > That compile(2) isn't Python's usual compile. It invokes a C++ > compiler on some subset of the examples the writer has seen before. Err, but it is Python code. The semicolon is just an artifact from bouncing back and forth between languages too quickly ;-) -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: <eng...@ss...> - 2004-06-22 06:11:18
|
On Mon, 21 Jun 2004, David Abrahams wrote: > Aahz <aa...@py...> writes: > > > On Mon, Jun 21, 2004, David Abrahams wrote: > >> Aahz <aa...@py...> writes: > >>> > >>> What I did was invent my own little ``include-output`` directive for > >>> external code -- I think code inside reST files should be kept to a > >>> minimum, so that the code is run every time the document is generated. > >>> See my sandbox if you're interested. > >> > >> What I'm worried about with adding a directive is that it will trip up > >> ordinary writers unless I go out of my way to make them aware of it. > >> My litre tool uses raw becase that directive is ignored unless the > >> format (litre) is recognized by the writer. I wish I was missing > >> something here; please tell me I am! I'd like to make litre's > >> intrusion on my ReST as minimal as possible. > > > > If that's your goal, make sure that the ``litre`` directive emits only > > elements found in nodes.py. IOW, make the ``litre`` directive a > > subclass of the ``literal`` directive. > > Aaaaahz! > Very cute trick. > > But then, how will my writer recognize my litre-generated literal > nodes? couldnt you check for an attribute in literal nodes (class ?). this way the code parts would be printed literal, and not ignored by other writers. a feature not a bug ? -- BINGO: objects, objects, objects (r.racko) --- Engelbert Gruber -------+ SSG Fintl,Gruber,Lassnig / A6170 Zirl Innweg 5b / Tel. ++43-5238-93535 ---+ |
From: David A. <da...@bo...> - 2004-06-22 22:37:13
|
eng...@ss... writes: > On Mon, 21 Jun 2004, David Abrahams wrote: > >> Aahz <aa...@py...> writes: >> >> > On Mon, Jun 21, 2004, David Abrahams wrote: >> >> Aahz <aa...@py...> writes: >> >>> >> >>> What I did was invent my own little ``include-output`` directive for >> >>> external code -- I think code inside reST files should be kept to a >> >>> minimum, so that the code is run every time the document is generated. >> >>> See my sandbox if you're interested. >> >> >> >> What I'm worried about with adding a directive is that it will trip up >> >> ordinary writers unless I go out of my way to make them aware of it. >> >> My litre tool uses raw becase that directive is ignored unless the >> >> format (litre) is recognized by the writer. I wish I was missing >> >> something here; please tell me I am! I'd like to make litre's >> >> intrusion on my ReST as minimal as possible. >> > >> > If that's your goal, make sure that the ``litre`` directive emits only >> > elements found in nodes.py. IOW, make the ``litre`` directive a >> > subclass of the ``literal`` directive. >> >> Aaaaahz! >> Very cute trick. >> >> But then, how will my writer recognize my litre-generated literal >> nodes? > > couldnt you check for an attribute in literal nodes (class ?). > > this way the code parts would be printed literal, and not ignored by > other writers. a feature not a bug ? I'm not worried about the literal blocks *themselves*; all literal blocks are getting handled by litre _right now_. I need to stick in material that every other writer will ignore. For example, here's a snippet from the book, with embedded litre: In general, a composite dimension is the product of powers of fundamental dimensions [#divisor]_. If we were going to represent these powers for manipulation at runtime, we could use an array of seven ``int``\ s, with each position in the array holding the power of a different fundamental dimension:: typedef int dimension[7]; // m l t ... dimension const mass = {1, 0, 0, 0, 0, 0, 0}; dimension const length = {0, 1, 0, 0, 0, 0, 0}; dimension const time = {0, 0, 1, 0, 0, 0, 0}; ... .. [#divisor] divisors just contribute negative exponents, since 1/*x* = *x*\ :sup:`-1`. In that representation, force would be:: dimension const force = {1, 1, -2, 0, 0, 0, 0}; .. raw:: litre compile(2); # compile the last two literal blocks together That is, *mlt*\ :sup:`-2`. However, if we want to get dimensions into the type system these arrays won't do the trick: they're all the same type! Instead we need types that *themselves* represent sequences of numbers, so that two masses have the same type and a mass is a different type from a length. That compile(2) isn't Python's usual compile. It invokes a C++ compiler on some subset of the examples the writer has seen before. By using a .. raw:: block I accomplish the following: 1. Other writers will be utterly undisturbed by the invocation of compile. They will ignore the raw block because it isn't for them. 2. I don't need to do anything special (such as installing a directive) before using a different kind of writer on my ReST. As far as I know, there's no other syntax besides comments that can be hijacked in this way. Now, maybe it would be a good idea to hijack comments. .. @compile(2) would be a whole lot terser, that's for sure. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: David G. <go...@py...> - 2004-06-23 02:14:53
|
I just remembered something that should be useful to you. You've been using the "raw" directive to get litre-specific output, like this: .. raw:: litre do.whatever() But that's really kind of abusing the system. Even better would be like this: .. litre:: do.whatever() But how to identify the content as Litre-specific without confusing all the other Writers? There's a comparable case with another directive: "meta". It's a directive that produces output for HTML only. The way it works is like this (it's tricky, so please bear with me): * The docutils.parsers.rst.directives.html.meta directive function hands off parsing to a special-purpose d.p.r.states.SpecializedBody subclass, MetaBody, which parses a field list. Don't worry about the details. * The MetaBody.parsemeta method constructs a "pending" node. From docutils.nodes: The "pending" element is used to encapsulate a pending operation: the operation (transform), the point at which to apply it, and any data it requires. Only the pending operation's location within the document is stored in the public document tree (by the "pending" object itself); the operation and its data are stored in the "pending" object's internal instance attributes. For example, say you want a table of contents in your reStructuredText document. The easiest way to specify where to put it is from within the document, with a directive:: .. contents:: But the "contents" directive can't do its work until the entire document has been parsed and possibly transformed to some extent. So the directive code leaves a placeholder behind that will trigger the second phase of its processing, something like this:: <pending ...public attributes...> + internal attributes Use `document.note_pending()` so that the `docutils.transforms.Transformer` stage of processing can run all pending transforms. docutils.nodes.pending has the following initializer: def __init__(self, transform, details=None, rawsource='', *children, **attributes): The first two are special: a docutils.transforms.Transform class implementing the pending operation, and detail data (dictionary) required by the pending operation. The "meta" directive constructs a "pending" node like this: pending = nodes.pending(components.Filter, {'component': 'writer', 'format': 'html', 'nodes': [node]}) ``node`` is a "meta" node, defined locally, and only known to the HTML Writer. Your "litre" directive could construct a "pending" node in exactly the same way, but with format 'litre' instead of 'html'. Your ``node`` would be the ``litre`` directive's content, as a literal block or a litre-specific node of your own making. * The transform in the last step is the key: docutils.transforms.components.Filter. From its docstring: Include or exclude elements which depend on a specific Docutils component. For use with `nodes.pending` elements. A "pending" element's dictionary attribute ``details`` must contain the keys "component" and "format". The value of ``details['component']`` must match the type name of the component the elements depend on (e.g. "writer"). The value of ``details['format']`` is the name of a specific format or context of that component (e.g. "html"). If the matching Docutils component supports that format or context, the "pending" element is replaced by the contents of ``details['nodes']`` (a list of nodes); otherwise, the "pending" element is removed. For example, the reStructuredText "meta" directive creates a "pending" element containing a "meta" element (in ``pending.details['nodes']``). Only writers (``pending.details['component'] == 'writer'``) supporting the "html" format (``pending.details['format'] == 'html'``) will include the "meta" element; it will be deleted from the output of all other writers. You indicate what format your writer supports with the ``supported`` class attribute, a list of strings to match against. The end result is, the contents of pending.details['nodes'] will be included for your Litre Writer, but removed for any other Writer. The "pending" node basically hides the Writer-specific stuff until the Filter transform (which is applied late in the game) can expose it safely. Get it? I'd be pleasantly surprised if you did, first time; I always have to read through the docstrings a couple of times to get all the connections straight. Read it through again, maybe twice, then ask away. -- David Goodger <http://python.net/~goodger> |
From: David A. <da...@bo...> - 2004-06-23 03:05:07
|
David Goodger <go...@py...> writes: > Get it? I'd be pleasantly surprised if you did, first time; I always > have to read through the docstrings a couple of times to get all the > connections straight. Read it through again, maybe twice, then ask > away. Not yet. Tell you what, though: you're going to have a hard time convincing me it's worth trying to do that, now that I have this beautiful comment interpretation syntax: .. @ example.append('typedef two_pointers<int>::type intstar2;') compile(all = True, expect_error = True, save = -1) I'm so pleased with the system now that I think I'd rather fight than switch ;-) -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |
From: David G. <go...@py...> - 2004-06-23 03:13:30
|
David Abrahams wrote: > Not yet. Tell you what, though: you're going to have a hard time > convincing me it's worth trying to do that, now that I have this > beautiful comment interpretation syntax: > > .. @ example.append('typedef two_pointers<int>::type intstar2;') > compile(all = True, expect_error = True, save = -1) > > I'm so pleased with the system now that I think I'd rather fight > than switch ;-) Just don't try to check that into the codebase! :-) In sandboxes anything goes, of course. -- David Goodger <http://python.net/~goodger> |
From: David A. <da...@bo...> - 2004-06-23 03:16:06
|
David Goodger <go...@py...> writes: > David Abrahams wrote: > > Not yet. Tell you what, though: you're going to have a hard time > > convincing me it's worth trying to do that, now that I have this > > beautiful comment interpretation syntax: > > > > .. @ example.append('typedef two_pointers<int>::type intstar2;') > > compile(all = True, expect_error = True, save = -1) > > > > I'm so pleased with the system now that I think I'd rather fight > > than switch ;-) > > Just don't try to check that into the codebase! :-) > In sandboxes anything goes, of course. It's totally non-intrusive. I don't have the slightest desire to put it in your repository! -- Dave Abrahams Boost Consulting http://www.boost-consulting.com |