mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-02-02 20:29:10 +00:00
Text-slicer refactoring
Substantially cleaning up the main slicer code
This commit is contained in:
parent
97979e1fb1
commit
abd8201aaa
@ -24,10 +24,8 @@ var SLICER_OUTPUT_TITLE = "$:/TextSlicer";
|
|||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
$tw.rootWidget.addEventListener("tm-slice-tiddler",function(event) {
|
$tw.rootWidget.addEventListener("tm-slice-tiddler",function(event) {
|
||||||
var slicer = new Slicer($tw.wiki,event.param);
|
var slicer = new Slicer($tw.wiki,event.param);
|
||||||
// slicer.sliceTiddler();
|
slicer.sliceTiddler(event.param)
|
||||||
// slicer.outputTiddlers();
|
slicer.outputTiddlers(event.param);
|
||||||
// Slice up and output the tiddler
|
|
||||||
slicer.outputTiddlers(slicer.sliceTiddler(event.param),event.param,event.param);
|
|
||||||
slicer.destroy();
|
slicer.destroy();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -38,6 +36,9 @@ function Slicer(wiki,sourceTitle) {
|
|||||||
this.currentId = 0;
|
this.currentId = 0;
|
||||||
this.iframe = null; // Reference to iframe used for HTML parsing
|
this.iframe = null; // Reference to iframe used for HTML parsing
|
||||||
this.stopWordList = "the and a of on i".split(" ");
|
this.stopWordList = "the and a of on i".split(" ");
|
||||||
|
this.tiddlers = {};
|
||||||
|
this.parentStack = [];
|
||||||
|
this.sliceTitle = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slicer.prototype.destroy = function() {
|
Slicer.prototype.destroy = function() {
|
||||||
@ -51,6 +52,50 @@ Slicer.prototype.nextId = function() {
|
|||||||
return ++this.currentId;
|
return ++this.currentId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Slicer.prototype.addTiddler = function(fields) {
|
||||||
|
if(fields.title) {
|
||||||
|
this.tiddlers[fields.title] = $tw.utils.extend({},this.tiddlers[fields.title],fields);
|
||||||
|
return fields.title;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Slicer.prototype.addToList = function(parent,child) {
|
||||||
|
var parentTiddler = this.tiddlers[parent] || {},
|
||||||
|
parentList = parentTiddler.list || [];
|
||||||
|
parentList.push(child);
|
||||||
|
this.addTiddler($tw.utils.extend({title: parent},parentTiddler,{list: parentList}));
|
||||||
|
};
|
||||||
|
|
||||||
|
Slicer.prototype.popParentStackUntil = function(type) {
|
||||||
|
// Pop the stack to remove any entries at the same or lower level
|
||||||
|
var newLevel = this.convertTypeToLevel(type),
|
||||||
|
topIndex = this.parentStack.length - 1;
|
||||||
|
do {
|
||||||
|
var topLevel = this.convertTypeToLevel(this.parentStack[this.parentStack.length - 1].type);
|
||||||
|
if(topLevel !== null && topLevel < newLevel ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.parentStack.length--;
|
||||||
|
} while(true);
|
||||||
|
return this.parentStack[this.parentStack.length - 1].title;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Slicer.prototype.convertTypeToLevel = function(type) {
|
||||||
|
if(type.charAt(0) === "h") {
|
||||||
|
return parseInt(type.charAt(1),10);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Slicer.prototype.isBlank = function(s) {
|
||||||
|
return (/^[\s\xA0]*$/mg).test(s);
|
||||||
|
};
|
||||||
|
|
||||||
Slicer.prototype.getSourceHtmlDocument = function(tiddler) {
|
Slicer.prototype.getSourceHtmlDocument = function(tiddler) {
|
||||||
this.iframe = document.createElement("iframe");
|
this.iframe = document.createElement("iframe");
|
||||||
document.body.appendChild(this.iframe);
|
document.body.appendChild(this.iframe);
|
||||||
@ -76,7 +121,7 @@ Slicer.prototype.getSourceDocument = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Slicer.prototype.makeParagraphTitle = function(title,text) {
|
Slicer.prototype.makeParagraphTitle = function(text) {
|
||||||
// Remove characters other than lowercase alphanumeric and spaces
|
// Remove characters other than lowercase alphanumeric and spaces
|
||||||
var self = this,
|
var self = this,
|
||||||
cleanText = text.toLowerCase().replace(/[^\s\xA0]/mg,function($0,$1,$2) {
|
cleanText = text.toLowerCase().replace(/[^\s\xA0]/mg,function($0,$1,$2) {
|
||||||
@ -98,138 +143,107 @@ Slicer.prototype.makeParagraphTitle = function(title,text) {
|
|||||||
while(c < words.length && (s.length + words[c].length + 1) < 50) {
|
while(c < words.length && (s.length + words[c].length + 1) < 50) {
|
||||||
s += "-" + words[c++];
|
s += "-" + words[c++];
|
||||||
}
|
}
|
||||||
return this.wiki.generateNewTitle("para" + s);
|
// Check for duplicates
|
||||||
|
var baseTitle = "para" + s;
|
||||||
|
c = 0;
|
||||||
|
var title = baseTitle;
|
||||||
|
while(this.tiddlers[title] || this.wiki.tiddlerExists(title) || this.wiki.isShadowTiddler(title) || this.wiki.findDraft(title)) {
|
||||||
|
title = baseTitle + " " + (++c);
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
};
|
||||||
|
|
||||||
|
Slicer.prototype.processNodeList = function(domNodeList) {
|
||||||
|
$tw.utils.each(domNodeList,this.processNode.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
Slicer.prototype.processNode = function(domNode) {
|
||||||
|
var parentTitle, tags,
|
||||||
|
text = domNode.textContent,
|
||||||
|
nodeType = domNode.nodeType;
|
||||||
|
if(nodeType === 1) {
|
||||||
|
var tagName = domNode.tagName.toLowerCase();
|
||||||
|
if(tagName === "h1" || tagName === "h2" || tagName === "h3" || tagName === "h4") {
|
||||||
|
if(!this.isBlank(text)) {
|
||||||
|
parentTitle = this.popParentStackUntil(tagName);
|
||||||
|
tags = [parentTitle];
|
||||||
|
if(domNode.className.trim() !== "") {
|
||||||
|
tags = tags.concat(domNode.className.split(" "));
|
||||||
|
}
|
||||||
|
this.addToList(parentTitle,text);
|
||||||
|
this.parentStack.push({type: tagName, title: this.addTiddler({
|
||||||
|
title: text,
|
||||||
|
text: "<<display-heading-tiddler level:'" + tagName + "'>>",
|
||||||
|
list: [],
|
||||||
|
tags: tags
|
||||||
|
})});
|
||||||
|
}
|
||||||
|
} else if(tagName === "ul" || tagName === "ol") {
|
||||||
|
var listTitle = this.sliceTitle + "-list-" + this.nextId();
|
||||||
|
parentTitle = this.parentStack[this.parentStack.length - 1].title;
|
||||||
|
tags = [parentTitle];
|
||||||
|
if(domNode.className.trim() !== "") {
|
||||||
|
tags = tags.concat(domNode.className.split(" "));
|
||||||
|
}
|
||||||
|
this.addToList(parentTitle,listTitle);
|
||||||
|
this.parentStack.push({type: tagName, title: this.addTiddler({
|
||||||
|
title: listTitle,
|
||||||
|
text: "<<display-list-tiddler type:'" + tagName + "'>>",
|
||||||
|
list: [],
|
||||||
|
tags: tags
|
||||||
|
})});
|
||||||
|
this.processNodeList(domNode.childNodes);
|
||||||
|
this.parentStack.pop();
|
||||||
|
} else if(tagName === "li") {
|
||||||
|
if(!this.isBlank(text)) {
|
||||||
|
var listItemTitle = this.sliceTitle + "-listitem-" + this.nextId();
|
||||||
|
parentTitle = this.parentStack[this.parentStack.length - 1].title;
|
||||||
|
tags = [parentTitle];
|
||||||
|
if(domNode.className.trim() !== "") {
|
||||||
|
tags = tags.concat(domNode.className.split(" "));
|
||||||
|
}
|
||||||
|
this.addToList(parentTitle,listItemTitle);
|
||||||
|
this.addTiddler({
|
||||||
|
title: listItemTitle,
|
||||||
|
text: text,
|
||||||
|
list: [],
|
||||||
|
tags: tags
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if(tagName === "p") {
|
||||||
|
if(!this.isBlank(text)) {
|
||||||
|
parentTitle = this.parentStack[this.parentStack.length - 1].title;
|
||||||
|
tags = [parentTitle];
|
||||||
|
if(domNode.className.trim() !== "") {
|
||||||
|
tags = tags.concat(domNode.className.split(" "));
|
||||||
|
}
|
||||||
|
this.addToList(parentTitle,this.addTiddler({
|
||||||
|
title: this.makeParagraphTitle(text),
|
||||||
|
text: text,
|
||||||
|
tags: tags
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
} else if(domNode.hasChildNodes()) {
|
||||||
|
this.processNodeList(domNode.childNodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Slice a tiddler into individual tiddlers
|
// Slice a tiddler into individual tiddlers
|
||||||
Slicer.prototype.sliceTiddler = function(title) {
|
Slicer.prototype.sliceTiddler = function(title) {
|
||||||
var self = this,
|
this.sliceTitle = title;
|
||||||
tiddlers = {},
|
var domNode = this.getSourceDocument();
|
||||||
domNode = this.getSourceDocument(),
|
this.parentStack.push({type: "h0", title: this.addTiddler({
|
||||||
parentStack = [],
|
|
||||||
addTiddler = function(fields) {
|
|
||||||
if(fields.title) {
|
|
||||||
tiddlers[fields.title] = $tw.utils.extend({},tiddlers[fields.title],fields);
|
|
||||||
return fields.title;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addToList = function(parent,child) {
|
|
||||||
var parentTiddler = tiddlers[parent] || {},
|
|
||||||
parentList = parentTiddler.list || [];
|
|
||||||
parentList.push(child);
|
|
||||||
addTiddler($tw.utils.extend({title: parent},parentTiddler,{list: parentList}));
|
|
||||||
},
|
|
||||||
convertTypeToLevel = function(type) {
|
|
||||||
if(type.charAt(0) === "h") {
|
|
||||||
return parseInt(type.charAt(1),10);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
popParentStackUntil = function(type) {
|
|
||||||
// Pop the stack to remove any entries at the same or lower level
|
|
||||||
var newLevel = convertTypeToLevel(type),
|
|
||||||
topIndex = parentStack.length - 1;
|
|
||||||
do {
|
|
||||||
var topLevel = convertTypeToLevel(parentStack[parentStack.length - 1].type);
|
|
||||||
if(topLevel !== null && topLevel < newLevel ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
parentStack.length--;
|
|
||||||
} while(true);
|
|
||||||
return parentStack[parentStack.length - 1].title;
|
|
||||||
},
|
|
||||||
isBlank = function(s) {
|
|
||||||
return (/^[\s\xA0]*$/mg).test(s);
|
|
||||||
},
|
|
||||||
processNodeList = function(domNodeList) {
|
|
||||||
$tw.utils.each(domNodeList,function(domNode) {
|
|
||||||
var parentTitle, tags,
|
|
||||||
text = domNode.textContent,
|
|
||||||
nodeType = domNode.nodeType;
|
|
||||||
if(nodeType === 1) {
|
|
||||||
var tagName = domNode.tagName.toLowerCase();
|
|
||||||
if(tagName === "h1" || tagName === "h2" || tagName === "h3" || tagName === "h4") {
|
|
||||||
if(!isBlank(text)) {
|
|
||||||
parentTitle = popParentStackUntil(tagName);
|
|
||||||
tags = [parentTitle];
|
|
||||||
if(domNode.className.trim() !== "") {
|
|
||||||
tags = tags.concat(domNode.className.split(" "));
|
|
||||||
}
|
|
||||||
addToList(parentTitle,text);
|
|
||||||
parentStack.push({type: tagName, title: addTiddler({
|
|
||||||
title: text,
|
|
||||||
text: "<<display-heading-tiddler level:'" + tagName + "'>>",
|
|
||||||
list: [],
|
|
||||||
tags: tags
|
|
||||||
})});
|
|
||||||
}
|
|
||||||
} else if(tagName === "ul" || tagName === "ol") {
|
|
||||||
var listTitle = title + "-list-" + self.nextId();
|
|
||||||
parentTitle = parentStack[parentStack.length - 1].title;
|
|
||||||
tags = [parentTitle];
|
|
||||||
if(domNode.className.trim() !== "") {
|
|
||||||
tags = tags.concat(domNode.className.split(" "));
|
|
||||||
}
|
|
||||||
addToList(parentTitle,listTitle);
|
|
||||||
parentStack.push({type: tagName, title: addTiddler({
|
|
||||||
title: listTitle,
|
|
||||||
text: "<<display-list-tiddler type:'" + tagName + "'>>",
|
|
||||||
list: [],
|
|
||||||
tags: tags
|
|
||||||
})});
|
|
||||||
processNodeList(domNode.childNodes);
|
|
||||||
parentStack.pop();
|
|
||||||
} else if(tagName === "li") {
|
|
||||||
if(!isBlank(text)) {
|
|
||||||
var listItemTitle = title + "-listitem-" + self.nextId();
|
|
||||||
parentTitle = parentStack[parentStack.length - 1].title;
|
|
||||||
tags = [parentTitle];
|
|
||||||
if(domNode.className.trim() !== "") {
|
|
||||||
tags = tags.concat(domNode.className.split(" "));
|
|
||||||
}
|
|
||||||
addToList(parentTitle,listItemTitle);
|
|
||||||
addTiddler({
|
|
||||||
title: listItemTitle,
|
|
||||||
text: text,
|
|
||||||
list: [],
|
|
||||||
tags: tags
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if(tagName === "p") {
|
|
||||||
if(!isBlank(text)) {
|
|
||||||
parentTitle = parentStack[parentStack.length - 1].title;
|
|
||||||
tags = [parentTitle];
|
|
||||||
if(domNode.className.trim() !== "") {
|
|
||||||
tags = tags.concat(domNode.className.split(" "));
|
|
||||||
}
|
|
||||||
addToList(parentTitle,addTiddler({
|
|
||||||
title: self.makeParagraphTitle(title,text),
|
|
||||||
text: text,
|
|
||||||
tags: tags
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
} else if(domNode.hasChildNodes()) {
|
|
||||||
processNodeList(domNode.childNodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
parentStack.push({type: "h0", title: addTiddler({
|
|
||||||
title: "Sliced up " + title,
|
title: "Sliced up " + title,
|
||||||
text: "{{||$:/plugins/tiddlywiki/text-slicer/templates/display-document}}",
|
text: "{{||$:/plugins/tiddlywiki/text-slicer/templates/display-document}}",
|
||||||
list: []
|
list: []
|
||||||
})});
|
})});
|
||||||
console.log(domNode);
|
this.processNodeList(domNode.childNodes);
|
||||||
processNodeList(domNode.childNodes);
|
|
||||||
return tiddlers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Output directly to the output tiddlers
|
// Output directly to the output tiddlers
|
||||||
Slicer.prototype.outputTiddlers = function(tiddlers,title,navigateFromTitle) {
|
Slicer.prototype.outputTiddlers = function(navigateFromTitle) {
|
||||||
$tw.utils.each(tiddlers,function(tiddlerFields) {
|
$tw.utils.each(this.tiddlers,function(tiddlerFields) {
|
||||||
var title = tiddlerFields.title;
|
var title = tiddlerFields.title;
|
||||||
if(title) {
|
if(title) {
|
||||||
$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddlerFields,$tw.wiki.getModificationFields()));
|
$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddlerFields,$tw.wiki.getModificationFields()));
|
||||||
@ -237,7 +251,7 @@ Slicer.prototype.outputTiddlers = function(tiddlers,title,navigateFromTitle) {
|
|||||||
});
|
});
|
||||||
// Navigate to output
|
// Navigate to output
|
||||||
var story = new $tw.Story({wiki: $tw.wiki});
|
var story = new $tw.Story({wiki: $tw.wiki});
|
||||||
story.navigateTiddler("Sliced up " + title,navigateFromTitle);
|
story.navigateTiddler("Sliced up " + this.sliceTitle,navigateFromTitle);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Output via an import tiddler
|
// Output via an import tiddler
|
||||||
|
@ -8,15 +8,15 @@ $:/plugins/tiddlywiki/text-slicer/config/show-toolbar/$(currentTiddler)$
|
|||||||
$:/plugins/tiddlywiki/text-slicer/config/view-type/$(currentTiddler)$
|
$:/plugins/tiddlywiki/text-slicer/config/view-type/$(currentTiddler)$
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define display-document()
|
\define toc-document()
|
||||||
<<display-heading-tiddler level:'h1'>>
|
<<display-heading-tiddler level:'h1'>>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
\define display-tiddler()
|
\define display-document()
|
||||||
<$set name="tv-show-toolbar" value={{$(config-show-toolbar)$}}>
|
<$set name="tv-show-toolbar" value={{$(config-show-toolbar)$}}>
|
||||||
|
|
||||||
View: <$select tiddler=<<config-view-type>> default="toc-tabbed-internal-nav">
|
View: <$select tiddler=<<config-view-type>> default="toc-tabbed-internal-nav">
|
||||||
<option value="display-document">Document</option>
|
<option value="toc-document">Document</option>
|
||||||
<option value="toc-selective-expandable">Outline</option>
|
<option value="toc-selective-expandable">Outline</option>
|
||||||
<option value="toc-tabbed-internal-nav">Tabbed outline</option>
|
<option value="toc-tabbed-internal-nav">Tabbed outline</option>
|
||||||
</$select>
|
</$select>
|
||||||
@ -44,4 +44,4 @@ View: <$select tiddler=<<config-view-type>> default="toc-tabbed-internal-nav">
|
|||||||
</$set>
|
</$set>
|
||||||
\end
|
\end
|
||||||
|
|
||||||
<<display-tiddler>>
|
<<display-document>>
|
||||||
|
Loading…
Reference in New Issue
Block a user