Closed mojavelinux closed 10 years ago
Having dabbled with RevealJS, I'd definitely like to work on/contribute to this endeavor.
Cool, I implemented the deck.js backend so if you have any question feel free to ask me here or by using http://discuss.asciidoctor.org/
@jordanmccullough That's great to hear! We've got a reveal.js pro in the house! Woot!
Although you probably don't need any hints, I know @paulrayner has played around with a reveal.js backend for Asciidoctor for one (or more) of his presentations. However, he was extending the built-in classes instead of using Tilt. Custom backends should be done using Tilt because the built-in classes should be treated as private.
My one word of advice is to aim for the simplest possible syntax (roles, options, etc) that will work. @jordanmccullough you probably don't need any convincing on that coming from Markdown. Hopefully you'll find the AsciiDoc syntax is a good fit for achieving the type of hierarchical organization of slides that you have in HydeSlides.
Happy hacking!
Writing a revealjs backend right now. Using tilt and haml. Never really used haml/titlt/revealjs and have to learn the structure asciidoctor calls the haml files. Created a subdirectory asciidoctor-backends/haml/revealjs and started with document.html.haml. Is that the right direction?
@buuhsmead Excellent!
I recommend starting with either haml or tilt (I see you chose haml, which is fine). It's easy to then port it to slim. Using multiple engines in the backend doesn't really benefit users, but it gives people interested in hacking on it the raw material if they prefer to use one engine over another. To be honest, I'm still debating with myself what the best approach is.
You have the right idea to get started:
<engine>/revealjs
in the asciidoctor-backends repository, where <engine>
is the template engine (e.g., haml, slim or erb)document.html.<engine>
, moving on to section.html.<engine>
, then likely block_paragraph.html.<engine>
, block_ulist.html.<engine>
and so forthI'll give a brief overview of the object model that is available for each template (hopefully so it makes its way into some official documentation soon).
Each template represents one type of document node, similar to an XML DOM node. There are three types of nodes:
The first template to be invoked is document.html.
You can think of the template as a single method call on the node object. Within the template, you have access to all the instance variables and instance methods of the node, just as you would inside a method call.
For example, the following line invokes the content()
method on the node:
=content
Each node holds the following common information:
Block nodes hold the following additional information:
* In a list block, the content is a collection of the list items.
Inline nodes hold the following additional information:
The following table shows some of the instance variables and instance methods you'll use in a template:
Name | Example(s) | Description |
---|---|---|
content | content | Renders the children of this node (if any) and returns the result. |
id | @id | The id assigned to the block or nil of no id is assigned. |
document | @document | A reference to the current document (and all of its nodes). |
attr(name, default = nil) | attr('language') attr('toc-class', 'toc') @document.attr('icons', 'font') |
Retrieves the value of the specified attribute in the attributes hash, using the name as a key. If the name is written as a symbol, it will be automatically converted to a string before lookup. |
attr?(name, match = nil) | attr?('icons') attr?('toc-placement', 'auto') |
Checks whether the specified attribute exists in the attribute hash, using the name as the key. If the name is written as a symbol, it will be automatically converted to a string before lookup. If a match is provided, additionally checks whether the attribute value matches the specified value. |
style | @style | Retrieves the style (qualifier) for a block. If the block does not have a style, nil is returned. |
role | role | A convenience method that returns the role attribute for the block, or nil if the block does not have a role. |
role? | role? | A convenience method to check whether the block has the role attribute. |
option?(name) | option?('loop') | A convenience method to check whether the specified option attribute (e.g., loop-option) is present. |
title | title | Retrieves the title of the block with normal substitutions (escape XML, render links, etc) applied. |
title? | title? | Checks whether a title has been assigned to this block. This method does not have side effects (e.g., checks for existence only, does not apply substitutions) |
image_uri(path) | image_uri(attr 'target') | Converts the path into an image uri (reference or embedded data) to be used in an HTML img tag. Applies security restrictions, cleans path and can embed image data if :data-uri: attribute is enabled on document. Always use this method when dealing with image references. Relative image paths are resolved relative to document directory unless overridden using :imagesdir: |
icon_uri(path) | icon_uri(attr 'target') | Same as image_uri except it specifically works with icons. By default, it will look in the subdirectory images/icons, unless overridden using :iconsdir: |
media_uri(path) | media_uri(attr 'target') | Similar to image_uri, except it does not support embedding the data into the document. Intended for video and audio paths. |
normalize_web_path(path, relative_root) | normalize_web_path(attr('stylesheet'), attr('stylesdir', '')) | Joins the path to the relative_root and normalizes parent and self references. Access to parent directories may be restricted based on safe mode setting. |
normalize_system_path(path, relative_root, jail) | normalize_system_path(attr('stylesheet'), attr('stylesdir', ''), true) | The most critical method to ensure proper security. Joins the path to the relative_root and normalizes parent and self references. Access to parent directories may be restricted based on the safe mode setting. This method is extremely careful about assembling safe paths. |
In both Haml and Slim, you can assign an array to an HTML attribute and it will automatically be compacted (empty elements removed) and joined into a space-separated list.
For example:
%div{:id=>@id, :class=>['admonitionblock', (attr :name), role]}
Assuming id=foobar, name=warning, role=nil, the following element is produced:
<div id="foobar" class="admonitionblock warning">
If you assign a single value to an attribute, and the value is nil, the attribute will be excluded. Thus, if id is nil, then the output of the previous example would be:
<div class="admonitionblock warning">
The list block templates (block_olist, block_ulist and block_dlist) are responsible for handling their own direct children.
For example:
%ol{:class=>@style, :start=>(attr :start), :type=>(Asciidoctor::ORDERED_LIST_KEYWORDS[@style])}
- content.each do |item|
%li
%p=item.text
- if item.blocks?
=item.content
Hopefully that gets you going. I'll post more information as it comes to mind.
I have some additional notes on the following wiki page, though it's mostly just an outline:
https://github.com/asciidoctor/asciidoctor/wiki/APIs-for-Backend-Templates
Here's a rough and partially complete list of attributes:
https://github.com/asciidoctor/asciidoctor/wiki/Catalog-of-Document-Attributes
The best reference, atm, is the html5 backend in Haml. It's nearly feature complete to 0.1.4.preview.1.
https://github.com/asciidoctor/asciidoctor-backends/tree/master/haml/html5
@mojavelinux Those pieces of info are a great help. Thank you!
Contributions to @buuhsmead's efforts for the RevealJS backend are en route.
Awesome @jordanmccullough!
I've published a preview release of Asciidoctor 0.1.4. I recommend building the reveal.js backend against it as it has some improvements for making backend development easier. For example, you can now check for the existence of a role using role?
and get a list of all roles using roles
.
gem install asciidoctor --pre
I spoke to @jordanmccullough about speaker notes today. I think an admonition block + an ideal fit for this use case. Here's how I do it in dzslides:
[NOTE.speaker]
--
* AsciiDoc is easy to read in raw form.
* It's also easy to proof and edit.
* The punctuation was chosen to look like what it means.
* Only requires a text editor to read or write.
--
In the block_admonition.html.haml
template you can check for this role using:
- if role? 'speaker'
-# output HTML for speaker notes here
- else
-# normal admonition stuff
I wonder if role?
should be has_role?
and let role?
check for an exact match. Thoughts?
I'm all for explicitness, so I vote for has_role? returning whether it has a role or not, assuming that's what you mean.
On Jul 6, 2013, at 5:49 PM, Dan Allen notifications@github.com wrote:
I wonder if role? should be has_role? and let role? check for an exact match. Thoughts?
— Reply to this email directly or view it on GitHubhttps://github.com/asciidoctor/asciidoctor-backends/issues/12#issuecomment-20563083 .
Some additional useful info for creating custom backends:
Added by @cmoulliard with this commit: 18714c55fa7f55528918b4e8c4087fa8008e3aaa
We'll use separate issues to track enhancements.
Create a backend for reveal.js presentations.
reveal.js: http://lab.hakim.se/reveal-js/
Keep in mind that we want to try to align the different presentation backends (deck.js, reveal.js, dzslides, etc) so that the same AsciiDoc source file will work using any one of them (within reason).
Also, each backend should be create in its own git repository to make collaboration and releases easier.