Preserve front matter ordering
See original GitHub issueIt’s a tricky thing to do with PyYAML, but using http://stackoverflow.com/a/21048064/5483904 it’s possible. Once you fix the loader up, the things that stand in the way are:
parse
takes in defaults as**kwargs
, which is automatically a dict. Additionally, you can’t specify a custom loader, so you have to set it globally.- Once you fix that,
Post.__init__
takes the metadata as**kwargs
yet again, which destroys the ordered dict received by the prior function
I suspect to really do this, one would have to break backwards compat. Here’s my hacky way of accomplishing this in case anyone else wants this Right Now:
# Patch yaml first
import collections
import yaml
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
def dict_representer(dumper, data):
return dumper.represent_dict(data.items())
def dict_constructor(loader, node):
loader.flatten_mapping(node)
return collections.OrderedDict(loader.construct_pairs(node))
try:
yaml.CSafeDumper.add_representer(collections.OrderedDict, dict_representer)
except ImportError:
pass
yaml.SafeDumper.add_representer(collections.OrderedDict, dict_representer)
yaml.SafeLoader.add_constructor(_mapping_tag, dict_constructor)
# patch frontmatter second
import frontmatter
def _parse(text, **defaults):
text = frontmatter.u(text)
# metadata starts with defaults
metadata = defaults.copy()
try:
_, fm, content = frontmatter.FM_BOUNDARY.split(text, 2)
except ValueError:
return metadata, text
fm = yaml.safe_load(fm)
if isinstance(fm, dict):
fm.update(metadata)
metadata = fm
return metadata, content.strip()
def _loads(text, **defaults):
metadata, content = _parse(text, **defaults)
post = frontmatter.Post(content)
post.metadata = metadata
return post
frontmatter.parse = _parse
frontmatter.loads = _loads
Issue Analytics
- State:
- Created 7 years ago
- Reactions:2
- Comments:14 (4 by maintainers)
Top Results From Across the Web
Best Practices: Front Matter for eBooks by Section
There aren't any definitive rules for how the different sections of front matter in an eBook should be organized, and it is very...
Read more >Book front matter elements - Book Design Made Simple
The usual order of book front matter elements · Half (or “bastard”) title page · Frontispiece · Title page (required) · Copyright page...
Read more >Create and Edit Front Matter - Pressbooks User Guide
Add a number to the Order input in Front Matter Attributes to control its ... Click the 'Save' button. ... Understand Front Matter...
Read more >The Front Matter: A Breakdown | Book Design
The “front matter” of a book includes the title page, copyright page, dedication, table of contents, foreword or preface, and introduction.
Read more >Front Matter and Back Matter [The Only Guide You Need]
“Front matter” and “back matter” are terms used to describe the first and last pages of a book (but not the actual story...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’ve managed to get order preserving frontmatter! The quick version is:
sort_keys=False
tofrontmatter.dump
iefrontmatter.dump(post, f, sort_keys=False)
Since python 3.7 insertion order for dicts are maintained (no OrderedDict needed) and since then PyYaml have added the option to not sort keys when dumping. kwargs is passed to handler.export, which is passed to
yaml.dump
and things just work!I’m happy if anyone has a PR that can solve this. For anything in the core library, updates should be added at the handler level.