-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support for YAML front matter #485
Comments
How exactly do you envision this working? The front matter is metadata for a document, which doesn't fit into the return value for a parsed document, which results in just text. This is really a task that needs to be delegated to whatever software is using marked. |
First, set an option to return an object rather than just text. If a front matter section is present, Marked could return an object like this: {
meta: {},
content: ""
} If there is no front matter, it would just return {
content: ""
} |
This really seems out of scope for marked, but I'll wait for @chjj to respond. |
I hear that. I just see a few markdown processors supporting meta data, and it's pretty useful to be able to include it. On Wed, Sep 10, 2014 at 2:29 PM, Scott González notifications@github.com
|
I certainly agree that the pattern itself is showing to be very useful and quite popular. It makes writing documentation and building sites with Markdown a very sane process. If you plan to use the meta data as an object with your template engine, why not just ready it in one swoop as you parse the document string. Maybe even support HJSON as well? Though following the UNIX philosophy it would make more sense of there was another project that took the parsed Markdown and went from there. If you think about how Jekyll uses it.... it does allow HTML as well. |
I just ran into a similar problem where I needed to separate YAML front matter from the markdown content. I ended up using the YAML Front Matter module. Seems to cover this use case pretty well. |
So, the situ on is to "pre-process" the .md file before sending it to the client? I guess if that is out of the scope of what marked is trying to do, that's fine. I think it would still be great to have support for at least removing meta data. On Mon, Oct 6, 2014 at 11:48 AM, Ian Sinnott notifications@github.com
|
IMO it's out of scope. I've had gulp pipelines like this: gulp.src('*.md')
.pipe(gulpFrontMatter()) // stores the front matter object on the File object and removes it from each file contents
.pipe(gulpMarkdown()) // convert to HTML, metadata is still accessible
.pipe(gulp.dest('./ouput')) // store HTML
.pipe(es.map(function(file){
console.log(file.frontMatter.hello); // stupid example
}); It should be removed before hand. |
It's been a year but github is currently parsing front matter into a table. Now that this is part of the official GFM parsing, I think we should put it into marked (into gfm) as well. Front matter:
|
@dvcrn if GitHub was, you wouldn't need to use an image as an example right? 😜 |
Nice catch! @dvcrn ! @adam-lynch click the other link. You can see it at the top of that page. |
Elliott, thanks :). Weird how they render markdown differently here hmm On Fri, 23 Oct 2015, 17:13 Elliott Regan notifications@github.com wrote:
|
They don't mention it in their docs, but they are definitely showing key-values, even complex ones with arrays, as a table. I still prefer JSON because it's easier to work with, but it makes sense for Github to display it Asa table. |
It's probably just left out because it's unrelated to their markdown parser. See https://github.com/blog/1647-viewing-yaml-metadata-in-your-documents |
FYI if people are still looking, @adam-lynch's comment here is conceptually the way to go. In terms of implementation, metalsmith is really great for this type of thing, and includes a metalsmith-markdown plugin that is built on top of marked. When used in combination with metalsmith-layouts, you can do some really cool things. For example (in a function build() {
var files = ['source/**', '!source/layouts/**', '!source/partials/**'];
return gulp
.src(files)
.pipe(metalsmith({
use: [
markdown(), // from `metalsmith-markdown` (`marked` wrapper)
layouts({ // from `metalsmith-layouts`
engine: 'handlebars', // any engine from consolidate.js
default: 'page.html',
directory: 'source/layouts',
partials: 'source/partials',
pattern: '**/*.html'
})
]
}))
.pipe(gulp.dest('build'));
}
Example
Example <!DOCTYPE html>
<html>
<body>
<h1>{{title}}</h1>
<main>{{{contents}}}</main>
</body>
</html> Outputs ( <!DOCTYPE html>
<html>
<body>
<h1>Documentation - 4.2.1</h1>
<main>
<ul>
<li>some</li>
<li>list</li>
</ul>
<p>some content</p>
</main>
</body>
</html> None of this would be possible without the work by @chjj and team, so thanks for that. I originally came here looking for answers, so hopefully this helps the next guy/gal. Cheers. |
See #956 Closing as out of scope for the two targeted specifications of Marked. |
:( but that makes sense. |
Memo for browser 😆 <div id="content"></div>
<script src="https://unpkg.com/marked/marked.min.js"></script>
<script src="https://unpkg.com/js-yaml@3/dist/js-yaml.js"></script>
<script src="https://unpkg.com/yaml-front-matter@4/dist/yamlFront.js"></script>
<script>
let cached_lex = marked.Lexer.lex
marked.Lexer.lex = function (text, options) {
let parsed = yamlFront.loadFront(text)
let cKey = '__content'
let table = [
[],
[],
[]
]
for (let k in parsed) {
if (k === cKey) {
continue
}
table[0].push(k)
table[1].push('---')
table[2].push(parsed[k])
}
let tableMd = table.map(row => row.join('|')).join('\n')
return cached_lex(tableMd + '\n' + parsed[cKey], options)
}
</script>
<script src="https://unpkg.com/jquery@3/dist/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.get('https://raw.githubusercontent.com/vuejs/vuejs.org/master/src/v2/examples/index.md', function(str) {
$("#content").html(marked(str));
});
});
</script> |
I want to ignore frontmatter for my scenario. Here is how I do it:
|
You can also use front-matter to get any edge cases. md = frontMatter(md).body; |
I came across a case where I do want the rendered output from my markdown to be handled differently based on the front matter. My use case is too niche to describe, but suppose we want to handle the case where we want to prefix some text to the beginning of headers, such that: ---
headingPrefix: Chapter:
---
# Some things I was thinking
These are some things I was thinking... would become <h1>Chapter: Some things I was thinking</h1>
<p>These are some things I was thinking...</p> still contrived, but you get the point; the text in the optional front-matter would be used in rendering HTML from the markdown. First the extension. To make this work, instead of just creating the extension we create a function that returns the extension; the function can take parameter(s) for the information it needs: import { marked } from 'marked';
export const fixHeadings = (headingPrefix: string): Partial<Omit<marked.Renderer<false>, 'options'>> => {
return {
heading(text, level) {
return `<h${level}>${headingPrefix} ${text}</h${level}>`;
},
};
}; Using the import { marked } from 'marked';
import fm from 'front-matter';
import { fixHeadings } from './fixheadings'
interface MarkdownOptions {
headingPrefix: string;
// other options that can be set in the front-matter
}
const defaultOptions: MarkdownOptions = {
headingPrefix: 'Chapter:', // good to have a default, because the front-matter might not exist
};
export const renderedOutputFromMarkdown = (md: string): string => {
const options = { ...defaultOptions };
// by default, the markdown we want to parse is the entire input
let markdownString = md;
try {
const fmResult = fm(md);
// if there is front-matter the markdown to parse is reduced to just the `body` from `front-matter`
markdownString = fmResult.body;
if ((fmResult.attributes as any).headingPrefix) {
options.headingPrefix = (fmResult.attributes as any).headingPrefix;
}
} catch {
// do nothing; can easily throw exceptions, especially when fm being edited
}
marked.use({ renderer: fixHeadings(options.headingPrefix) });
// other marked.use() options go here as well
return marked.parse(markdownString);
}; |
updated version of the front matter lib : https://www.npmjs.com/package/gray-matter Converts a string with front-matter, like this: ---
title: Hello
slug: home
---
<h1>Hello world!</h1> Into an object like this: {
content: '<h1>Hello world!</h1>',
data: {
title: 'Hello',
slug: 'home'
}
} |
Like this: http://jekyllrb.com/docs/frontmatter/
The text was updated successfully, but these errors were encountered: