Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topic parser rewrite #138

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8a3611b
Working on rewriting the topic parser.
peterasujan Apr 5, 2015
56f9df8
Parsing almost fully written. About to try it.
peterasujan Apr 7, 2015
3c10307
I think I have the basic parser working. Haven't tested on too many t…
peterasujan Apr 7, 2015
e519a87
Couple things.
peterasujan Apr 7, 2015
d7ae669
Got raw html working.
peterasujan Apr 7, 2015
d3d030b
Added example topic -> json in docs.
peterasujan Apr 7, 2015
815953d
Rendering seems to be working okay. Need to test on other topic files…
peterasujan Apr 7, 2015
c30b749
Fixed snap ugliness in section titles.
peterasujan Apr 9, 2015
2daf28d
add test topic file
cycomachead Apr 9, 2015
7219b86
normalize text for spacing
cycomachead Apr 9, 2015
16401e8
Merge branch 'topic-parser-rewrite' of github.com:beautyjoy/llab into…
peterasujan Apr 9, 2015
1688b7d
Fixed raw html bug.
peterasujan Apr 9, 2015
72e793e
normalize tabs
cycomachead Apr 9, 2015
359d789
lots of code cleanup
cycomachead Apr 9, 2015
548a42c
old tags array is not needed.
cycomachead Apr 9, 2015
50c8b8d
more minor code style tweaks and comments
cycomachead Apr 9, 2015
fa28e34
spacing
cycomachead Apr 9, 2015
22826dc
merge with master
cycomachead May 20, 2015
ee10bd1
The course link matches current behavior
cycomachead May 21, 2015
7b2e0ef
course link is in the the top menu on topic pages
cycomachead May 21, 2015
0b3ec9e
comment spacing
cycomachead May 23, 2015
c2eb511
Fix the URL bug in topic rendering
cycomachead May 24, 2015
7505a66
Don't render hidden items on topic pages
cycomachead May 24, 2015
4c7ec1e
mathjax test
cycomachead Jun 22, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
lots of code cleanup
  • Loading branch information
cycomachead committed Apr 9, 2015
commit 359d789a68fc179670ad57d332c90be921218e7b
13 changes: 7 additions & 6 deletions script/library.js
Original file line number Diff line number Diff line change
@@ -224,24 +224,25 @@ llab.getAttributesForElement = function(elm) {
};


// These are STRINGS that are query selectors for selecting page elements
// We want to store them in a single place because it's easier to update
llab.selectors = {};
// These are code fragments which are reusable components.
llab.fragments = {};
// These are common strings that need not be build and should be reused!
llab.strings = {};
llab.strings.goMain = 'Go to the Course Page';
// … is ellipsis
llab.strings.clickNav = 'Click here to navigate  ';
//
// These are code fragments which are reusable components.
llab.fragments = {};
llab.fragments.bootstrapSep = '<li class="divider list_item" role="presentation"></li>';
llab.fragments.bootstrapCaret = '<span class="caret"></span>';
llab.fragments.hamburger = '<span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>';
// These are STRINGS that are query selectors for selecting page elements
// We want to store them in a single place because it's easier to update
llab.selectors = {};
// LLAB selectors for common page elements
llab.selectors.FULL = '.full';
llab.selectors.NAVSELECT = '.llab-nav';
llab.selectors.PROGRESS = '.full-bottom-bar';
llab.selectors.NAVTITLE = '.navbar-title';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed double and single quotes.

llab.selectors.MOBILETITLE = '.title-small-screen';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed double and single quotes.
Too many errors. (81% scanned).


//// cookie stuff
// someday my framework will come, but for now, stolen blithely from http://www.quirksmode.org/js/cookies.html
245 changes: 130 additions & 115 deletions script/topic.js
Original file line number Diff line number Diff line change
@@ -26,8 +26,8 @@
The line will be treated as any other line otherwise

raw-html:
all following lines until a blank line are just raw html that stuck on the page.
(Michael claims that a blank line is actually not necessary)
all following lines until a blank line or a resource tag are just raw html
that is inserted into the model.

other currently supported classes: quiz, assignment, resource, forum, video, extresource.

@@ -47,132 +47,145 @@
*/
llab.tags = ["h1", "h2", "h3", "h4", "h5", "h6"];
llab.topicKeywords = {};
llab.topicKeywords.resources = ["quiz", "assignment", "resource", "forum", "video", "extresource", "reading", "group"];
llab.topicKeywords.resources = ["quiz", "assignment", "resource",
"forum", "video", "extresource",
"reading", "group"];
llab.topicKeywords.headings = ["h1", "h2", "h3", "h4", "h5", "h6", "heading"];
llab.topicKeywords.info = ["big-idea", "learning-goal"]

llab.matchesArray = function(line, A) {
var matches = A.map(function(s) {return line.match(s);});
return llab.any(matches.map(function(m) {return m != null;}));
}

llab.getKeyword = function(line, A) {
var matches = A.map(function(s) {return line.match(s);});
return A[llab.which(matches.map(function(m) {return m != null;}))];
}

llab.getContent = function(line) {
var sepIdx = line.indexOf(':');
var content = line.slice(sepIdx + 1);
var sliced = content.split(/\[|\]/);
return {text: sliced[0], url: sliced[1]};
}

llab.isResource = function(line) {
return llab.matchesArray(line, llab.topicKeywords.resources);
}

llab.isInfo = function(line) {
return llab.matchesArray(line, llab.topicKeywords.info);
}

llab.isHeading = function(line) {
return llab.matchesArray(line, llab.topicKeywords.headings);
}

llab.isKeyword = function(line) {
return llab.isResource(line) || llab.isInfo(line) || llab.isHeading(line);
}

llab.renderFull = function(data, ignored1, ignored2) {
var content = llab.parseTopicFile(data);
llab.renderTopicModel(content);
}

llab.parseTopicFile = function(data) {

llab.file = llab.topic;

data = data.replace(/(\r)/gm,""); // normalize line endings
var lines = data.split("\n");
var topics = {topics: []};
var topics = { topics: [] };
var line, topic_model, item, list, text, content, section, indent;
var in_topic = false, raw = false;
var url = document.URL;
for (var i = 0; i < lines.length; i++) {
line = llab.stripComments(lines[i]);
line = $.trim(line);
line = $.trim(line); // FIXME -- can't do this!
if (line.length && !raw) {
if (line.match(/^title:/)) {
topics.title = line.slice(6);
} else if (line.match(/^topic:/)) {
topic_model.title = line.slice(6);
topics.title = line.slice(6);
} else if (line.match(/^topic:/)) {
topic_model.title = line.slice(6);
} else if (line.match(/^raw-html/)) {
raw = true;
} else if (line[0] == "{") {
topic_model = {type: 'topic', url: '', contents: []}; // TODO: Figure out url
topics.topics.push(topic_model);
section = {title: '', contents: [], type: 'section'};
topic_model.contents.push(section);
// TODO: Figure out url
topic_model = { type: 'topic', url: '', contents: [] };
topics.topics.push(topic_model);
section = { title: '', contents: [], type: 'section' };
topic_model.contents.push(section);
} else if (llab.isHeading(line)) {
headingType = llab.getKeyword(line, llab.topicKeywords.headings);
if (section.contents.length > 0) {
section = {title: '', contents: [], type: 'section'};
headingType = llab.getKeyword(line, llab.topicKeywords.headings);
if (section.contents.length > 0) {
section = { title: '', contents: [], type: 'section' };
topic_model.contents.push(section);
}
section.title = llab.getContent(line)['text'];
section.headingType = headingType;
}
section.title = llab.getContent(line)['text'];
section.headingType = headingType;
} else if (line[0] == "}") {
// shouldn't matter
// shouldn't matter
} else if (llab.isInfo(line)) {
tag = llab.getKeyword(line, llab.topicKeywords.info);
indent = llab.indentLevel(line);
content = llab.getContent(line)['text'];
item = {type: tag, contents: content, indent: indent};
tag = llab.getKeyword(line, llab.topicKeywords.info);
indent = llab.indentLevel(line);
content = llab.getContent(line)['text']; // ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed double and single quotes.
['text'] is better written in dot notation.

// todo: do we really need indentation now?
// if so, I think it should be added to the type
// and only if indentation levels != nested levels.
item = { type: tag, contents: content, indent: indent };
section.contents.push(item);
} else if (llab.isResource(line) || true) { // dumb way to handle lines without a known tag
tag = llab.getKeyword(line, llab.topicKeywords.resources);
} else if (llab.isResource(line) || true) {
// FIXME: dumb way to handle lines without a known tag
// Shouldn't this just be an else case?
tag = llab.getKeyword(line, llab.topicKeywords.resources);
indent = llab.indentLevel(line);
content = llab.getContent(line);
item = {type: tag, indent: indent, contents: content.text, url: content.url};
section.contents.push(item);
content = llab.getContent(line);
item = { type: tag, indent: indent, contents: content.text,
url: content.url };
section.contents.push(item);
}
} else if (line.length == 0) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use '===' to compare with '0'.

raw = false;
}
}
if (raw) {
var raw_html = [];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'raw_html' is not in camel case.

text = llab.getContent(line)['text']; // in case they start the raw html on the same line
if (text) {
raw_html.push(text)
}
text = llab.getContent(line)['text']; // in case they start the raw html on the same line

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.
Mixed double and single quotes.
['text'] is better written in dot notation.

if (text) {
raw_html.push(text)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'raw_html' is not in camel case.
Missing semicolon.

}
// FIXME -- if nested topics are good check for {
while (lines[i+1].length >= 1 && lines[i+1].slice(0) != "}" && !llab.isKeyword(lines[i+1])) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long.

i++;
line = lines[i];
raw_html.push(line);
i++;
line = lines[i];
raw_html.push(line);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identifier 'raw_html' is not in camel case.

}
section.contents.push({type: 'raw_html', contents: raw_html});

section.contents.push({ type: 'raw_html', contents: raw_html });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed double and single quotes.
Identifier 'raw_html' is not in camel case.

raw = false;
}
}
}
llab.topics = topics; // TODO: this is for testing purposes
// $('body').append("<pre>\n" + JSON.stringify(llab.topics, null, '\t') + "\n</pre>") // testing

return topics;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.


llab.matchesArray = function(line, A) {
var matches = A.map(function(s) {return line.match(s) });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.

return llab.any(matches.map(function(m) {return m != null }));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use '!==' to compare with 'null'.
Missing semicolon.

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.


llab.getKeyword = function(line, A) {
var matches = A.map(function(s) {return line.match(s) });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.

return A[llab.which(matches.map(function(m) {return m != null }))];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use '!==' to compare with 'null'.
Missing semicolon.

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.


llab.getContent = function(line) {
var sepIdx = line.indexOf(':');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed double and single quotes.

var content = line.slice(sepIdx + 1);
var sliced = content.split(/\[|\]/);
return { text: sliced[0], url: sliced[1] };
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.


llab.isResource = function(line) {
return llab.matchesArray(line, llab.topicKeywords.resources);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.


llab.isInfo = function(line) {
return llab.matchesArray(line, llab.topicKeywords.info);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.


llab.isHeading = function(line) {
return llab.matchesArray(line, llab.topicKeywords.headings);
}

llab.isKeyword = function(line) {
return llab.isResource(line) || llab.isInfo(line) || llab.isHeading(line);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.
Too many errors. (48% scanned).


llab.renderFull = function(data, ignored1, ignored2) {
var content = llab.parseTopicFile(data);
llab.renderTopicModel(content);
}

// TODO: this data format is messy.
llab.renderTopicModel = function(topics) {
llab.renderTitle(topics.title);
for (var i = 0; i < topics.topics.length; i++) {
llab.renderTopic(topics.topics[i]);
}
topics.topics.forEach(function(topic) {
llab.renderTopic(topic);
});
}

llab.renderTitle = function(title) {
$('.title-small-screen').html(title);
$('.navbar-title').html(title);
var titleText = $('.navbar-title').text();
var navbar, titleText;
navbar = $(llab.selectors.NAVTITLE)
$(llab.selectors.MOBILETITLE).html(title);
navbar.html(title);
titleText = navbar.text(); // Normalize Window Title
titleText = titleText.replace('snap', 'Snap!');
document.title = titleText;
}
@@ -181,59 +194,61 @@ llab.renderTopic = function(topic_model) {
var FULL = llab.selectors.FULL,
params = llab.getURLParameters(),
course = params.course;
var topicDOM = $(document.createElement("div")).attr({'class': 'topic'});
$(FULL).append(topicDOM);
topicDOM.append($(document.createElement("div")).attr({'class': 'topic_header'}).append(topic_model.title))
var topicDOM = $("<div>").attr({ 'class': 'topic' });

topicDOM.append($(document.createElement("div")).attr(
{'class': 'topic_header'}).append(topic_model.title));

// FIXME -- forEach
var current;
for (var i = 0; i < topic_model.contents.length; i++) {
current = topic_model.contents[i];
if (current.type == "section") {
llab.renderSection(current, topicDOM);
}
current = topic_model.contents[i];
if (current.type == "section") {
llab.renderSection(current, topicDOM);
}
}

// Make sure to only update view once things are rendered.
$(FULL).append(topicDOM);
}

llab.renderSection = function(section, parent) {
var sectionDOM = $(document.createElement("section")).appendTo(parent);
var sectionDOM = $("<section>");
if (section.title) {
var headingType = section.headingType;
if (!llab.isTag(headingType) || headingType == "heading") {
headingType = "h3";
}
sectionDOM.append($(document.createElement(headingType)).append(section.title));
var tag = section.headingType == "heading" ? 'h3' : section.headingType;
sectionDOM.append($('<' + tag + '>').append(section.title));
}

var current;
for (var i = 0; i < section.contents.length; i++) {
current = section.contents[i];
if (current.type && llab.isResource(current.type)) {
llab.renderResource(current, sectionDOM);
} else if (current.type && llab.isInfo(current.type)) {
var infoSection = [current];
while (i < section.contents.length - 1 && section.contents[i].type == current.type) {
i++;
infoSection.push(section.contents[i]);
current = section.contents[i];
if (current.type && llab.isResource(current.type)) {
llab.renderResource(current, sectionDOM);
} else if (current.type && llab.isInfo(current.type)) {
var infoSection = [current];
while (i < section.contents.length - 1 && section.contents[i].type == current.type) {
i++;
infoSection.push(section.contents[i]);
}
llab.renderInfo(infoSection, current.type, sectionDOM);
} else if (current.type == "section") {
llab.renderSection(current, sectionDOM);
} else { // handles current.type == "raw_html"
sectionDOM.append(current.contents);
}
llab.renderInfo(infoSection, current.type, sectionDOM);
} else if (current.type == "section") {
llab.renderSection(current, sectionDOM);
} else if (current.type == "raw_html") {
sectionDOM.append(current.contents);
} else {
sectionDOM.append(current.contents);
}
}

sectionDOM.appendTo(parent);
}

llab.renderResource = function(resource, parent) {
var item = $(document.createElement("div")).attr({'class': resource.type});
var new_contents = resource.contents + "\n";
if (resource.url) {
var slash = resource.url[0] == "/" ? '' : '/';
item.append($(document.createElement("a")).attr({'href': llab.rootURL + slash + resource.url}).append(new_contents));
var slash = resource.url[0] == "/" ? '' : '/';
item.append($(document.createElement("a")).attr({'href': llab.rootURL + slash + resource.url}).append(new_contents));
} else {
item.append(new_contents);
item.append(new_contents);
}
parent.append(item);
}