Convert markdown to html with a table of contents using Redcarpet - ruby

My goal is to convert a markdown document to html, with a table of contents at the top. I saw that Redcarpet has a HTML_TOC option, which is really nice. But when I use it, it only renders the TOC, it does not include the rest of the document.
renderer = Redcarpet::Render::HTML_TOC.new(with_toc_data: true)
markdown = Redcarpet::Markdown.new(renderer)
html = markdown.render(File.read(input_file))
How do I render both the TOC and document itself in the same html page?
The only thing I can think of is to render two separate html objects, then combine them. But that is a little messy because I'd have to parse out the head/body tags properly before combining them. Is there a better way?

The only thing I can think of is to render two separate html objects, then combine them.
That would be exactly what you need to do. As a reminder, Markdown does not render a complete HTML document anyway. You only get an HTML fragment. For example a simple Markdown document:
A simple Markdown document.
gets rendered as the following HTML fragment:
<p>A simple Markdown document.</p>
However, for a complete, valid HTML document you need (at least) the following:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<p>A simple Markdown document.</p>
</body>
</html>
Considering that you need to generate all of that anyway, how is it "messy" to obtain the TOC and the body separately?
In fact, in more sophisticated systems, the TOC may be in a sidebar or something. Therefore, using a templating system, the TOC can be passed to a template separately anyway, where it is then placed in a container which separates it from the document body for positioning and styling by CSS.
The exact template syntax might vary depending on which tools you use, but perhaps something like this:
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }}</title>
</head>
<body>
<aside>
{{ page.toc }}
</aside>
<div id="body">
{{ page.body }}
</div>
</body>
</html>
Of course, you don't have to use a template, but is certainly is a "clean" way to generate a document.

Related

How do I use pandoc to delete the enclosing tags and just extract a branch of an AST?

I have been studying pandoc filters. I think I get it and have done some tutorials but I'm still having trouble wrapping my head around extracting an embedded body tag and converting it to a div tag while deleting all the enclosing paraphernalia
Suppose I have a simple html file:
<html>
<head>
<title>bla</title>
</head>
<body>
Hello World
</body>
</html>
How would I transform it to
<div>
Hello World
<div>
To leave the <body> tags etc, simply run pandoc without the --standalone (aka -s) option. If you've looked into pandoc filters, you already know how to insert a div where you need it.
P.S. If you look at the pandoc document AST definition, you see that it's simply some metadata and a list of block elements. The <body> tags etc. are all from the HTML template, not the AST.

Laravel 5 proper way to require CSS file from view

I've got specific Form component, which is declared as
Form::component('fcRadio', 'components.form.fcradio', ['name', 'options', 'selected' => null]);
and used as
{{ Form::fcRadio('name', $options }}
What I want is somehow attach custom CSS file, so if the page fires this component at least once, the desired CSS file is included to the <head> of my document.
For example, in Joomla it was like
$this->document->addStylesheet('my_awesome_style.css');
Is there any way to achieve the same in Laravel?
UPD:
I've extended the answers below a bit to let it add multiple styles from multiple templates. Finally, it looks like this:
#section('styles')
#parent
{{HTML::style('css/fcradio.css')}}
#stop
It works fine, but if I use the component twice per page, style is also adds twice. How can I allow multiple but unique entries?
So this is typically how I deal with it:
In your folder: resources/views I create a folder called layout. This folder handles the templates for all my pages.
Then I create a file called default.blade.php. In it I put the bulk of the HTML code. Here's an example of how default.blade.php could look (slimmed down, obviously)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
#yield('title')
</title>
<link rel="stylesheet" href="{{ asset('css/main.css') }}">
<!-- Additional per-page css -->
#yield('css')
</head>
<body>
#yield('content')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="js/script.js"></script>
<script src="{{ asset('js/bootstrap.min.js') }}"></script>
<!-- Include per-page JS -->
#yield('js')
</body>
</html>
Right, so essentially what we have so far is the #yield() and asset() helpers.
#yield() is special blade syntax that Laravel uses to say, "Okay. Any time a blade view that is inheriting THIS master template calls the section named in this #yield() I will display that content right here.
asset() is a nifty little helper that basically appends your URL structure onto the string you pass it. So if your url is http://MyGreatSite.com and you use asset('js/script.js') it will spit out a fully qualified URL that will work anywhere on the site (http://MyGreatSite.com/js/script.js). asset() is great because you can use it in blade templates that will get sent out as an email and all of the files will work in an email inbox because they are absolute links.
Right. So now we have this master template and we need to use it. So what I do is create another view in the resources/views directory. Lets say we're doing a contact page. I would make contact.blade.php. Now I want to inherit that master template we created. So we do that like so:
#extends('layout.default)
#section('css')
<link rel="stylesheet" href="{{ asset('css/contact.css') }}">
#stop
#section('title')
Contact Us
#stop
#section('content')
<h1>Contact us</h1>
<p>
Contact us via email: contact#mygreatsite.com
</p>
#stop
#section('js')
<script src="{{ asset('js/contact-form.js') }}"></script>
#stop
Okay, so, first things first. At the very top we tell this blade file that we want to use the template we just made. We use the blade helper #extends() and pass it the path to our view relative to the views directory separated by periods.
Next, we want to create the sections that correspond to the template. We do that by opening the section with #section() and passing the name of the section we want to push this block of content to. We write our content and then we close the section by using #stop. Pretty simple. For images, css, or js, we simply use the asset() helper again.
I know it's a little long-winded, but hopefully that helps and explains the process a little better.
tl;dr: Use #yield(), #section(), and asset().
So I think I understand what you are saying.
In your blade layout file create a section inside the head:
<head>
#yield('componentcss')
</head>
And in the component do:
#section('componentcss')
{{HTML::style('css/fcradio.css')}}
#stop
You could also just include the css but I wouldn't advise this:
#section('componentcss')
<style>
.exampleclass {text-align:center;}
</style>
#stop
Hopefully I have understood you correctly.
I've finally found a bit tricky but working solution:
#hasSection('fcRadioStyle')
#else
#section('fcRadioStyle')
{{Html::style('css/components/fcradio.css')}}
#stop
#section('styles')
#yield('fcRadioStyle')
#append
#endif
This makes by Form::fcRadio append this style only once

Dompdf: Can i import pdf as background

i have a pdf form that i need to be able to import as a background then use Dompdf to overlay html/text.
can this be done?
thanks
Dompdf is a library for converting HTML -> PDF. I'm no expert on that particular library but as far as I can tell it doesn't do things like overlaying html/text.
PDF cannot be imported into HTML because it isn't an HTML format and it isn't an image. There might be a parser library somewhere (e.g. http://www.pdfonline.com/easyconverter/sdk/pdf-to-html/), but without your own fairly extensive work you wont get that PDF document to be displayed in HTML.
HOWEVER, you CAN use something like this, it'll show your PDF document as the background, create a div that covers the screen just above the PDF document to make it non-interactive, then you can put all your contents above that. Note that there will be controls showing on the sides which as far as I know can't be prevented since they're provided by the browser when displaying a PDF file (you could use some fancy JS/CSS to prevent it I'm guessing but I don't know exactly how off the top of my head).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PDF as background</title>
</head>
<body>
<iframe src="http://unec.edu.az/application/uploads/2014/12/pdf-sample.pdf" style="width: 100vw; height: 100vh;position:absolute;top:0;z-index:0;"></iframe>
<div style="position:fixed;width:100%;height:100%;z-index:1"></div>
<div id="content" style="position: absolute;top:50%;left: calc(50% - 4cm);z-index:2">
<h1 style="font-size:20px;background:#00ff00;">I am on top of the PDF document!</h1>
</div>
</body>
</html>

How does Jekyll use post.html to generate pages?

I'm having some difficulty getting Jekyll to use a particular theme and I think there's something fundamental I'm missing about how {{ content }} works with posts.
So, in a generic Jekyll site, index.html has a layout specified in its front matter. When the site is generated, the layout includes index.html as {{ content }}. It's kind of inverted, where the page specifies the layout and then the layout calls the page, but simple enough.
Posts, on the other hand, are all generated via a file, post.html, which resides in the _layouts folder even though it isn't really a layout. Like index.html it's essentially just a for loop. This is where I'm running into trouble.
Is post.html a required file? Could I rename it story.html?
Why does post.html require a layout in the front matter? The actual post, that is, the markdown that contains the text for said post, also requires a layout in its front mater. Is there a circumstance where post.html would have a different layout than the layout specified in the markdown file?
Edit: one other question. Why is {{ content }} called in multiple places? index.html and the layout file both have {{ content }}. Why doesn't the layout simply {% include %} index.html and let index.html call {{ content }}
I think you largely figured it out by yourself, but I'll still explain it in my own words.
You're right that {{ content }} is the placeholder in the layout file where the content of the actual page will go.
What probably confused you is the fact that you can build a set of nested layout files where one "inherits" from the other, and each layout has its own {{ content }}.
And yes, I didn't find anything about this in the docs, I figured it out by myself or better, by looking at examples.
So here's an example for you.
First, a default layout and a page:
/_layouts/default.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }}</title>
</head>
<body>
<h1>{{ page.title }}</h1>
{{ content }}
</body>
</html>
/index.md:
---
title: example page
layout: default
---
This is the page content.
The generated HTML will look like this:
<!DOCTYPE html>
<html>
<head>
<title>example page</title>
</head>
<body>
<h1>example page</h1>
<p>This is the page content.</p>
</body>
</html>
Now let's create another layout file that "inherits" from the first one.
You'll probably want to use something like this if you're building a blog with Jekyll.
The layout file shown above is the default for all pages, blog posts and regular ones.
When you want all blog posts to contain additional information like post date and user, tags and so on.
For this, you can create a second layout file which uses the first one:
/_layouts/post.html:
---
layout: default
---
<div class="blogpost">
<i>post date: {{ page.date }}</i>
{{ content }}
</div>
And a blog post which uses this layout:
/_posts\2015-04-08-example-post.md:
---
title: example post
layout: post
---
This is the post content.
And the generated HTML:
<!DOCTYPE html>
<html>
<head>
<title>example post</title>
</head>
<body>
<h1>example post</h1>
<div class="blogpost">
<i>post date: 2015-04-08 00:00:00 +0200</i>
<p>This is the post content.</p>
</div>
</body>
</html>
In other words, something like this happened:
Jekyll used the post layout and put the content of the post into {{ content }}
Jekyll used the default layout and put the complete generated HTML from step 1 into {{ content }}
(no idea if Jekyll really does things in this order under the hood, but you get the idea)
You can see another example if you create a new Jekyll project as shown in the "Quick-start Instructions" on the home page of the Jekyll site.
The example site that Jekyll (version 2.1.1 on my machine) creates has three layout files, two of which (page and post) inherit from the default one.
I have an answer for myself, sort of. Each markdown file is assigned a layout in the front matter. But this "layout" isn't really a layout at all or it's a partial layout?
The terminology escapes me, so I'll just list the steps.
1) The markdown file has layout: post
2) Whatever is in the markdown file gets processed and then sent over to the logic residing in post.html. Here's the part that I wasn't getting right off: post.html has it's own layout. That's what's up in the front matter. Essentially we have the layout's layout.
3) The outer "layout" (default.html in a vanilla jekyll install), wraps itself around the inner "layout" (post.html), which wraps itself around the actual {{ content }}.
post.html could be named whatever, so long as the various layout lines are properly set.
I still don't know why {{ content }} winds up at the top of the layout stack only to be passed all the way back down. I'm not even sure "passed" is the right word when dealing with liquid. I like Jekyll, but it's kind of a nest of snakes.

Is it valid to give a style element an ID?

It says here that it is not within HTML4, though I don't really see where that's spelled out in the text.
From what I can tell, based on this, it is ok to do so in HTML5 but I'm not entirely sure (assuming style is an HTML element?)
I am using this to rotate out a stylesheet and want it to be as valid as possible according to HTML5 specs, so wondering if I should rewrite it with a data-* element.
+1 Interesting question!
Instead of using a style block, you should consider linking (link) to your stylesheets and then switch them out by referencing an id or a class.
That said, title is perfectly acceptable for a style tag in HTML5. You can use this as a hook for your stylesheet switching.
http://www.w3.org/TR/html5/semantics.html#the-style-element
Fyi... this validates
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<style title="whatever"></style>
</head>
<body>
Test body
</body>
</html>
http://validator.w3.org/#validate_by_input+with_options
I've just put the following code into the W3C validator and it has no errors :)
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<style id="test"></style>
</head>
<body>
Test body
</body>
</html>
I think the W3C Validator is a good resource for this type of thing, it is marked as experimental but that's because the standard is yet to be be finalised.
It is not valid in HTML4 (as per the spec) and data-* attributes are not either. That is, the document will not validate against the Doctype spec if you use these attributes.
Regardless of whether the document validates or not, browsers will ignore elements that they do not recognize.
Style tags are DOM elements like any other tag, so you can add any attributes you want.

Resources