Increased section granularity

This commit is contained in:
benweet 2013-11-17 22:59:03 +00:00
parent 24896627c4
commit d73f789f73
6 changed files with 79 additions and 53 deletions

View File

@ -98,7 +98,7 @@ define([
}; };
} }
// Add a Hook to the eventMgr that we can fire using eventMgr.eventName() // Declare an event Hook in the eventMgr that we can fire using eventMgr.eventName()
function addEventHook(eventName) { function addEventHook(eventName) {
eventMgr[eventName] = createEventHook(eventName); eventMgr[eventName] = createEventHook(eventName);
} }
@ -113,7 +113,7 @@ define([
} }
}; };
// Call every onInit listeners (extensions only) // Call every onInit listeners (enabled extensions only)
createEventHook("onInit")(); createEventHook("onInit")();
// Load/Save extension config from/to settings // Load/Save extension config from/to settings
@ -183,7 +183,6 @@ define([
addEventHook("onPagedownConfigure"); addEventHook("onPagedownConfigure");
addEventHook("onSectionsCreated"); addEventHook("onSectionsCreated");
addEventHook("onMarkdownTrim"); addEventHook("onMarkdownTrim");
addEventHook("onExtraExtensions");
// Operation on ACE // Operation on ACE
addEventHook("onAceCreated"); addEventHook("onAceCreated");

View File

@ -74,9 +74,6 @@ define([
editor.hooks.chain("onPreviewRefresh", prettify.prettyPrint); editor.hooks.chain("onPreviewRefresh", prettify.prettyPrint);
} }
Markdown.Extra.init(converter, options); Markdown.Extra.init(converter, options);
// Send extensions list to other extensions
eventMgr.onExtraExtensions(markdownExtra.config.extensions);
}; };
return markdownExtra; return markdownExtra;

View File

@ -1,6 +1,9 @@
define([ define([
"classes/Extension" "underscore",
], function(Extension) { "extensions/markdownExtra",
"extensions/mathJax",
"classes/Extension",
], function(_, markdownExtra, mathJax, Extension) {
var markdownSectionParser = new Extension("markdownSectionParser", "Markdown section parser"); var markdownSectionParser = new Extension("markdownSectionParser", "Markdown section parser");
@ -10,26 +13,49 @@ define([
}; };
markdownSectionParser.onPagedownConfigure = function(editor) { markdownSectionParser.onPagedownConfigure = function(editor) {
// Build a regexp to look for section delimiters
var regexp = '^.+[ \\t]*\\n=+[ \\t]*\\n+|^.+[ \\t]*\\n-+[ \\t]*\\n+|^\\#{1,6}[ \\t]*.+?[ \\t]*\\#*\\n+'; // Title delimiters
if(markdownExtra.config.enabled) {
if(_.some(markdownExtra.config.extensions, function(extension) {
return extension == "fenced_code_gfm";
})) {
regexp = '^```.*\\n[\\s\\S]*?\\n```|' + regexp; // Fenced block delimiters
}
}
if(mathJax.config.enabled) {
// Math delimiter has to follow 1 empty line to be considered as a section delimiter
regexp = '^[ \\t]*\\n[ \\t]*\\$\\$[\\s\\S]*\\$\\$|' + regexp; // $$ math delimiters
regexp = '^[ \\t]*\\n[ \\t]*\\\\\\\\\\[[\\s\\S]*\\\\\\\\\\]|' + regexp; // \\[ \\] math delimiters
regexp = '^[ \\t]*\\n[ \\t]*\\\\\\\\begin\\{[a-z]*\\*?\\}[\\s\\S]*\\\\\\\\end\\{[a-z]*\\*?\\}|' + regexp; // \\begin{...} \\end{...} math delimiters
}
regexp = new RegExp(regexp, 'gmi');
var converter = editor.getConverter(); var converter = editor.getConverter();
converter.hooks.chain("preConversion", function(text) { converter.hooks.chain("preConversion", function(text) {
eventMgr.previewStartTime = new Date(); eventMgr.previewStartTime = new Date();
var tmpText = text + "\n\n"; var tmpText = text + "\n\n";
var sectionList = [], offset = 0; var sectionList = [], offset = 0;
// Look for titles (excluding gfm blocs) // Look for delimiters
tmpText.replace(/^```.*\n[\s\S]*?\n```|(^.+[ \t]*\n=+[ \t]*\n+|^.+[ \t]*\n-+[ \t]*\n+|^\#{1,6}[ \t]*.+?[ \t]*\#*\n+)/gm, function(match, title, matchOffset) { tmpText.replace(regexp, function(match, matchOffset) {
if(title) { // Create a new section with the text preceding the delimiter
// We just found a title which means end of the previous var sectionText = tmpText.substring(offset, matchOffset);
// section sectionList.push({
// Exclude last \n of the section text: sectionText,
sectionList.push(tmpText.substring(offset, matchOffset)); textWithDelimiter: '\n<div class="se-section-delimiter"></div>\n\n' + sectionText + '\n'
});
offset = matchOffset; offset = matchOffset;
}
return "";
}); });
// Last section // Last section
sectionList.push(tmpText.substring(offset, text.length)); var sectionText = tmpText.substring(offset, text.length);
sectionList.push({
text: sectionText,
textWithDelimiter: '\n<div class="se-section-delimiter"></div>\n\n' + sectionText + '\n'
});
eventMgr.onSectionsCreated(sectionList); eventMgr.onSectionsCreated(sectionList);
return text; return _.reduce(sectionList, function(result, section) {
return result + section.textWithDelimiter;
}, '');
}); });
}; };

View File

@ -1,9 +1,10 @@
define([ define([
"underscore", "underscore",
"crel", "crel",
"extensions/markdownExtra",
"classes/Extension", "classes/Extension",
"text!html/partialRenderingSettingsBlock.html", "text!html/partialRenderingSettingsBlock.html",
], function(_, crel, Extension, partialRenderingSettingsBlockHTML) { ], function(_, crel, markdownExtra, Extension, partialRenderingSettingsBlockHTML) {
var partialRendering = new Extension("partialRendering", "Partial Rendering", true); var partialRendering = new Extension("partialRendering", "Partial Rendering", true);
partialRendering.settingsBlock = partialRenderingSettingsBlockHTML; partialRendering.settingsBlock = partialRenderingSettingsBlockHTML;
@ -63,6 +64,7 @@ define([
sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex); sectionsToRemove = sectionList.slice(leftIndex, sectionList.length + rightIndex);
sectionList = leftSections.concat(modifiedSections).concat(rightSections); sectionList = leftSections.concat(modifiedSections).concat(rightSections);
} }
var doFootnotes = false; var doFootnotes = false;
var hasFootnotes = false; var hasFootnotes = false;
partialRendering.onSectionsCreated = function(sectionListParam) { partialRendering.onSectionsCreated = function(sectionListParam) {
@ -70,8 +72,8 @@ define([
var newSectionList = []; var newSectionList = [];
var newLinkDefinition = '\n'; var newLinkDefinition = '\n';
hasFootnotes = false; hasFootnotes = false;
_.each(sectionListParam, function(text) { _.each(sectionListParam, function(section) {
text += "\n\n"; var text = section.textWithDelimiter + '\n';
// Strip footnotes // Strip footnotes
if(doFootnotes) { if(doFootnotes) {
@ -94,14 +96,11 @@ define([
return wholeMatch; return wholeMatch;
}); });
// Skip space only sections
if(/\S/.test(text)) {
// Add section to the newSectionList // Add section to the newSectionList
newSectionList.push({ newSectionList.push({
id: ++sectionCounter, id: ++sectionCounter,
text: text + '\n' text: text + '\n'
}); });
}
}); });
updateSectionList(newSectionList, newLinkDefinition); updateSectionList(newSectionList, newLinkDefinition);
@ -131,14 +130,14 @@ define([
id: 'wmd-preview-section-' + section.id, id: 'wmd-preview-section-' + section.id,
class: 'wmd-preview-section preview-content' class: 'wmd-preview-section preview-content'
}); });
var isFirst = true; var isNextDelimiter = false;
while (childNode) { while (childNode) {
var nextNode = childNode.nextSibling; var nextNode = childNode.nextSibling;
if(isFirst === false && /(^| )wmd-title($| )/.test(childNode.className)) { if(isNextDelimiter === true && childNode.tagName == 'DIV' && childNode.className == 'se-section-delimiter') {
// Stop when encountered the next wmd-title // Stop when encountered the next delimiter
break; break;
} }
isFirst = false; isNextDelimiter = true;
if(childNode.tagName == 'DIV' && childNode.className == 'footnotes') { if(childNode.tagName == 'DIV' && childNode.className == 'footnotes') {
_.each(childNode.querySelectorAll("ol > li"), storeFootnote); _.each(childNode.querySelectorAll("ol > li"), storeFootnote);
} }
@ -197,10 +196,14 @@ define([
}); });
}; };
partialRendering.onExtraExtensions = function(extraExtensions) { partialRendering.onInit = function(extraExtensions) {
doFootnotes = _.some(extraExtensions, function(extension) { if(markdownExtra.config.enabled) {
if(_.some(markdownExtra.config.extensions, function(extension) {
return extension == "footnotes"; return extension == "footnotes";
}); })) {
doFootnotes = true;
}
}
}; };
partialRendering.onReady = function() { partialRendering.onReady = function() {

View File

@ -37,8 +37,8 @@ define([
var mdTextOffset = 0; var mdTextOffset = 0;
var mdSectionOffset = 0; var mdSectionOffset = 0;
var firstSectionOffset = offsetBegin; var firstSectionOffset = offsetBegin;
_.each(sectionList, function(sectionText) { _.each(sectionList, function(section) {
mdTextOffset += sectionText.length + firstSectionOffset; mdTextOffset += section.text.length + firstSectionOffset;
firstSectionOffset = 0; firstSectionOffset = 0;
var documentPosition = aceEditor.session.doc.indexToPosition(mdTextOffset); var documentPosition = aceEditor.session.doc.indexToPosition(mdTextOffset);
var screenPosition = aceEditor.session.documentToScreenPosition(documentPosition.row, documentPosition.column); var screenPosition = aceEditor.session.documentToScreenPosition(documentPosition.row, documentPosition.column);
@ -54,18 +54,19 @@ define([
// Try to find corresponding sections in the preview // Try to find corresponding sections in the preview
htmlSectionList = []; htmlSectionList = [];
var htmlSectionOffset = 0; var htmlSectionOffset;
var previewScrollTop = $previewElt.scrollTop(); var previewScrollTop = $previewElt.scrollTop();
// Each title element is a section separator $previewElt.find(".preview-content > .se-section-delimiter + *").each(function() {
$previewElt.find(".preview-content > .wmd-title").each(function() { var $delimiterElt = $(this);
var $titleElt = $(this);
// Consider div scroll position and header element top margin // Consider div scroll position and header element top margin
var newSectionOffset = $titleElt.position().top + previewScrollTop + pxToFloat($titleElt.css('margin-top')); var newSectionOffset = $delimiterElt.position().top + previewScrollTop + pxToFloat($delimiterElt.css('margin-top'));
if(htmlSectionOffset !== undefined) {
htmlSectionList.push({ htmlSectionList.push({
startOffset: htmlSectionOffset, startOffset: htmlSectionOffset,
endOffset: newSectionOffset, endOffset: newSectionOffset,
height: newSectionOffset - htmlSectionOffset height: newSectionOffset - htmlSectionOffset
}); });
}
htmlSectionOffset = newSectionOffset; htmlSectionOffset = newSectionOffset;
}); });
// Last section // Last section

View File

@ -339,7 +339,7 @@ a {
display: inline-block; display: inline-block;
visibility: hidden; visibility: hidden;
width: 8px; width: 8px;
height: 7px; height: 8px;
border-radius: 1px; border-radius: 1px;
margin: 0 2px; margin: 0 2px;
background-color: @btn-success-color; background-color: @btn-success-color;