Skip to content
This repository has been archived by the owner on Jan 25, 2019. It is now read-only.

reStructuredText rendering errors don't show filename, just "string" #144

Open
matt-garman opened this issue Nov 17, 2015 · 6 comments
Open

Comments

@matt-garman
Copy link
Contributor

If my reStructuredText source document has an error, the filename is not printed, only "string". For example:

<string>:29: (ERROR/3) Unexpected indentation.

I'm not sure if this happens with other renderers too, I currently only use RST.

In renderers.py, for the ReStructuredText implementation, there is a call to docutils.core.publish_parts() (line 92). This function takes an optional parameter, "source_path", which is currently not used by Wok. Whatever this is set to will be displayed when there is an error, instead of the ambiguous "string" (as shown above). Both the documentation and my experimentation suggest this variable is for display purposes only, i.e. it doesn't actually try to reference that variable as a file.

I think this is a relatively easy fix: to the generic Renderer.render() function, I could add an additional optional variable that defaults to None. This variable would be "source_path" (or "source_filename" or even "slug"), and if set, would be passed through to the the underlying renderer if supported.

Maybe there's a better/cleaner way to do this that is less "invasive" to the API? I'm happy to work on this, but would like a little guidance on the best route to take. Thanks!

@edunham
Copy link
Collaborator

edunham commented Nov 17, 2015

Thanks for the issue report! I think adding the source_path sounds like a reasonable fix.

@mythmon thoughts on that solution?

@mythmon
Copy link
Owner

mythmon commented Nov 17, 2015

This doesn't seem invasive to the API to me. I like the idea of adding the source_path argument to the render function. That's what it is there for, after all.

@matt-garman, if you'd like to file a PR for those changes, that would be awesome 🎆. Otherwise, I'm sure someone will get to it at some point.

@matt-garman
Copy link
Contributor Author

Thank you for the quick feedback! I should be able to come up with a PR fairly soon.

Another idea: the render() function could be changed to take an object; and that object would initially contain the to-be-rendered text plus the source filename. If ever more metadata is to be passed to the underlying renderers, this might be a little cleaner (or maybe messier, depending on your perspective ;)).

Sorry, I accidentally closed this, re-opening.

@matt-garman matt-garman reopened this Nov 17, 2015
@matt-garman
Copy link
Contributor Author

This is in theory easy to implement, but I'm getting hung up on something that doesn't make sense to me. In renderers.py, I simply added a "source_path=None" argument to all render() definitions. And then in page.py, for the from_file() function, I modified the content rendering line like this:

page.meta['content'] = page.renderer.render(page.original, source_path=page.path)

It works as expected for everything in the test_site, except the html_renderer.html page, where it blows up with this:

Traceback (most recent call last):
  File "/home/matt/development/web/virtualenv/wok/bin/wok", line 5, in <module>
    pkg_resources.run_script('wok==1.1.1', 'wok')
  File "/home/matt/development/web/virtualenv/wok/lib/python2.7/site-packages/pkg_resources.py", line 540, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/home/matt/development/web/virtualenv/wok/lib/python2.7/site-packages/pkg_resources.py", line 1462, in run_script
    exec_(script_code, namespace, namespace)
  File "/home/matt/development/web/virtualenv/wok/lib/python2.7/site-packages/pkg_resources.py", line 41, in exec_
    exec("""exec code in globs, locs""")
  File "<string>", line 1, in <module>
  File "/home/matt/development/web/virtualenv/wok/lib/python2.7/site-packages/wok-1.1.1-py2.7.egg/EGG-INFO/scripts/wok", line 4, in <module>
    import pkg_resources
  File "build/bdist.linux-x86_64/egg/wok/engine.py", line 151, in __init__
  File "build/bdist.linux-x86_64/egg/wok/engine.py", line 189, in generate_site
  File "build/bdist.linux-x86_64/egg/wok/engine.py", line 369, in load_pages
  File "build/bdist.linux-x86_64/egg/wok/page.py", line 123, in from_file
TypeError: render() got an unexpected keyword argument 'source_path'

So just before the render() call I added some prints:

        print "DEBUG: page.path=\"" + str(page.path) + "\""
        print "DEBUG: page.renderer=\"" + str(page.renderer) + "\""
        print "DEBUG: page.renderer.render=\"" + str(page.renderer.render) + "\""

For the stuff that works, the output of these prints is predictable:

DEBUG: page.path="content/tests/dates3.mkd"
DEBUG: page.renderer="<class 'wok.renderers.Markdown'>"
DEBUG: page.renderer.render="<bound method type.render of <class 'wok.renderers$Markdown'>>"

But for the html file, it shows this:

DEBUG: page.path="content/tests/html_renderer.html"
DEBUG: page.renderer="<class '__renderers__.'>"
DEBUG: page.renderer.render="<function render at 0x15917d0>"

I don't really understand where this "function render at 0x15917d0" actually lives in the source.

Any thoughts?

Thanks!

@mythmon
Copy link
Owner

mythmon commented Nov 29, 2015

Needing to add source_path=None to all the calls seems wrong. I think it would be better to make the renderer that cares about paths have a source_path parameter that defaults to None. For calls that don't care about the source path, they can leave it out. Then you can add it back in only for the code paths that need it.

I'm not quite sure what could cause the errors you talk about though. I think it would be better to post a PR with your code in it, even if the code is unfinished. Talking about this error will be easier when we can all see the code.

Thanks for the work on this!

matt-garman added a commit to matt-garman/wok that referenced this issue Nov 30, 2015
render() definitions so it can be passed through to the actual RST
docutils renderer.

This code fails on the test site, and has some debug print
statements added.  It is intended as an illustration only,
definitely not production quality.
@matt-garman
Copy link
Contributor Author

Needing to add source_path=None to all the calls seems wrong. I think it would be better to make the renderer that cares about paths have a source_path parameter that defaults to None. For calls that don't care about the source path, they can leave it out. Then you can add it back in only for the code paths that need it.

I agree, but I don't see how this is possible without more dramatic changes to the code.

The Renderer class (and all sub-classes) defines the render() function as static (@classmethod). Every page object has a renderer member defined by its extension. When the page.renderer.render() function is actually called, it's not known if source_path is needed or not. IOW, to use the source_path parameter at this point, the filename extension check would have to be re-done which to me also seems wrong.

Here's another idea, though it's much more substantial in scope: change render() to be non-static. Create something like a factory that will produce a Renderer object based on filename extension, on a per-page basis (i.e. each page has its own Renderer instance). The ReStructuredText Renderer class can have a source_path member which will be set when instantiated (i.e. by the factory).

I'm not quite sure what could cause the errors you talk about though. I think it would be better to post a PR with your code in it, even if the code is unfinished. Talking about this error will be easier when we can all see the code.

Done! Hopefully some of what I wrote above will make more sense in light of the PR code.

Thanks for the work on this!

You are welcome, though I feel like I'm creating more work for you! :)

matt-garman added a commit to matt-garman/wok that referenced this issue Dec 15, 2015
Issue mythmon#144: reStructuredText rendering errors don't show filename,
just "string".  The actual ReST renderer,
docutils.core.publish_parts(), supports a "source_path" parameter,
which can be used to set the filename of the rendered file.  With
this paramter set, in case of error, the filename will be shown
instead of just "<string>".

This fix fundamentally modifies the structure of the
wok/renderers.py module.  Previously, all render() functions were
defined as classmethods.  This change makes them instance methods.
Each page object gets assigned its own Renderer instance.  For the
ReStructuredText renderer, an optional source_path parameter is
allowed by the constructor.  If set, this will be stored with the
instance, and passed on to the docutils function.

A new function is introduced in wok/renderers.py: factory().  This
is called in wok/engine.py when the renderer is assigned to the
page.  This does the work of looking at all available renderers, and
matching the filename extention to the appropriate renderer, and
returning a valid object instance.
matt-garman added a commit to matt-garman/wok that referenced this issue Dec 16, 2015
- Add file "test_site/wok_expected_output-test_site" which is the
  output of "wok -v" when run with current upstream master.
- Introduce new environment variable "CMP_OUTPUT" in .travis.yml.
- Enhance bin/site-tests such that if CMP_OUTPUT==true, it will run
  cmp on the wok_expected_output-$TEST_SITE file versus the output
  of the "wok -v" run.
- Goal of this enhancement is to support more robust testing of
  fixes for issues mythmon#144 and mythmon#145.
matt-garman added a commit to matt-garman/wok that referenced this issue Dec 16, 2015
This was a known-bad commit just to illustrate a problem.  A bad way
to fix issue mythmon#144 (add source_path param to all render() methods in
wok/renderers.py).  Removing to clean up.

This reverts commit 7cf34e2.
edunham pushed a commit to edunham/wok that referenced this issue Nov 15, 2016
- Add file "test_site/wok_expected_output-test_site" which is the
  output of "wok -v" when run with current upstream master.
- Introduce new environment variable "CMP_OUTPUT" in .travis.yml.
- Enhance bin/site-tests such that if CMP_OUTPUT==true, it will run
  cmp on the wok_expected_output-$TEST_SITE file versus the output
  of the "wok -v" run.
- Goal of this enhancement is to support more robust testing of
  fixes for issues mythmon#144 and mythmon#145.
edunham pushed a commit to edunham/wok that referenced this issue Nov 15, 2016
This was a known-bad commit just to illustrate a problem.  A bad way
to fix issue mythmon#144 (add source_path param to all render() methods in
wok/renderers.py).  Removing to clean up.

This reverts commit 7cf34e2.
matt-garman added a commit to matt-garman/wok that referenced this issue Jun 28, 2017
The reStructuredText render will pass use this metadata if availbe,
and pass through to the source_path parameter in publich_parts.
This is to fix issue mythmon#144.
matt-garman added a commit to matt-garman/wok that referenced this issue Jun 28, 2017
docutils.core.publish_parts() source_path parameter.  This is to fix
issue mythmon#144.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants