Skip to content

Conversation

kernc
Copy link
Contributor

@kernc kernc commented Nov 24, 2014

The Meta extension currenly only supports extended RFC822-style headers.

Another ubiquitous meta-data format, even prevalent perhaps when it comes to *.md files, is YAML. Pandoc supports YAML metadata, Jekyll uses it.

It'd be nice if this markdown implementation also supported YAML meta data. Making a plugin is an option, but the only existing plugin seems to not work at all and break the established API.

It'd make some sense to have YAML meta-data supported out-of-the-box. Please let me know what you think. With heads up, I'll be happy to further write tests and document the addition.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.95%) when pulling a21c92d on kernc:meta_yaml into c04d2c9 on waylan:master.

@waylan
Copy link
Member

waylan commented Nov 25, 2014

I have a number of concerns about this.

First, the existing tests are failing. That needs to be fixed. And where's the tests and documentation of the few features?

But before we get to that, why can't this be a seperate extension? And why would I use YAML to define structured data and then throw all that away? The existing meta-data extension has no idea of data types and that's why it returns everything as a list of strings. But with YAML I get type inference that works for free. If I'm using YAML, I want to keep that. Seems to me a seperate extension with a different API makes more sense.

That said, I realize that various existing projects (Pelican, MkDocs, etc.) use the existing extension and (type ignorant) API. I suppose one might be interested in using YAML with such a framework without the need to hack the framework, which this would accomplish. That said, if after carefully crafting my YAML meta-data with a give type, that type is thrown out and a different type is assigned by the framework, I would find that extremely annoying.

I could go either way on this. In fact, as I have recently been playing with some of these frameworks that use the existing extension, I was thInking that it might be useful to provide a way to assign a given type to a specific name. Perhaps when loading the extension, a set of key-value pairs could be passed in as configs that define a type for given key names in the meta data. Something like {title: string, date: datetime, summary: multiline}. That way, the returned data would already be of the give type. I may reach out to the developers of some of these frameworks for some feedback. Not sure how adding YAML support fits into that. I'll have to chew on that.

@waylan
Copy link
Member

waylan commented Nov 25, 2014

After thinking on this, I believe the best approach is to follow MultiMarkdown's lead and optionally allow the YAML deliminators (--- & ...), but not actually use YAML to parse the content. That way, YAML would still be able to parse the content (in implementations that support YAML), but our implementation/API would not change any (and would avoid a third-party dependency).

I suppose we could also add a config option to turn on YAML parsing which should return the data as YAML parses it. But the default would be to have that feature turned off (for backward compatibility) even when the YAML deliminators are present.

That way, existing frameworks will continue to work as-is, and their users could even add the YAML deliminators (which cause the metadata to get rendered as a table by GitHub for example). And, if any framework actually wants to have real YAML parsing, they can turn on the YAML parsing and get structured data. In fact, I like that better that providing an API to define types for the current implementation (as I suggested in my previous comment). if you want structured data, turn on YAML and if you want raw data (the current API), turn off YAML---either way we should still support the YAML deliminators.

@kernc kernc force-pushed the meta_yaml branch 2 times, most recently from 884de30 to 499cea2 Compare November 25, 2014 23:12
@kernc
Copy link
Contributor Author

kernc commented Nov 25, 2014

Ok, I agree to what you are saying about retaining structure. Took me 40 minutes yesterday to figure out it's by design I can't force-load YAML as pure strings. 😃

So, is something like this (PR updated) what you had in mind? The dependency on PyYAML is a soft one, required only if YAML is enabled.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.42%) when pulling 499cea2 on kernc:meta_yaml into c04d2c9 on waylan:master.

@waylan
Copy link
Member

waylan commented Nov 26, 2014

Not exactly. You added support for YAML, but you did not add support for the YAML deliminators when YAML is not turned on---which should just be a couple more lines of code.

Also, let's not import yaml within the method. I'd prefer to import at the module level and if it fails assign False to it. Something like:

try:
    import yaml
except ImportError:
    yaml = False

# then later in the method:

        if self.config['yaml'] and yaml ...

Also, lets call the config key 'yaml', no reason to make it so lengthy.

@kernc
Copy link
Contributor Author

kernc commented Nov 26, 2014

So if YAML is not turned on, what happens, the YAML header is just skipped?

And regarding

        if self.config['yaml'] and yaml

If YAML is requested but yaml is not available, the extension shouldn't pass that silently, correct?

@kernc
Copy link
Contributor Author

kernc commented Nov 26, 2014

Oh, I get it. You want to enable just skipping --- regardless of what mode is on. Then, if YAML is disabled, just parse the contents between --- as regular meta data. On it!

Update: But what if a YAML header, say a multi-level or a list example of it, is unparsable as simple meta-data (when parsing YAML is disabled)?

@waylan
Copy link
Member

waylan commented Nov 26, 2014

The contents of a document should never cause the parser to raise an error (we can't be crashing web servers---the libraries most common use case). Your implementation would raise an error only when a document contained YAML but the yaml lib was not available. However, the error would only occur when trying to parse the document (not on class initialization). Using my suggested method, the parser doesn't raise an error---the results are just not what was expected. Perhaps not as easy to debug---but good documentation should address that.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.29%) when pulling 92ba322 on kernc:meta_yaml into c04d2c9 on waylan:master.

@kernc
Copy link
Contributor Author

kernc commented Nov 27, 2014

Ok, how about now? Not crashing anywhere, only a warning is logged iff YAML parsing is enabled and a YAML-header'd document is encountered and yaml is unavailable.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.29%) when pulling 3b9fe5b on kernc:meta_yaml into c04d2c9 on waylan:master.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we be passing the configs into the Class on initiation? Like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dunno. Inspecting all the built-in extensions, I've seen examples of both, and more. This way, we avoid one thin __init__(). Since this isn't functional programming and since MetaPreprocessor and MetaExtension are tangled one way or another, doesn't really matter IMHO. Unless you have a preference. ¯_(ツ)_/¯

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is my preference. It makes for easier to read code later and it is the way the API is designed to work. If other extensions don't follow this pattern, they should be updated--unless there is a good reason not to of course.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. FTR, the given wikilinks example sets md attribute exactly the same way:

        wikilinkPattern.md = md

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling 5b99a2a on kernc:meta_yaml into c04d2c9 on waylan:master.

@kernc
Copy link
Contributor Author

kernc commented Nov 29, 2014

Whaddya think? 😃

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling 79c5184 on kernc:meta_yaml into c04d2c9 on waylan:master.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's leave this test as-is and add a seperate test with the YAML deliminators. That way we have a test for each possible scenario.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling 93dbf9b on kernc:meta_yaml into c04d2c9 on waylan:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling 93dbf9b on kernc:meta_yaml into c04d2c9 on waylan:master.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed this before. This way of passing config options into extensions is pending deprecation. I realize some existing tests still use this, but let's not add any more. We'll just have to change it before the next release anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, no problem. Hope now is fine?

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling af84cd2 on kernc:meta_yaml into c04d2c9 on waylan:master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.1%) when pulling 53f0e44 on kernc:meta_yaml into c04d2c9 on waylan:master.

@waylan
Copy link
Member

waylan commented Dec 1, 2014

@kernc thanks for the work on this. I just merged your work with a couple minor changes.

@waylan waylan closed this Dec 1, 2014
@kernc
Copy link
Contributor Author

kernc commented Dec 1, 2014

Yay, thanks! 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants