hmml_to_html.c: Reference indicators [#15]

Also support multiple annotations citing the same reference
This commit is contained in:
Matt Mascarenhas 2017-03-15 02:10:11 +00:00
parent 012693bd39
commit 388c60e942
4 changed files with 159 additions and 73 deletions

View File

@ -66,7 +66,8 @@ main(int ArgC, char **Args)
// NOTE(matt): Init MemoryArena
char *MemoryArena;
int ArenaSize = 1024 * 64;
// TODO(matt): Actually calculate how much memory I'll need
int ArenaSize = 1024 * 512;
if(!(MemoryArena = calloc(ArenaSize, 1)))
{
perror(Args[0]);
@ -76,28 +77,12 @@ main(int ArgC, char **Args)
// NOTE(matt): Setup buffers and ptrs
char *InPtr;
buffer Template;
buffer Working;
buffer Text;
buffer Out;
FILE *TemplateFile;
if(!(TemplateFile = fopen("style.css", "r")))
{
perror(Args[0]);
return 1;
}
fseek(TemplateFile, 0, SEEK_END);
Template.Size = ftell(TemplateFile);
fseek(TemplateFile, 0, SEEK_SET);
Template.Location = MemoryArena + ClaimedMemory;
ClaimedMemory += Template.Size;
fread(Template.Location, Template.Size, 1, TemplateFile);
fclose(TemplateFile);
Out.Location = MemoryArena + ClaimedMemory;
Out.Size = 1024 * 32;
Out.Size = 1024 * 200;
ClaimedMemory += Out.Size;
for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex)
@ -116,7 +101,7 @@ main(int ArgC, char **Args)
if(HMML.well_formed)
{
Working.Location = MemoryArena + ClaimedMemory;
Working.Size = 1024 * 2;
Working.Size = 1024 * 1;
ClaimedMemory += Working.Size;
sprintf(Working.Location,
@ -141,6 +126,7 @@ main(int ArgC, char **Args)
}
int AnnotationIndex = 0;
int ReferenceIndex = 1;
while(AnnotationIndex < HMML.annotation_count)
{
if(HMML.annotations[AnnotationIndex].reference_count)
@ -161,26 +147,34 @@ main(int ArgC, char **Args)
{
for(int i = 0; i < HMML.annotations[AnnotationIndex].reference_count; ++i)
{
// NOTE(matt): Consider removing the ref_index class if it ain't needed
sprintf(Working.Location,
" <a data-id=\"%d\" href=\"%s\" target=\"_blank\" class=\"ref\">\n"
" <span data-timestamp=\"%d\" class=\"timecode\">(<span class=\"time\">%s</span>)</span>\n"
" <span class=\"ref_content\">\n"
" <div class=\"source\">%s</div>\n"
" <div class=\"ref_title\">%s</div>\n"
" </span>\n"
// NOTE(matt): Fill the div class="ref_indices" with <= 3 span
// class="ref_index" and ensure to put these <=3 spans on the same line without
// a space between them
" <div class=\"ref_indices\">\n"
" <span data-timestamp=\"%d\" class=\"timecode\"><span class=\"ref_index\">[%d]</span><span class=\"time\">%s</span></span>\n"
" </div>\n"
" </a>\n",
AnnotationIndex,
HMML.annotations[AnnotationIndex].references[i].url,
TimecodeToSeconds(HMML.annotations[AnnotationIndex].time),
HMML.annotations[AnnotationIndex].time,
HMML.annotations[AnnotationIndex].references[i].site ? HMML.annotations[AnnotationIndex].references[i].site : HMML.annotations[AnnotationIndex].references[i].author,
HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[AnnotationIndex].references[i].page : HMML.annotations[AnnotationIndex].references[i].title);
HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[AnnotationIndex].references[i].page : HMML.annotations[AnnotationIndex].references[i].title,
TimecodeToSeconds(HMML.annotations[AnnotationIndex].time),
ReferenceIndex,
HMML.annotations[AnnotationIndex].time);
Working.Ptr = Working.Location;
while(*Working.Ptr)
{
*Out.Ptr++ = *Working.Ptr++;
}
++ReferenceIndex;
}
++AnnotationIndex;
}
@ -204,22 +198,82 @@ HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[Annotati
*Out.Ptr++ = *Working.Ptr++;
}
int DataRef = 0;
int DataRef = 1;
for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex)
{
InPtr = HMML.annotations[AnnotationIndex].text;
Text.Location = MemoryArena + ClaimedMemory;
Text.Size = 256;
ClaimedMemory += Text.Size;
Text.Ptr = Text.Location;
if(HMML.annotations[AnnotationIndex].reference_count) // || HMML.annotations[AnnotationIndex].is_quote)
{
sprintf(Working.Location,
" <div class=\"marker\" data-timestamp=\"%d\" data-ref=\"%d\">\n", TimecodeToSeconds(HMML.annotations[AnnotationIndex].time), AnnotationIndex);
for(int RefLocalIndex = 0; RefLocalIndex < HMML.annotations[AnnotationIndex].reference_count; ++RefLocalIndex)
{
while(InPtr - HMML.annotations[AnnotationIndex].text < HMML.annotations[AnnotationIndex].references[RefLocalIndex].offset)
{
*Text.Ptr++ = *InPtr++;
}
int Inc = 0;
if(HMML.annotations[AnnotationIndex].references[RefLocalIndex].offset <= 2)
{
if(HMML.annotations[AnnotationIndex].references[RefLocalIndex].page)
{
Inc = sprintf(Text.Ptr, "%s",
HMML.annotations[AnnotationIndex].references[RefLocalIndex].page);
}
else if(HMML.annotations[AnnotationIndex].references[RefLocalIndex].site)
{
Inc = sprintf(Text.Ptr, "%s",
HMML.annotations[AnnotationIndex].references[RefLocalIndex].site);
}
else if(HMML.annotations[AnnotationIndex].references[RefLocalIndex].title)
{
Inc = sprintf(Text.Ptr, "%s",
HMML.annotations[AnnotationIndex].references[RefLocalIndex].title);
}
else
{
fprintf(stderr, "%s: Potentially incomplete reference at %s:%d\n",
Args[0],
Args[FileIndex],
HMML.annotations[AnnotationIndex].line);
}
Text.Ptr += Inc;
}
if(HMML.annotations[AnnotationIndex].references[RefLocalIndex].offset <= 2 && Text.Ptr[-1] == ' ')
{
--Text.Ptr;
}
Inc = sprintf(Text.Ptr, "<sup>%d</sup>", DataRef);
Text.Ptr += Inc;
++DataRef;
}
while(*InPtr)
{
*Text.Ptr++ = *InPtr++;
}
}
else
{
sprintf(Working.Location,
" <div class=\"marker\" data-timestamp=\"%d\">\n", TimecodeToSeconds(HMML.annotations[AnnotationIndex].time));
while(*InPtr)
{
*Text.Ptr++ = *InPtr++;
}
}
*Text.Ptr = '\0';
Text.Ptr = Text.Location;
Working.Ptr = Working.Location;
while(*Working.Ptr)
{
@ -236,13 +290,15 @@ HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[Annotati
" </div>\n"
" </div>\n",
HMML.annotations[AnnotationIndex].time,
HMML.annotations[AnnotationIndex].text,
Text.Location,
HMML.annotations[AnnotationIndex].time,
HMML.annotations[AnnotationIndex].text,
Text.Location,
HMML.annotations[AnnotationIndex].time,
HMML.annotations[AnnotationIndex].text);
Text.Location);
Working.Ptr = Working.Location;
ClaimedMemory -= Text.Size;
while(*Working.Ptr)
{
*Out.Ptr++ = *Working.Ptr++;
@ -279,6 +335,7 @@ HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[Annotati
" player.setTime(parseInt(time, 10));\n"
" player.play();\n"
" ev.preventDefault();\n"
" ev.stopPropagation();\n"
" return false;\n"
" }\n"
" });\n"
@ -296,13 +353,14 @@ HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[Annotati
"function onRefChanged(ref) {\n"
" if (ref !== undefined && ref !== null) {\n"
" document.querySelector(\".refs_container\").classList.add(\"current\");\n"
" var refs = document.querySelectorAll(\".refs .ref\");\n"
" for (var i = 0; i < refs.length; ++i) {\n"
" var dataID = refs[i].getAttribute(\"data-id\");\n"
" if (ref == dataID) {\n"
" refs[i].classList.add(\"current\");\n"
" var refElements = document.querySelectorAll(\".refs .ref\");\n"
" var refs = ref.split(\",\");\n"
"\n"
" for (var i = 0; i < refElements.length; ++i) {\n"
" if (refs.includes(refElements[i].getAttribute(\"data-id\"))) {\n"
" refElements[i].classList.add(\"current\");\n"
" } else {\n"
" refs[i].classList.remove(\"current\");\n"
" refElements[i].classList.remove(\"current\");\n"
" }\n"
" }\n"
" } else {\n"

View File

@ -14,46 +14,46 @@
<div class="mouse_catcher"></div>
<div class="refs">
<a data-id="3" href="https://github.com/ucb-bar/rocket/blob/master/src/main/scala/instructions.scala" target="_blank" class="ref">
<span data-timestamp="543" class="timecode">(<span class="time">9:03</span>)</span>
<span class="ref_content">
<div class="source">GitHub</div>
<div class="ref_title">instructions.scala</div>
</span>
<span data-timestamp="543" class="timecode"><span class="ref_index">[1]</span><span class="time">9:03</span></span>
</a>
<a data-id="3" href="https://en.wikipedia.org/wiki/Register-transfer_level" target="_blank" class="ref">
<span data-timestamp="543" class="timecode">(<span class="time">9:03</span>)</span>
<span class="ref_content">
<div class="source">Wikipedia</div>
<div class="ref_title">Register-transfer level</div>
</span>
<span data-timestamp="543" class="timecode"><span class="ref_index">[2]</span><span class="time">9:03</span></span>
</a>
<a data-id="4" href="https://forums.sifive.com/t/confusion-regarding-freedom-e-sdk-inline-asm/383" target="_blank" class="ref">
<span data-timestamp="955" class="timecode">(<span class="time">15:55</span>)</span>
<span class="ref_content">
<div class="source">SiFive Forums</div>
<div class="ref_title">Confusion Regarding Freedom E SDK inline asm</div>
</span>
<span data-timestamp="955" class="timecode"><span class="ref_index">[3]</span><span class="time">15:55</span></span>
</a>
<a data-id="6" href="https://riscv.org/specifications" target="_blank" class="ref">
<span data-timestamp="1344" class="timecode">(<span class="time">22:24</span>)</span>
<span class="ref_content">
<div class="source">RISC-V"</div>
<div class="ref_title">User-Level ISA Specification v2.1</div>
</span>
<span data-timestamp="1344" class="timecode"><span class="ref_index">[4]</span><span class="time">22:24</span></span>
</a>
<a data-id="8" href="http://ericw.ca/notes/a-tiny-guide-to-gcc-inline-assembly.html" target="_blank" class="ref">
<span data-timestamp="1733" class="timecode">(<span class="time">28:53</span>)</span>
<span class="ref_content">
<div class="source">ericw.</div>
<div class="ref_title">A Tiny Guide to GCC Inline Assembly</div>
</span>
<span data-timestamp="1733" class="timecode"><span class="ref_index">[5]</span><span class="time">28:53</span></span>
</a>
<a data-id="10" href="https://riscv.org/specifications/privileged-isa/" target="_blank" class="ref">
<span data-timestamp="2421" class="timecode">(<span class="time">40:21</span>)</span>
<span class="ref_content">
<div class="source">RISC-V</div>
<div class="ref_title">Draft Privileged ISA Specification v1.9.1</div>
</span>
<span data-timestamp="2421" class="timecode"><span class="ref_index">[6]</span><span class="time">40:21</span></span>
</a>
</div>
</div>
@ -90,21 +90,21 @@
</div>
</div>
<div class="marker" data-timestamp="543" data-ref="3">
<div class="content"><span class="timecode">9:03</span>Revisit instructions.scala and research register-transfer level</div>
<div class="content"><span class="timecode">9:03</span>Revisit instructions.scala<sup>1</sup> and research register-transfer level<sup>2</sup></div>
<div class="progress faded">
<div class="content"><span class="timecode">9:03</span>Revisit instructions.scala and research register-transfer level</div>
<div class="content"><span class="timecode">9:03</span>Revisit instructions.scala<sup>1</sup> and research register-transfer level<sup>2</sup></div>
</div>
<div class="progress main">
<div class="content"><span class="timecode">9:03</span>Revisit instructions.scala and research register-transfer level</div>
<div class="content"><span class="timecode">9:03</span>Revisit instructions.scala<sup>1</sup> and research register-transfer level<sup>2</sup></div>
</div>
</div>
<div class="marker" data-timestamp="955" data-ref="4">
<div class="content"><span class="timecode">15:55</span>Come to understand how to specify that rs1 represents an immediate or a register, thanks to the reply to the "Confusion Regarding Freedom E SDK inline asm" forum thread</div>
<div class="content"><span class="timecode">15:55</span>Come to understand how to specify that rs1 represents an immediate or a register, thanks to the reply to the "Confusion Regarding Freedom E SDK inline asm" forum thread<sup>3</sup></div>
<div class="progress faded">
<div class="content"><span class="timecode">15:55</span>Come to understand how to specify that rs1 represents an immediate or a register, thanks to the reply to the "Confusion Regarding Freedom E SDK inline asm" forum thread</div>
<div class="content"><span class="timecode">15:55</span>Come to understand how to specify that rs1 represents an immediate or a register, thanks to the reply to the "Confusion Regarding Freedom E SDK inline asm" forum thread<sup>3</sup></div>
</div>
<div class="progress main">
<div class="content"><span class="timecode">15:55</span>Come to understand how to specify that rs1 represents an immediate or a register, thanks to the reply to the "Confusion Regarding Freedom E SDK inline asm" forum thread</div>
<div class="content"><span class="timecode">15:55</span>Come to understand how to specify that rs1 represents an immediate or a register, thanks to the reply to the "Confusion Regarding Freedom E SDK inline asm" forum thread<sup>3</sup></div>
</div>
</div>
<div class="marker" data-timestamp="1105">
@ -117,12 +117,12 @@
</div>
</div>
<div class="marker" data-timestamp="1344" data-ref="6">
<div class="content"><span class="timecode">22:24</span>Read about CSRRCI in the CSR Instructions section of the User-Level ISA Specification</div>
<div class="content"><span class="timecode">22:24</span>Read about CSRRCI in the CSR Instructions section of the User-Level ISA Specification<sup>4</sup></div>
<div class="progress faded">
<div class="content"><span class="timecode">22:24</span>Read about CSRRCI in the CSR Instructions section of the User-Level ISA Specification</div>
<div class="content"><span class="timecode">22:24</span>Read about CSRRCI in the CSR Instructions section of the User-Level ISA Specification<sup>4</sup></div>
</div>
<div class="progress main">
<div class="content"><span class="timecode">22:24</span>Read about CSRRCI in the CSR Instructions section of the User-Level ISA Specification</div>
<div class="content"><span class="timecode">22:24</span>Read about CSRRCI in the CSR Instructions section of the User-Level ISA Specification<sup>4</sup></div>
</div>
</div>
<div class="marker" data-timestamp="1385">
@ -135,12 +135,12 @@
</div>
</div>
<div class="marker" data-timestamp="1733" data-ref="8">
<div class="content"><span class="timecode">28:53</span>GNU Assembly Syntax: Constraints and Syntax</div>
<div class="content"><span class="timecode">28:53</span>GNU Assembly Syntax: Constraints and Syntax<sup>5</sup></div>
<div class="progress faded">
<div class="content"><span class="timecode">28:53</span>GNU Assembly Syntax: Constraints and Syntax</div>
<div class="content"><span class="timecode">28:53</span>GNU Assembly Syntax: Constraints and Syntax<sup>5</sup></div>
</div>
<div class="progress main">
<div class="content"><span class="timecode">28:53</span>GNU Assembly Syntax: Constraints and Syntax</div>
<div class="content"><span class="timecode">28:53</span>GNU Assembly Syntax: Constraints and Syntax<sup>5</sup></div>
</div>
</div>
<div class="marker" data-timestamp="2115">
@ -153,12 +153,12 @@
</div>
</div>
<div class="marker" data-timestamp="2421" data-ref="10">
<div class="content"><span class="timecode">40:21</span>Pop back up to the top of the stack, to reset_demo(), and read about the currently allocated RISC-V machine-level CSR addresses</div>
<div class="content"><span class="timecode">40:21</span>Pop back up to the top of the stack, to reset_demo(), and read about the currently allocated RISC-V machine-level CSR addresses<sup>6</sup></div>
<div class="progress faded">
<div class="content"><span class="timecode">40:21</span>Pop back up to the top of the stack, to reset_demo(), and read about the currently allocated RISC-V machine-level CSR addresses</div>
<div class="content"><span class="timecode">40:21</span>Pop back up to the top of the stack, to reset_demo(), and read about the currently allocated RISC-V machine-level CSR addresses<sup>6</sup></div>
</div>
<div class="progress main">
<div class="content"><span class="timecode">40:21</span>Pop back up to the top of the stack, to reset_demo(), and read about the currently allocated RISC-V machine-level CSR addresses</div>
<div class="content"><span class="timecode">40:21</span>Pop back up to the top of the stack, to reset_demo(), and read about the currently allocated RISC-V machine-level CSR addresses<sup>6</sup></div>
</div>
</div>
<div class="marker" data-timestamp="2651">
@ -244,6 +244,7 @@ for (var i = 0; i < refTimecodes.length; ++i) {
player.setTime(parseInt(time, 10));
player.play();
ev.preventDefault();
ev.stopPropagation();
return false;
}
});
@ -261,13 +262,14 @@ for (var i = 0; i < refSources.length; ++i) {
function onRefChanged(ref) {
if (ref !== undefined && ref !== null) {
document.querySelector(".refs_container").classList.add("current");
var refs = document.querySelectorAll(".refs .ref");
for (var i = 0; i < refs.length; ++i) {
var dataID = refs[i].getAttribute("data-id");
if (ref == dataID) {
refs[i].classList.add("current");
var refElements = document.querySelectorAll(".refs .ref");
var refs = ref.split(",");
for (var i = 0; i < refElements.length; ++i) {
if (refs.includes(refElements[i].getAttribute("data-id"))) {
refElements[i].classList.add("current");
} else {
refs[i].classList.remove("current");
refElements[i].classList.remove("current");
}
}
} else {

View File

@ -66,6 +66,7 @@ Player.prototype.play = function() {
if (!this.playing) {
this.youtubePlayer.playVideo();
}
this.pauseAfterBuffer = false;
} else {
this.shouldPlay = true;
}

View File

@ -160,7 +160,7 @@ body {
padding: 10px;
border-bottom: 1px solid rgb(51, 51, 51);
display: flex;
flex-direction: row;
flex-direction: column;
align-items: center;
text-decoration: none;
color: white;
@ -185,18 +185,43 @@ body {
.refs .ref .timecode {
display: inline-block;
min-width: 55px;
font-size: 12px;
padding-right: 10px;
text-align: right;
padding: 0;
}
.refs .ref .ref_indices {
text-align: center;
}
.refs .ref .ref_indices .timecode {
display: inline-block;
font-size: 12px;
}
.refs .ref .ref_indices .timecode:first-child::before {
content: "";
}
.refs .ref .ref_indices .timecode::before {
content: "•";
margin: 0 4px;
}
.refs .ref .timecode:hover .time {
text-decoration: underline;
}
.refs .ref .ref_content {
width: 100%;
text-align: center;
}
.refs .ref .source {
font-size: 10px;
color: #888;
line-height: 8px;
}
.refs .ref .timecode .ref_index {
margin-right: 4px;
}