Merge branch 'attributes' of https://github.com/VonC/reveal.js into dev

This commit is contained in:
Hakim El Hattab 2013-12-02 12:12:27 +01:00
commit 65bd155c34
6 changed files with 196 additions and 154 deletions

View file

@ -60,25 +60,25 @@ You can write your content as a separate file and have reveal.js load it at runt
#### Element Attributes
Special syntax is available for adding attributes to Markdown elements. This is useful for fragments, amongst other things.
Special syntax (in html comment) is available for adding attributes to Markdown elements. This is useful for fragments, amongst other things.
```html
<section data-markdown>
<script type="text/template">
- Item 1 {.class="fragment" data-fragment-index="2"}
- Item 2 {.class="fragment" data-fragment-index="1"}
- Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
- Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
</script>
</section>
```
#### Slide Attributes
Special syntax is available for adding attributes to the slide `<section>` elements generated by your Markdown.
Special syntax (in html comment) is available for adding attributes to the slide `<section>` elements generated by your Markdown.
```html
<section data-markdown>
<script type="text/template">
<!-- slide-attributes: data-background="#ff0000" -->
<!-- slide: data-background="#ff0000" -->
Mardown content
</script>
</section>

View file

@ -28,8 +28,8 @@
var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
DEFAULT_NOTES_SEPARATOR = 'note:',
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '{\\\.\s*?([^}]+?)}',
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '^.*?<!--\\\sslide-attributes:\\\s(.*?)-->';
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
/**
@ -73,7 +73,7 @@
value = attributes[i].value;
// disregard attributes that are used for markdown loading/parsing
if( /data\-(markdown|separator|vertical|notes|attributes)/gi.test( name ) ) continue;
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
if( value ) {
result.push( name + '=' + value );
@ -97,7 +97,6 @@
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
options.attributes = options.attributes || '';
options.slideAttributesSeparator = options.slideAttributesSeparator || DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR;
return options;
@ -129,17 +128,14 @@
options = getSlidifyOptions( options );
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
horizontalSeparatorRegex = new RegExp( options.separator ),
slideAttributesSeparatorRegex = new RegExp( options.slideAttributesSeparator, 'm' );
horizontalSeparatorRegex = new RegExp( options.separator );
var matches,
lastIndex = 0,
isHorizontal,
wasHorizontal = true,
content,
sectionStack = [],
matchAttributes,
slideAttributes = "";
sectionStack = [];
// iterate until all blocks between separators are stacked up
while( matches = separatorRegex.exec( markdown ) ) {
@ -178,35 +174,19 @@
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
// vertical
if( sectionStack[i] instanceof Array ) {
// The 'data-xxx' attributes of the first child must be set on the wrapping parent section to be effective
// Mainly for data-transition (otherwise, it is ignored for the first vertical slide)
firstChild = sectionStack[i][0];
matchAttributes = slideAttributesSeparatorRegex.exec( firstChild );
slideAttributes = matchAttributes ? matchAttributes[1] : "";
dataAttributes = "";
if( slideAttributes != "" ) {
// http://stackoverflow.com/questions/18025762/javascript-regex-replace-all-word-characters-except-word-characters-between-ch
// Keep only data-attributes for the parent slide section.
dataAttributes = slideAttributes.replace( /(data-\S+=\"[^\"]+?\")|\w|[\"=]/g, function(a, b) { return b || ''; });
}
markdownSections += '<section '+ options.attributes + ' ' + dataAttributes + '>';
markdownSections += '<section '+ options.attributes +'>';
sectionStack[i].forEach( function( child ) {
matchAttributes = slideAttributesSeparatorRegex.exec( child );
slideAttributes = matchAttributes ? matchAttributes[1] : "";
child = matchAttributes ? child.replace( slideAttributesSeparatorRegex,"" ) : child
markdownSections += '<section ' + slideAttributes + ' data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
} );
markdownSections += '</section>';
}
else {
matchAttributes = slideAttributesSeparatorRegex.exec( sectionStack[i] );
slideAttributes = matchAttributes ? matchAttributes[1] : "";
content = matchAttributes ? sectionStack[i].replace( slideAttributesSeparatorRegex,"" ) : sectionStack[i]
markdownSections += '<section '+ options.attributes + ' ' + slideAttributes +' data-markdown>' + createMarkdownSlide( content, options ) + '</section>';
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
}
}
return markdownSections;
}
@ -240,12 +220,12 @@
xhr.onreadystatechange = function() {
if( xhr.readyState === 4 ) {
if ( xhr.status >= 200 && xhr.status < 300 ) {
section.outerHTML = slidify( xhr.responseText, {
separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-vertical' ),
notesSeparator: section.getAttribute( 'data-notes' ),
attributes: getForwardedAttributes( section ),
slideAttributesSeparator: section.getAttribute( 'data-attributes' ),
attributes: getForwardedAttributes( section )
});
}
@ -277,24 +257,12 @@
separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-vertical' ),
notesSeparator: section.getAttribute( 'data-notes' ),
attributes: getForwardedAttributes( section ),
slideAttributesSeparator: section.getAttribute( 'data-attributes' ),
attributes: getForwardedAttributes( section )
});
}
else {
var content = getMarkdownFromSlide( section );
var slideAttributesSeparatorRegex = new RegExp( section.getAttribute( 'data-attributes' ) || DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR, 'm' );
var matchAttributes = slideAttributesSeparatorRegex.exec( content );
if ( matchAttributes ) {
var slideAttributes = matchAttributes[1];
content = content.replace( slideAttributesSeparatorRegex,"" );
var slideAttributesRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
while( matchesAttributes = slideAttributesRegex.exec( slideAttributes ) ) {
section.setAttribute( matchesAttributes[1], matchesAttributes[2] );
}
}
section.innerHTML = createMarkdownSlide( content );
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
}
}
@ -319,40 +287,51 @@
var classes = matches[1];
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
node.nodeValue = nodeValue;
while( matchesClass = mardownClassRegex.exec( classes ) ) {
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
}
return true;
}
return false;
}
/**
* Add attributes to the parent element of a text node,
* or the element of an attribute node.
*/
function addAttributes( element, separator ) {
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
if( element.childNodes.length > 0 ) {
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
previousParentElement = element;
for( var i = 0; i < element.childNodes.length; i++ ) {
addAttributes( element.childNodes[i], separator );
childElement = element.childNodes[i];
if ( i > 0 ) {
j = i - 1;
while ( j >= 0 ) {
aPreviousChildElement = element.childNodes[j];
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
previousParentElement = aPreviousChildElement;
break;
}
j = j - 1;
}
}
parentSection = section;
if( childElement.nodeName == "section" ) {
parentSection = childElement ;
previousParentElement = childElement ;
}
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
}
}
}
var nodeValue;
var elementTarget;
// From http://stackoverflow.com/questions/9178174/find-all-text-nodes
if( element.nodeType == Node.TEXT_NODE && /\S/.test(element.nodeValue) ) {
addAttributeInElement( element, element.parentNode, separator );
}
if( element.nodeType == Node.ELEMENT_NODE && element.attributes.length > 0 ) {
for( var j = 0; j < element.attributes.length; j++ ){
var attr = element.attributes[j];
addAttributeInElement( attr, element, separator );
if ( element.nodeType == Node.COMMENT_NODE ) {
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
addAttributeInElement( element, section, separatorSectionAttributes );
}
}
}
/**
@ -376,9 +355,12 @@
var markdown = getMarkdownFromSlide( section );
section.innerHTML = marked( markdown );
addAttributes( section, section.getAttribute( 'data-element-attributes' ) ||
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
section.parentNode.getAttribute( 'data-element-attributes' ) ||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR );
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
section.getAttribute( 'data-attributes' ) ||
section.parentNode.getAttribute( 'data-attributes' ) ||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
// If there were notes, we need to re-add them after
// having overwritten the section's HTML

View file

@ -25,7 +25,7 @@
<section data-markdown data-separator="^\n\n\n"
data-vertical="^\n\n"
data-notes="^Note:"
data-attributes="^\s*?--\s(.*?)$"
data-attributes="--\s(.*?)$"
data-charset="utf-8">
<script type="text/template">
# Test attributes in Markdown
@ -34,11 +34,11 @@
## Slide 2
-- id="slide2" data-transition="zoom" data-background="#A0C66B"
<!-- -- id="slide2" data-transition="zoom" data-background="#A0C66B" -->
## Slide 2.1
-- data-background="#ff0000" data-transition="fade"
<!-- -- data-background="#ff0000" data-transition="fade" -->
## Slide 2.2
@ -47,7 +47,7 @@
## Slide 3
-- data-transition="zoom" data-background="#C6916B"
<!-- -- data-transition="zoom" data-background="#C6916B" -->
@ -66,11 +66,11 @@
## Slide 2 Def
<!-- slide-attributes: id="slide2def" data-transition="concave" data-background="#A7C66B" -->
<!-- .slide: id="slide2def" data-transition="concave" data-background="#A7C66B" -->
## Slide 2.1 Def
<!-- slide-attributes: data-background="#f70000" data-transition="page" -->
<!-- .slide: data-background="#f70000" data-transition="page" -->
## Slide 2.2 Def
@ -79,7 +79,7 @@
## Slide 3 Def
<!-- slide-attributes: data-transition="concave" data-background="#C7916B" -->
<!-- .slide: data-transition="concave" data-background="#C7916B" -->
@ -89,7 +89,7 @@
<section data-markdown>
<script type="text/template">
<!-- slide-attributes: data-background="#ff0000" -->
<!-- .slide: data-background="#ff0000" -->
## Hello world
</script>
</section>
@ -97,7 +97,7 @@
<section data-markdown>
<script type="text/template">
## Hello world
<!-- slide-attributes: data-background="#ff0000" -->
<!-- .slide: data-background="#ff0000" -->
</script>
</section>
@ -106,7 +106,7 @@
## Hello world
Test
<!-- slide-attributes: data-background="#ff0000" -->
<!-- .slide: data-background="#ff0000" -->
More Test
</script>

View file

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<title>reveal.js - Test Markdown</title>
<title>reveal.js - Test Markdown Element Attributes</title>
<link rel="stylesheet" href="../css/reveal.min.css">
<link rel="stylesheet" href="qunit-1.12.0.css">
@ -24,19 +24,23 @@
<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
<section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$" data-element-attributes="{_\s*?([^}]+?)}">>
<script type="text/template">
## Slide 1.1 {_class="fragment fade-out" data-fragment-index="1"}
## Slide 1.1
<!-- {_class="fragment fade-out" data-fragment-index="1"} -->
--
## Slide 1.2 {_class="fragment shrink"}
## Slide 1.2
<!-- {_class="fragment shrink"} -->
Paragraph 1 {_class="fragment grow"}
Paragraph 1
<!-- {_class="fragment grow"} -->
Paragraph 2 {_class="fragment grow"}
Paragraph 2
<!-- {_class="fragment grow"} -->
- list item 1 {_class="fragment roll-in"}
- list item 2 {_class="fragment roll-in"}
- list item 3 {_class="fragment roll-in"}
- list item 1 <!-- {_class="fragment roll-in"} -->
- list item 2 <!-- {_class="fragment roll-in"} -->
- list item 3 <!-- {_class="fragment roll-in"} -->
---
@ -45,27 +49,75 @@
Paragraph 1.2
multi-line {_class="fragment highlight-red"}
multi-line <!-- {_class="fragment highlight-red"} -->
Paragraph 2.2 {_class="fragment highlight-red"}
Paragraph 2.2 <!-- {_class="fragment highlight-red"} -->
Paragraph 2.3 {_class="fragment highlight-red"}
Paragraph 2.3 <!-- {_class="fragment highlight-red"} -->
Paragraph 2.4 {_class="fragment highlight-red"}
Paragraph 2.4 <!-- {_class="fragment highlight-red"} -->
- list item 1 {_class="fragment highlight-green"}
- list item 2 {_class="fragment highlight-green"}
- list item 3 {_class="fragment highlight-green"}
- list item 4 {_class="fragment highlight-green"}
- list item 5 {_class="fragment highlight-green"}
- list item 1 <!-- {_class="fragment highlight-green"} -->
- list item 2<!-- {_class="fragment highlight-green"} -->
- list item 3<!-- {_class="fragment highlight-green"} -->
- list item 4
<!-- {_class="fragment highlight-green"} -->
- list item 5<!-- {_class="fragment highlight-green"} -->
Test
![Example Picture{_class="reveal stretch"}](assets/image2.png)
![Example Picture](examples/assets/image2.png)
<!-- {_class="reveal stretch"} -->
</script>
</section>
<section data-markdown data-separator="^\n\n\n"
data-vertical="^\n\n"
data-notes="^Note:"
data-charset="utf-8">
<script type="text/template">
# Test attributes in Markdown with default separator
## Slide 1 Def <!-- .element: class="fragment highlight-red" data-fragment-index="1" -->
## Slide 2 Def
<!-- .element: class="fragment highlight-red" -->
</script>
</section>
<section data-markdown>
<script type="text/template">
## Hello world
A paragraph
<!-- .element: class="fragment highlight-blue" -->
</script>
</section>
<section data-markdown>
<script type="text/template">
## Hello world
Multiple
Line
<!-- .element: class="fragment highlight-blue" -->
</script>
</section>
<section data-markdown>
<script type="text/template">
## Hello world
Test<!-- .element: class="fragment highlight-blue" -->
More Test
</script>
</section>
</div>
</div>

View file

@ -5,33 +5,41 @@ Reveal.addEventListener( 'ready', function() {
QUnit.module( 'Markdown' );
test( 'Vertical separator', function() {
strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 2, 'found two slides' );
strictEqual( document.querySelectorAll( '.reveal .slides>section>section' ).length, 4, 'found four slides' );
});
test( 'Attributes on vertical slides header', function() {
test( 'Attributes on element header in vertical slides', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.fade-out' ).length, 1, 'found one vertical slide with class fragment.fade-out on header' );
strictEqual( document.querySelectorAll( '.reveal .slides section>section h2.fragment.shrink' ).length, 1, 'found one vertical slide with class fragment.shrink on header' );
});
test( 'Attributes on vertical slides paragraphs', function() {
test( 'Attributes on element paragraphs in vertical slides', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section>section p.fragment.grow' ).length, 2, 'found a vertical slide with two paragraphs with class fragment.grow' );
});
test( 'Attributes on vertical slides list items', function() {
test( 'Attributes on element list items in vertical slides', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section>section li.fragment.roll-in' ).length, 3, 'found a vertical slide with three list items with class fragment.roll-in' );
});
test( 'Attributes on horizontal slides paragraphs', function() {
test( 'Attributes on element paragraphs in horizontal slides', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-red' ).length, 4, 'found a horizontal slide with four paragraphs with class fragment.grow' );
});
test( 'Attributes on horizontal slides list items', function() {
test( 'Attributes on element list items in horizontal slides', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section li.fragment.highlight-green' ).length, 5, 'found a horizontal slide with five list items with class fragment.roll-in' );
});
test( 'Attributes on horizontal slides list items', function() {
test( 'Attributes on element list items in horizontal slides', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section img.reveal.stretch' ).length, 1, 'found a horizontal slide with stretched image, class img.reveal.stretch' );
});
test( 'Attributes on elements in vertical slides with default element attribute separator', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section h2.fragment.highlight-red' ).length, 2, 'found two h2 titles with fragment highlight-red in vertical slides with default element attribute separator' );
});
test( 'Attributes on elements in single slides with default element attribute separator', function() {
strictEqual( document.querySelectorAll( '.reveal .slides section p.fragment.highlight-blue' ).length, 3, 'found three elements with fragment highlight-blue in single slide with default element attribute separator' );
});
} );
Reveal.initialize();