Increased section granularity
This commit is contained in:
parent
24896627c4
commit
d73f789f73
@ -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,8 +183,7 @@ 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");
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}, '');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
// Add section to the newSectionList
|
||||||
if(/\S/.test(text)) {
|
newSectionList.push({
|
||||||
// Add section to the newSectionList
|
id: ++sectionCounter,
|
||||||
newSectionList.push({
|
text: text + '\n'
|
||||||
id: ++sectionCounter,
|
});
|
||||||
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) {
|
||||||
return extension == "footnotes";
|
if(_.some(markdownExtra.config.extensions, function(extension) {
|
||||||
});
|
return extension == "footnotes";
|
||||||
|
})) {
|
||||||
|
doFootnotes = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
partialRendering.onReady = function() {
|
partialRendering.onReady = function() {
|
||||||
|
@ -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'));
|
||||||
htmlSectionList.push({
|
if(htmlSectionOffset !== undefined) {
|
||||||
startOffset: htmlSectionOffset,
|
htmlSectionList.push({
|
||||||
endOffset: newSectionOffset,
|
startOffset: htmlSectionOffset,
|
||||||
height: newSectionOffset - htmlSectionOffset
|
endOffset: newSectionOffset,
|
||||||
});
|
height: newSectionOffset - htmlSectionOffset
|
||||||
|
});
|
||||||
|
}
|
||||||
htmlSectionOffset = newSectionOffset;
|
htmlSectionOffset = newSectionOffset;
|
||||||
});
|
});
|
||||||
// Last section
|
// Last section
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user