Commit 45728178 authored by Matt Mascarenhas's avatar Matt Mascarenhas

cinera.c: Search [#7]

Also put the stuff in a new directory called cinera, that contains only
the files needed to get going, with example template files.
parent c7d764c0
Fair warning: This is all under development and not yet packaged up for easy
deployment
## hmml_to_html
## cinera
### Download, and prepare the parser
1. `git clone [email protected]:Annotation-Pushers/Annotation-System.git`
2. `cd Annotation-System/hmmlib`
3. `make`
4. `cp hmml.a hmmlib.h ../hmml_to_html/`
5. `cd ../hmml_to_html/`
4. `cp hmml.a hmmlib.h ../cinera/`
5. `cd ../cinera/`
Note: For each parser update, remember to make and copy it into place
### Build
1. `zsh hmml_to_html.c` (replacing zsh with your shell as appropriate)
1. `zsh cinera.c` (replacing zsh with your shell as appropriate)
### Run
#### Ordinary operation
#### Single Edition operation
./hmml_to_html test.hmml
cinera test.hmml
This simply generates an HTML file (and updates `cinera_topics.css` if needed)
from `test.hmml` and outputs to `out.html`
Note that if the `.hmml` file contains quotes (as `test.hmml` does), it would be
easiest for now just to remove the quote from `test.hmml`. If you want quotes
to work, run:
#### Project Edition operation
mkdir /home/matt/git/GitHub/insofaras/25fc16d58a297a486334
git clone https://gist.github.com/insofaras/25fc16d58a297a486334 /home/matt/git/GitHub/insofaras/25fc16d58a297a486334
cinera -p ProjectID
(Seriously, the path is hardcoded for now)
Setting the ProjectID with the `-p` flag triggers Project Edition. In this
edition `cinera` monitors the Project Input Directory for new, edited and
deleted .hmml files, and generates one table of contents / search page and a
player page each for valid sets of annotations (or removes them, if needed).
Note also that `cinera.css` contains a `body {}` block at the bottom which you
may want to remove / comment out
By default all directories - input and output - are set to the current working
directory. Typical operation will involve setting these flags:
-d Project Input Directory, the directory where the .hmml files reside
-r Root Directory, path shallower than or equal to the CSS, Images and JS
directories
-u Root URL, corresponding to the Root Directory (optional if the Output
Base Directory resides in the Root Directory)
-b Output Base Directory, location of the table of contents / search page
-t Player Template Location
-x Index Template Location
#### Integration
CINERA_MODE=INTEGRATE ./hmml_to_html test.hmml
CINERA_MODE=INTEGRATE cinera test.hmml
This will integrate into `template_player.html` (configurable with -t) the
player and related elements generated from `test.hmml` and output to
`out_integrated.html`
This will integrate into `template.html` (currently hardcoded) the player and
related elements generated from `test.hmml` and output to `out.html`
Feel free to play with `template_player.html` to your heart's content. If you do
anything invalid, `cinera` will tell you what's wrong
Feel free to play with `template.html` to your heart's content. If you do
anything invalid, `hmml_to_html` will tell you what's wrong
#### Templates
Valid tags:
- `<!-- __CINERA_TITLE__ -->` _the day / episode name, intended to be used
inside your own `<title>` element, but may be used wherever and as many times
as you want on your page_
*Index Template*
- `<!-- __CINERA_INCLUDES__ -->` _the necessary `.css` and `.js` files_
- `<!-- __CINERA_INDEX__ -->` _the table of contents, and search functionality_
*Player Template*
- `<!-- __CINERA_INCLUDES__ -->` _the necessary `.css` and `.js` files, and charset setting_
- `<!-- __CINERA_MENUS__ -->` _ _the menu bar that typically appears above the
player in my samples_
- `<!-- __CINERA_MENUS__ -->` _ _the menu bar that typically appears above the player in my samples_
- `<!-- __CINERA_PLAYER__ -->` _the player_
- `<!-- __CINERA_SCRIPT__ -->` _the listeners that enable interaction with the player_
- `<!-- __CINERA_SCRIPT__ -->` _the filter state objects and `.js` file, which must come after both the MENUS and PLAYER tags_
#### Arguments
Usage: ./hmml_to_html [option(s)] filename(s)
Usage: ./cinera [option(s)] filename(s)
Options:
-c <CSS directory path>
Override default CSS directory (".")
-i <images directory path>
Override default images directory (".")
-j <JS directory path>
Override default JS directory (".")
-o <output location>
Override default output location ("out.html")
-q <quotes directory path>
Override default quotes directory ("/home/matt/git/GitHub/insofaras/25fc16d58a297a486334")
-t <template location>
Override default template location ("template.html")
and automatically enable integration
-h
display this help
Paths:
-r <root directory>
Override default root directory (".")
-u <root URL>
Override default root URL ("")
-b <base output directory>
Override project's default base output directory (".")
-c <CSS directory path>
Override default CSS directory (""), relative to root
-i <images directory path>
Override default images directory (""), relative to root
-j <JS directory path>
Override default JS directory (""), relative to root
-t <player template location>
Override default player template location ("template_player.html"), relative to root
and automatically enable integration
-x <index template location>
Override default index template location ("template_index.html"), relative to root
and automatically enable integration
-o <output location>
Override default output player location for SINGLE_EDITION ("out.html")
-d <project directory>
Override default project directory (".")
-f
Force integration with an incomplete template
-p <project ID>
Set the project ID, corresponding to the "project" field in the HMML files
-l <n>
Override default log level (0), where n is from 0 (terse) to 7 (verbose)
-m <default medium>
Override default default medium ("programming")
-U <seconds>
Override default update interval ("4")
-h
display this help
#### Environment Variables
CINERA_MODE=INTEGRATE
Enable integration
/* Index */
.queryContainer {
width: 1024px;
margin: 15px auto;
display: flex;
flex-direction: horizontal;
}
.queryContainer label {
flex-grow: 0;
flex-shrink: 0;
}
.queryContainer .inputContainer {
flex-grow: 1;
position: relative;
}
#query {
width: 100%;
}
.spinner {
position: absolute;
top: 2px;
right: 5px;
color: black;
height: 100%;
display: none;
}
.spinner.show {
display: block;
}
#results,
#cineraIndex {
width: 800px;
margin: 0 auto;
}
.dayName {
width: 200px;
display: inline-block;
vertical-align: top;
font-size: 12px;
line-height: 16px;
box-sizing: border-box;
padding: 5px;
}
#cineraIndex dt a {
display: block;
padding: 5px;
text-decoration: none;
}
.markerList {
display: inline-block;
width: 600px;
box-sizing: border-box;
vertical-align: top;
}
.markerList > .marker {
padding: 10px 5px;
cursor: pointer;
border-top: 1px solid;
display: block;
text-decoration: none;
}
.markerList > .marker:first-child {
border: none;
}
#resultsSummary {
text-align: center;
margin: 10px 0;
}
/* Player */
/* Structure */
.title,
......@@ -181,10 +265,14 @@
}
.title > .menu > .credits_container .credit .support {
text-align: right;
padding: 16px;
}
.title > .menu > .credits_container .credit .support .support_icon {
height: 16px;
width: 16px;
}
.title > .menu > .refs .ref:last-child,
.title > .menu > .credits_container .credit:last-child {
border: none;
......
/* Search */
.dayContainer.hero,
#cineraIndex.hero dt {
background-color: #161616;
}
.dayContainer:nth-child(2n).hero,
#cineraIndex.hero dt:nth-child(2n) {
background-color: #303030;
}
.dayContainer.hero > .dayName,
#cineraIndex.hero dt a {
color: #8A877D;
}
.markerList.hero > .marker
{
border-color: rgba(255, 255, 255, 0.1);
color: #ddd;
}
.markerList.hero > .marker b {
color: black;
background-color: rgb(255, 155, 0);
}
.markerList.hero > .marker:hover {
background-color: #444;
}
/* Player */
.title.hero,
.title.hero .menu .refs,
.title.hero .menu > .refs .ref,
......
.dayContainer.riscy,
#cineraIndex.riscy dt,
.title.riscy,
.title.riscy > .menu .refs,
.title.riscy > .menu .filter_container,
......@@ -8,9 +11,31 @@
.markers_container.riscy,
.markers_container.riscy > .marker {
background-color: #EEE;
}
.dayContainer:nth-child(2n).riscy,
#cineraIndex.riscy dt:nth-child(2n) {
background-color: #FFF;
}
.markerList.riscy > .marker,
.title.riscy,
.title.riscy > .menu .refs,
.title.riscy > .menu .filter_container,
.title.riscy > .menu > .refs .ref,
.title.riscy > .menu > .filter_container .filter_mode,
.title.riscy > .menu > .credits_container,
.title.riscy > .menu > .credits_container .credit,
.markers_container.riscy,
.markers_container.riscy > .marker {
border-color: rgba(246, 178, 26, 0.8);
}
.dayContainer.riscy > .dayName,
.markerList.riscy > .marker,
#cineraIndex.riscy dt a,
.title.riscy,
.title.riscy > .menu > .refs .ref,
/*.title.riscy > .menu > .refs .ref .timecode:hover:before,*/
......@@ -36,23 +61,22 @@
}
.title.riscy > .menu > .refs .ref.current .ref_indices .timecode.focused {
color: rgb(246, 178, 26);
color: rgb(246, 178, 26);
}
.markerList.riscy > .marker:hover,
#cineraIndex.riscy dt:hover,
/*.title.riscy > .menu:hover,*/
.title.riscy > .menu.visible,
/*.title.riscy > .menu > .refs .ref:hover,*/
.title.riscy > .menu > .quotes_container .ref.focused,
.title.riscy > .menu > .references_container .ref.focused,
.title.riscy > .menu > .filter_container .filter_mode:hover,
/*.title.riscy > .menu > .filter_container .filter_content:hover,*/
.title.riscy > .menu > .filter_container .filter_content.focused,
/*.title.riscy > .menu > .credits_container .credit *:hover,*/
.title.riscy > .menu > .credits_container .credit *.focused,
.markers_container.riscy > .marker:hover > .content {
background-color: #FFF8E7;
}
......@@ -63,15 +87,13 @@ color: rgb(246, 178, 26);
color: #FFF8E7;
}
.title.riscy > .menu > .refs .ref.current,
/*.title.riscy > .menu > .refs .ref.current .timecode:hover:before,*/
.markers_container.riscy > .marker > .progress .content {
color: #FFF;
}
.markerList.riscy > .marker b,
.title.riscy > .menu > .refs .ref.current,
/*.title.riscy > .menu > .refs .ref.current .timecode:hover:before,*/
.markers_container.riscy > .marker > .progress .content {
background-color: rgb(42, 49, 114);
color: #FFF;
}
/*.title.riscy > .menu > .refs .ref.current:hover,*/
......
var menuState = [];
var titleBar = document.querySelector(".title");
var quotesMenu = titleBar.querySelector(".quotes_container");
if(quotesMenu)
{
menuState.push(quotesMenu);
var quoteTimecodes = quotesMenu.querySelectorAll(".refs .ref .ref_indices .timecode");
for (var i = 0; i < quoteTimecodes.length; ++i) {
quoteTimecodes[i].addEventListener("click", function(ev) {
if (player) {
var time = ev.currentTarget.getAttribute("data-timestamp");
mouseSkipToTimecode(player, time, ev);
}
});
}
var lastFocusedQuote = null;
}
var referencesMenu = titleBar.querySelector(".references_container");
if(referencesMenu)
{
menuState.push(referencesMenu);
var referenceItems = referencesMenu.querySelectorAll(".ref");
if(referenceItems)
{
for(var i = 0; i < referenceItems.length; ++i)
{
referenceItems[i].addEventListener("mouseenter", function(ev) {
mouseOverReferences(this);
})
};
var lastFocusedReference = null;
var lastFocusedIdentifier = null;
}
var refTimecodes = referencesMenu.querySelectorAll(".refs .ref .ref_indices .timecode");
for (var i = 0; i < refTimecodes.length; ++i) {
refTimecodes[i].addEventListener("click", function(ev) {
if (player) {
var time = ev.currentTarget.getAttribute("data-timestamp");
mouseSkipToTimecode(player, time, ev);
}
});
}
}
if(referencesMenu || quotesMenu)
{
var refSources = titleBar.querySelectorAll(".refs .ref"); // This is for both quotes and refs
for (var i = 0; i < refSources.length; ++i) {
refSources[i].addEventListener("click", function(ev) {
if (player) {
player.pause();
}
});
}
}
var filterMenu = titleBar.querySelector(".filter_container");
if(filterMenu)
{
menuState.push(filterMenu);
var lastFocusedCategory = null;
var lastFocusedTopic = null;
var lastFocusedMedium = null;
var filter = filterMenu.parentNode;
var filterModeElement = filter.querySelector(".filter_mode");
filterModeElement.addEventListener("click", function(ev) {
toggleFilterMode();
});
var filterMode = filterModeElement.classList[1];
var filterItems = filter.querySelectorAll(".filter_content");
for(var i = 0; i < filterItems.length; ++i)
{
filterItems[i].addEventListener("mouseenter", function(ev) {
navigateFilter(this);
})
filterItems[i].addEventListener("click", function(ev) {
filterItemToggle(this);
});
}
}
var creditsMenu = titleBar.querySelector(".credits_container");
if(creditsMenu)
{
menuState.push(creditsMenu);
var lastFocusedCreditItem = null;
var creditItems = creditsMenu.querySelectorAll(".person, .support");
for(var i = 0; i < creditItems.length; ++i)
{
creditItems[i].addEventListener("mouseenter", function(ev) {
if(this != lastFocusedCreditItem)
{
lastFocusedCreditItem.classList.remove("focused");
if(lastFocusedCreditItem.classList.contains("support"))
{
setIconLightness(lastFocusedCreditItem.firstChild);
}
lastFocusedCreditItem = this;
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
if(focusedElement.classList.contains("support"))
{
setIconLightness(focusedElement.firstChild);
}
}
})
}
var supportIcons = creditsMenu.querySelectorAll(".support_icon");
{
for(var i = 0; i < supportIcons.length; ++i)
{
setIconLightness(supportIcons[i]);
}
}
}
var sourceMenus = titleBar.querySelectorAll(".menu");
var helpButton = titleBar.querySelector(".help");
var helpDocumentation = helpButton.querySelector(".help_container");
helpButton.addEventListener("click", function(ev) {
handleMouseOverMenu(this, ev.type);
})
var focusedElement = null;
var focusedIdentifier = null;
var playerContainer = document.querySelector(".player_container")
var player = new Player(playerContainer, onRefChanged);
window.addEventListener("resize", function() { player.updateSize(); });
document.addEventListener("keydown", function(ev) {
var key = ev.key;
if(ev.getModifierState("Shift") && key == " ")
{
key = "capitalSpace";
}
if(handleKey(key) == true && focusedElement)
{
ev.preventDefault();
}
});
for(var i = 0; i < sourceMenus.length; ++i)
{
sourceMenus[i].addEventListener("mouseenter", function(ev) {
handleMouseOverMenu(this, ev.type);
})
sourceMenus[i].addEventListener("mouseleave", function(ev) {
handleMouseOverMenu(this, ev.type);
})
};
var testMarkers = playerContainer.querySelectorAll(".marker");
window.addEventListener("blur", function(){
document.getElementById("focus-warn").style.display = "block";
});
window.addEventListener("focus", function(){
document.getElementById("focus-warn").style.display = "none";
});
var colouredItems = playerContainer.querySelectorAll(".author, .member, .project");
for(i = 0; i < colouredItems.length; ++i)
{
setTextLightness(colouredItems[i]);
}
var topicDots = document.querySelectorAll(".category");
for(var i = 0; i < topicDots.length; ++i)
{
setDotLightness(topicDots[i]);
}
if(location.hash) {
player.setTime(location.hash.startsWith('#') ? location.hash.substr(1) : location.hash);
}
......@@ -392,14 +392,22 @@ function toggleMenuVisibility(element) {
if(element.querySelectorAll(".credit .support")[0])
{
lastFocusedCreditItem = element.querySelectorAll(".credit .support")[0];
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
else
{
lastFocusedCreditItem = element.querySelectorAll(".credit .person")[0];
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
}
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
else
{
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
}
}
}
......@@ -532,15 +540,18 @@ function handleKey(key) {
if(focusedElement.parentNode.previousElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support"))
{
setIconLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
else
{
lastFocusedCreditItem = focusedElement.parentNode.previousElementSibling.querySelector(".person");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
focusedElement.classList.add("focused");
}
}
}
......@@ -596,15 +607,18 @@ function handleKey(key) {
if(focusedElement.parentNode.nextElementSibling.querySelector(".support") &&
focusedElement.classList.contains("support"))
{
setIconLightness(focusedElement.firstChild);
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".support");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
else
{
lastFocusedCreditItem = focusedElement.parentNode.nextElementSibling.querySelector(".person");
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
focusedElement.classList.add("focused");
}
}
}
......@@ -618,11 +632,17 @@ function handleKey(key) {
if(focusedIdentifier.previousElementSibling)
{
focusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = focusedIdentifier.previousElementSibling;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
else if(focusedIdentifier.parentNode.previousElementSibling.classList.contains("ref_indices"))
{
focusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = focusedIdentifier.parentNode.previousElementSibling.lastElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
}
else if(focusedElement.classList.contains("filter_content"))
{
......@@ -648,6 +668,7 @@ function handleKey(key) {
focusedElement.classList.remove("focused");
lastFocusedCreditItem = focusedElement.previousElementSibling;
setIconLightness(focusedElement.firstChild);
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
}
......@@ -668,6 +689,13 @@ function handleKey(key) {
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
else if(focusedIdentifier.parentNode.nextElementSibling)
{
focusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = focusedIdentifier.parentNode.nextElementSibling.firstElementChild;
focusedIdentifier = lastFocusedIdentifier;
focusedIdentifier.classList.add("focused");
}
}
else if(focusedElement.classList.contains("filter_content"))
{
......@@ -696,6 +724,7 @@ function handleKey(key) {
lastFocusedCreditItem = focusedElement.nextElementSibling;
focusedElement = lastFocusedCreditItem;
focusedElement.classList.add("focused");
setIconLightness(focusedElement.firstChild);
}
}
}
......@@ -951,11 +980,16 @@ function filterItemToggle(filterItem) {
function resetFilter() {
for(i in filterItems)
{
if(filterItems[i].classList && filterItems[i].classList.contains("off"))
if(filterItems[i].classList)
{
filterItemToggle(filterItems[i]);
var selectedCategory = filterItems[i].classList[1];
if(filterInitState[selectedCategory].off ^ filterState[selectedCategory].off)
{
filterItemToggle(filterItems[i]);
}
}
}
if(filterMode == "exclusive")
{
toggleFilterMode();
......@@ -1082,7 +1116,7 @@ function mouseOverReferences(reference) {
focusedElement = lastFocusedReference;
focusedElement.classList.add("focused");
var ourIdentifiers = reference.querySelector(".ref_indices").children;
var ourIdentifiers = reference.querySelectorAll(".timecode");
weWereLastFocused = false;
for(var k = 0; k < ourIdentifiers.length; ++k)
{
......@@ -1094,7 +1128,7 @@ function mouseOverReferences(reference) {
if(!weWereLastFocused)
{
lastFocusedIdentifier.classList.remove("focused");
lastFocusedIdentifier = reference.querySelector(".ref_indices").firstElementChild;
lastFocusedIdentifier = ourIdentifiers[0];
}
focusedIdentifer = lastFocusedIdentifier;
focusedIdentifer.classList.add("focused");
......@@ -1219,7 +1253,19 @@ function setDotLightness(topicDot)
}
else
{
topicDot.style.backgroundColor = ("hsl(" + Hue + ", " + Saturation + "%, 24%)");
topicDot.style.borderColor = ("hsl(" + Hue + ", " + Saturation + "%, 24%)");
topicDot.style.backgroundColor = ("hsl(" + Hue + ", " + Saturation + "%, 47%)");
topicDot.style.borderColor = ("hsl(" + Hue + ", " + Saturation + "%, 47%)");
}
}