mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-24 17:36:14 -04:00
resolve merge conflict
This commit is contained in:
commit
58bbfd8a65
210 changed files with 12113 additions and 7505 deletions
|
@ -63,7 +63,7 @@ if(os.type().indexOf("Windows") > -1)
|
|||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.convertFile = function(srcFile, destFile, type, callback)
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ else
|
|||
{
|
||||
//add data to buffer
|
||||
stdoutBuffer+=data.toString();
|
||||
|
||||
|
||||
//we're searching for the prompt, cause this means everything we need is in the buffer
|
||||
if(stdoutBuffer.search("AbiWord:>") != -1)
|
||||
{
|
||||
|
@ -121,27 +121,29 @@ else
|
|||
firstPrompt = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
spawnAbiword();
|
||||
|
||||
doConvertTask = function(task, callback)
|
||||
{
|
||||
abiword.stdin.write("convert " + task.srcFile + " " + task.destFile + " " + task.type + "\n");
|
||||
|
||||
//create a callback that calls the task callback and the caller callback
|
||||
stdoutCallback = function (err)
|
||||
{
|
||||
callback();
|
||||
console.log("queue continue");
|
||||
task.callback(err);
|
||||
try{
|
||||
task.callback(err);
|
||||
}catch(e){
|
||||
console.error("Abiword File failed to convert", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//Queue with the converts we have to do
|
||||
var queue = async.queue(doConvertTask, 1);
|
||||
|
||||
exports.convertFile = function(srcFile, destFile, type, callback)
|
||||
{
|
||||
{
|
||||
queue.push({"srcFile": srcFile, "destFile": destFile, "type": type, "callback": callback});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ exports.getPadDokuWikiDocument = function (padId, revNum, callback)
|
|||
|
||||
getPadDokuWiki(pad, revNum, callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function _escapeDokuWiki(s)
|
||||
{
|
||||
|
|
87
src/node/utils/ExportHelper.js
Normal file
87
src/node/utils/ExportHelper.js
Normal file
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Helpers for export requests
|
||||
*/
|
||||
|
||||
/*
|
||||
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var async = require("async");
|
||||
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||
var padManager = require("../db/PadManager");
|
||||
var ERR = require("async-stacktrace");
|
||||
var Security = require('ep_etherpad-lite/static/js/security');
|
||||
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
|
||||
exports.getPadPlainText = function(pad, revNum){
|
||||
var atext = ((revNum !== undefined) ? pad.getInternalRevisionAText(revNum) : pad.atext());
|
||||
var textLines = atext.text.slice(0, -1).split('\n');
|
||||
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
||||
var apool = pad.pool();
|
||||
|
||||
var pieces = [];
|
||||
for (var i = 0; i < textLines.length; i++){
|
||||
var line = _analyzeLine(textLines[i], attribLines[i], apool);
|
||||
if (line.listLevel){
|
||||
var numSpaces = line.listLevel * 2 - 1;
|
||||
var bullet = '*';
|
||||
pieces.push(new Array(numSpaces + 1).join(' '), bullet, ' ', line.text, '\n');
|
||||
}
|
||||
else{
|
||||
pieces.push(line.text, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return pieces.join('');
|
||||
};
|
||||
|
||||
|
||||
exports._analyzeLine = function(text, aline, apool){
|
||||
var line = {};
|
||||
|
||||
// identify list
|
||||
var lineMarker = 0;
|
||||
line.listLevel = 0;
|
||||
if (aline){
|
||||
var opIter = Changeset.opIterator(aline);
|
||||
if (opIter.hasNext()){
|
||||
var listType = Changeset.opAttributeValue(opIter.next(), 'list', apool);
|
||||
if (listType){
|
||||
lineMarker = 1;
|
||||
listType = /([a-z]+)([12345678])/.exec(listType);
|
||||
if (listType){
|
||||
line.listTypeName = listType[1];
|
||||
line.listLevel = Number(listType[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lineMarker){
|
||||
line.text = text.substring(1);
|
||||
line.aline = Changeset.subattribution(aline, 1);
|
||||
}
|
||||
else{
|
||||
line.text = text;
|
||||
line.aline = aline;
|
||||
}
|
||||
return line;
|
||||
};
|
||||
|
||||
|
||||
exports._encodeWhitespace = function(s){
|
||||
return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c){
|
||||
return "&#" +c.charCodeAt(0) + ";";
|
||||
});
|
||||
};
|
|
@ -21,31 +21,9 @@ var padManager = require("../db/PadManager");
|
|||
var ERR = require("async-stacktrace");
|
||||
var Security = require('ep_etherpad-lite/static/js/security');
|
||||
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
function getPadPlainText(pad, revNum)
|
||||
{
|
||||
var atext = ((revNum !== undefined) ? pad.getInternalRevisionAText(revNum) : pad.atext());
|
||||
var textLines = atext.text.slice(0, -1).split('\n');
|
||||
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
||||
var apool = pad.pool();
|
||||
|
||||
var pieces = [];
|
||||
for (var i = 0; i < textLines.length; i++)
|
||||
{
|
||||
var line = _analyzeLine(textLines[i], attribLines[i], apool);
|
||||
if (line.listLevel)
|
||||
{
|
||||
var numSpaces = line.listLevel * 2 - 1;
|
||||
var bullet = '*';
|
||||
pieces.push(new Array(numSpaces + 1).join(' '), bullet, ' ', line.text, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
pieces.push(line.text, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return pieces.join('');
|
||||
}
|
||||
var getPadPlainText = require('./ExportHelper').getPadPlainText;
|
||||
var _analyzeLine = require('./ExportHelper')._analyzeLine;
|
||||
var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
|
||||
|
||||
function getPadHTML(pad, revNum, callback)
|
||||
{
|
||||
|
@ -469,7 +447,7 @@ function getHTMLFromAtext(pad, atext, authorColors)
|
|||
pieces.push('</li></ul>');
|
||||
}
|
||||
lists.length--;
|
||||
}
|
||||
}
|
||||
var lineContentFromHook = hooks.callAllStr("getLineHTMLForExport",
|
||||
{
|
||||
line: line,
|
||||
|
@ -477,14 +455,14 @@ function getHTMLFromAtext(pad, atext, authorColors)
|
|||
attribLine: attribLines[i],
|
||||
text: textLines[i]
|
||||
}, " ", " ", "");
|
||||
if (lineContentFromHook)
|
||||
{
|
||||
pieces.push(lineContentFromHook, '');
|
||||
}
|
||||
else
|
||||
{
|
||||
pieces.push(lineContent, '<br>');
|
||||
}
|
||||
if (lineContentFromHook)
|
||||
{
|
||||
pieces.push(lineContentFromHook, '');
|
||||
}
|
||||
else
|
||||
{
|
||||
pieces.push(lineContent, '<br>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,45 +481,6 @@ function getHTMLFromAtext(pad, atext, authorColors)
|
|||
return pieces.join('');
|
||||
}
|
||||
|
||||
function _analyzeLine(text, aline, apool)
|
||||
{
|
||||
var line = {};
|
||||
|
||||
// identify list
|
||||
var lineMarker = 0;
|
||||
line.listLevel = 0;
|
||||
if (aline)
|
||||
{
|
||||
var opIter = Changeset.opIterator(aline);
|
||||
if (opIter.hasNext())
|
||||
{
|
||||
var listType = Changeset.opAttributeValue(opIter.next(), 'list', apool);
|
||||
if (listType)
|
||||
{
|
||||
lineMarker = 1;
|
||||
listType = /([a-z]+)([12345678])/.exec(listType);
|
||||
if (listType)
|
||||
{
|
||||
line.listTypeName = listType[1];
|
||||
line.listLevel = Number(listType[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lineMarker)
|
||||
{
|
||||
line.text = text.substring(1);
|
||||
line.aline = Changeset.subattribution(aline, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
line.text = text;
|
||||
line.aline = aline;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
|
||||
{
|
||||
padManager.getPad(padId, function (err, pad)
|
||||
|
@ -551,7 +490,7 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
|
|||
var head =
|
||||
(noDocType ? '' : '<!doctype html>\n') +
|
||||
'<html lang="en">\n' + (noDocType ? '' : '<head>\n' +
|
||||
'<title>' + Security.escapeHTML(padId) + '</title>\n' +
|
||||
'<title>' + Security.escapeHTML(padId) + '</title>\n' +
|
||||
'<meta charset="utf-8">\n' +
|
||||
'<style> * { font-family: arial, sans-serif;\n' +
|
||||
'font-size: 13px;\n' +
|
||||
|
@ -576,80 +515,7 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
|
|||
callback(null, head + html + foot);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _encodeWhitespace(s) {
|
||||
return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c)
|
||||
{
|
||||
return "&#" +c.charCodeAt(0) + ";"
|
||||
});
|
||||
}
|
||||
|
||||
// copied from ACE
|
||||
|
||||
|
||||
function _processSpaces(s)
|
||||
{
|
||||
var doesWrap = true;
|
||||
if (s.indexOf("<") < 0 && !doesWrap)
|
||||
{
|
||||
// short-cut
|
||||
return s.replace(/ /g, ' ');
|
||||
}
|
||||
var parts = [];
|
||||
s.replace(/<[^>]*>?| |[^ <]+/g, function (m)
|
||||
{
|
||||
parts.push(m);
|
||||
});
|
||||
if (doesWrap)
|
||||
{
|
||||
var endOfLine = true;
|
||||
var beforeSpace = false;
|
||||
// last space in a run is normal, others are nbsp,
|
||||
// end of line is nbsp
|
||||
for (var i = parts.length - 1; i >= 0; i--)
|
||||
{
|
||||
var p = parts[i];
|
||||
if (p == " ")
|
||||
{
|
||||
if (endOfLine || beforeSpace) parts[i] = ' ';
|
||||
endOfLine = false;
|
||||
beforeSpace = true;
|
||||
}
|
||||
else if (p.charAt(0) != "<")
|
||||
{
|
||||
endOfLine = false;
|
||||
beforeSpace = false;
|
||||
}
|
||||
}
|
||||
// beginning of line is nbsp
|
||||
for (var i = 0; i < parts.length; i++)
|
||||
{
|
||||
var p = parts[i];
|
||||
if (p == " ")
|
||||
{
|
||||
parts[i] = ' ';
|
||||
break;
|
||||
}
|
||||
else if (p.charAt(0) != "<")
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < parts.length; i++)
|
||||
{
|
||||
var p = parts[i];
|
||||
if (p == " ")
|
||||
{
|
||||
parts[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
return parts.join('');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// copied from ACE
|
||||
|
@ -676,3 +542,56 @@ function _findURLs(text)
|
|||
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
// copied from ACE
|
||||
function _processSpaces(s){
|
||||
var doesWrap = true;
|
||||
if (s.indexOf("<") < 0 && !doesWrap){
|
||||
// short-cut
|
||||
return s.replace(/ /g, ' ');
|
||||
}
|
||||
var parts = [];
|
||||
s.replace(/<[^>]*>?| |[^ <]+/g, function (m){
|
||||
parts.push(m);
|
||||
});
|
||||
if (doesWrap){
|
||||
var endOfLine = true;
|
||||
var beforeSpace = false;
|
||||
// last space in a run is normal, others are nbsp,
|
||||
// end of line is nbsp
|
||||
for (var i = parts.length - 1; i >= 0; i--){
|
||||
var p = parts[i];
|
||||
if (p == " "){
|
||||
if (endOfLine || beforeSpace) parts[i] = ' ';
|
||||
endOfLine = false;
|
||||
beforeSpace = true;
|
||||
}
|
||||
else if (p.charAt(0) != "<"){
|
||||
endOfLine = false;
|
||||
beforeSpace = false;
|
||||
}
|
||||
}
|
||||
// beginning of line is nbsp
|
||||
for (var i = 0; i < parts.length; i++){
|
||||
var p = parts[i];
|
||||
if (p == " "){
|
||||
parts[i] = ' ';
|
||||
break;
|
||||
}
|
||||
else if (p.charAt(0) != "<"){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < parts.length; i++){
|
||||
var p = parts[i];
|
||||
if (p == " "){
|
||||
parts[i] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
return parts.join('');
|
||||
}
|
||||
|
|
292
src/node/utils/ExportTxt.js
Normal file
292
src/node/utils/ExportTxt.js
Normal file
|
@ -0,0 +1,292 @@
|
|||
/**
|
||||
* TXT export
|
||||
*/
|
||||
|
||||
/*
|
||||
* 2013 John McLear
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var async = require("async");
|
||||
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||
var padManager = require("../db/PadManager");
|
||||
var ERR = require("async-stacktrace");
|
||||
var Security = require('ep_etherpad-lite/static/js/security');
|
||||
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
|
||||
var getPadPlainText = require('./ExportHelper').getPadPlainText;
|
||||
var _analyzeLine = require('./ExportHelper')._analyzeLine;
|
||||
|
||||
// This is slightly different than the HTML method as it passes the output to getTXTFromAText
|
||||
function getPadTXT(pad, revNum, callback)
|
||||
{
|
||||
var atext = pad.atext;
|
||||
var html;
|
||||
async.waterfall([
|
||||
// fetch revision atext
|
||||
|
||||
|
||||
function (callback)
|
||||
{
|
||||
if (revNum != undefined)
|
||||
{
|
||||
pad.getInternalRevisionAText(revNum, function (err, revisionAtext)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
atext = revisionAtext;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
callback(null);
|
||||
}
|
||||
},
|
||||
|
||||
// convert atext to html
|
||||
|
||||
|
||||
function (callback)
|
||||
{
|
||||
html = getTXTFromAtext(pad, atext); // only this line is different to the HTML function
|
||||
callback(null);
|
||||
}],
|
||||
// run final callback
|
||||
|
||||
|
||||
function (err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, html);
|
||||
});
|
||||
}
|
||||
|
||||
exports.getPadTXT = getPadTXT;
|
||||
|
||||
|
||||
// This is different than the functionality provided in ExportHtml as it provides formatting
|
||||
// functionality that is designed specifically for TXT exports
|
||||
function getTXTFromAtext(pad, atext, authorColors)
|
||||
{
|
||||
var apool = pad.apool();
|
||||
var textLines = atext.text.slice(0, -1).split('\n');
|
||||
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
|
||||
|
||||
var tags = ['h1', 'h2', 'strong', 'em', 'u', 's'];
|
||||
var props = ['heading1', 'heading2', 'bold', 'italic', 'underline', 'strikethrough'];
|
||||
var anumMap = {};
|
||||
var css = "";
|
||||
|
||||
props.forEach(function (propName, i)
|
||||
{
|
||||
var propTrueNum = apool.putAttrib([propName, true], true);
|
||||
if (propTrueNum >= 0)
|
||||
{
|
||||
anumMap[propTrueNum] = i;
|
||||
}
|
||||
});
|
||||
|
||||
function getLineTXT(text, attribs)
|
||||
{
|
||||
var propVals = [false, false, false];
|
||||
var ENTER = 1;
|
||||
var STAY = 2;
|
||||
var LEAVE = 0;
|
||||
|
||||
// Use order of tags (b/i/u) as order of nesting, for simplicity
|
||||
// and decent nesting. For example,
|
||||
// <b>Just bold<b> <b><i>Bold and italics</i></b> <i>Just italics</i>
|
||||
// becomes
|
||||
// <b>Just bold <i>Bold and italics</i></b> <i>Just italics</i>
|
||||
var taker = Changeset.stringIterator(text);
|
||||
var assem = Changeset.stringAssembler();
|
||||
var openTags = [];
|
||||
|
||||
var idx = 0;
|
||||
|
||||
function processNextChars(numChars)
|
||||
{
|
||||
if (numChars <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var iter = Changeset.opIterator(Changeset.subattribution(attribs, idx, idx + numChars));
|
||||
idx += numChars;
|
||||
|
||||
while (iter.hasNext())
|
||||
{
|
||||
var o = iter.next();
|
||||
var propChanged = false;
|
||||
Changeset.eachAttribNumber(o.attribs, function (a)
|
||||
{
|
||||
if (a in anumMap)
|
||||
{
|
||||
var i = anumMap[a]; // i = 0 => bold, etc.
|
||||
if (!propVals[i])
|
||||
{
|
||||
propVals[i] = ENTER;
|
||||
propChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
propVals[i] = STAY;
|
||||
}
|
||||
}
|
||||
});
|
||||
for (var i = 0; i < propVals.length; i++)
|
||||
{
|
||||
if (propVals[i] === true)
|
||||
{
|
||||
propVals[i] = LEAVE;
|
||||
propChanged = true;
|
||||
}
|
||||
else if (propVals[i] === STAY)
|
||||
{
|
||||
propVals[i] = true; // set it back
|
||||
}
|
||||
}
|
||||
// now each member of propVal is in {false,LEAVE,ENTER,true}
|
||||
// according to what happens at start of span
|
||||
if (propChanged)
|
||||
{
|
||||
// leaving bold (e.g.) also leaves italics, etc.
|
||||
var left = false;
|
||||
for (var i = 0; i < propVals.length; i++)
|
||||
{
|
||||
var v = propVals[i];
|
||||
if (!left)
|
||||
{
|
||||
if (v === LEAVE)
|
||||
{
|
||||
left = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v === true)
|
||||
{
|
||||
propVals[i] = STAY; // tag will be closed and re-opened
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tags2close = [];
|
||||
|
||||
for (var i = propVals.length - 1; i >= 0; i--)
|
||||
{
|
||||
if (propVals[i] === LEAVE)
|
||||
{
|
||||
//emitCloseTag(i);
|
||||
tags2close.push(i);
|
||||
propVals[i] = false;
|
||||
}
|
||||
else if (propVals[i] === STAY)
|
||||
{
|
||||
//emitCloseTag(i);
|
||||
tags2close.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < propVals.length; i++)
|
||||
{
|
||||
if (propVals[i] === ENTER || propVals[i] === STAY)
|
||||
{
|
||||
propVals[i] = true;
|
||||
}
|
||||
}
|
||||
// propVals is now all {true,false} again
|
||||
} // end if (propChanged)
|
||||
|
||||
var chars = o.chars;
|
||||
if (o.lines)
|
||||
{
|
||||
chars--; // exclude newline at end of line, if present
|
||||
}
|
||||
|
||||
var s = taker.take(chars);
|
||||
|
||||
// removes the characters with the code 12. Don't know where they come
|
||||
// from but they break the abiword parser and are completly useless
|
||||
// s = s.replace(String.fromCharCode(12), "");
|
||||
|
||||
// remove * from s, it's just not needed on a blank line.. This stops
|
||||
// plugins from being able to display * at the beginning of a line
|
||||
// s = s.replace("*", ""); // Then remove it
|
||||
|
||||
assem.append(s);
|
||||
} // end iteration over spans in line
|
||||
|
||||
var tags2close = [];
|
||||
for (var i = propVals.length - 1; i >= 0; i--)
|
||||
{
|
||||
if (propVals[i])
|
||||
{
|
||||
tags2close.push(i);
|
||||
propVals[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // end processNextChars
|
||||
processNextChars(text.length - idx);
|
||||
return(assem.toString());
|
||||
} // end getLineHTML
|
||||
var pieces = [css];
|
||||
|
||||
// Need to deal with constraints imposed on HTML lists; can
|
||||
// only gain one level of nesting at once, can't change type
|
||||
// mid-list, etc.
|
||||
// People might use weird indenting, e.g. skip a level,
|
||||
// so we want to do something reasonable there. We also
|
||||
// want to deal gracefully with blank lines.
|
||||
// => keeps track of the parents level of indentation
|
||||
var lists = []; // e.g. [[1,'bullet'], [3,'bullet'], ...]
|
||||
for (var i = 0; i < textLines.length; i++)
|
||||
{
|
||||
var line = _analyzeLine(textLines[i], attribLines[i], apool);
|
||||
var lineContent = getLineTXT(line.text, line.aline);
|
||||
if(line.listTypeName == "bullet"){
|
||||
lineContent = "* " + lineContent; // add a bullet
|
||||
}
|
||||
if(line.listLevel > 0){
|
||||
for (var j = line.listLevel - 1; j >= 0; j--){
|
||||
pieces.push('\t');
|
||||
}
|
||||
if(line.listTypeName == "number"){
|
||||
pieces.push(line.listLevel + ". ");
|
||||
// This is bad because it doesn't truly reflect what the user
|
||||
// sees because browsers do magic on nested <ol><li>s
|
||||
}
|
||||
pieces.push(lineContent, '\n');
|
||||
}else{
|
||||
pieces.push(lineContent, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
return pieces.join('');
|
||||
}
|
||||
exports.getTXTFromAtext = getTXTFromAtext;
|
||||
|
||||
exports.getPadTXTDocument = function (padId, revNum, noDocType, callback)
|
||||
{
|
||||
padManager.getPad(padId, function (err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
getPadTXT(pad, revNum, function (err, html)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
callback(null, html);
|
||||
});
|
||||
});
|
||||
};
|
|
@ -26,7 +26,13 @@ function setPadHTML(pad, html, callback)
|
|||
var apiLogger = log4js.getLogger("ImportHtml");
|
||||
|
||||
// Parse the incoming HTML with jsdom
|
||||
var doc = jsdom(html.replace(/>\n+</g, '><'));
|
||||
try{
|
||||
var doc = jsdom(html.replace(/>\n+</g, '><'));
|
||||
}catch(e){
|
||||
apiLogger.warn("Error importing, possibly caused by malformed HTML");
|
||||
var doc = jsdom("<html><body><div>Error during import, possibly malformed HTML</div></body></html>");
|
||||
}
|
||||
|
||||
apiLogger.debug('html:');
|
||||
apiLogger.debug(html);
|
||||
|
||||
|
|
|
@ -125,11 +125,11 @@ function requestURIs(locations, method, headers, callback) {
|
|||
}
|
||||
|
||||
function completed() {
|
||||
var statuss = responses.map(function (x) {return x[0]});
|
||||
var headerss = responses.map(function (x) {return x[1]});
|
||||
var contentss = responses.map(function (x) {return x[2]});
|
||||
var statuss = responses.map(function (x) {return x[0];});
|
||||
var headerss = responses.map(function (x) {return x[1];});
|
||||
var contentss = responses.map(function (x) {return x[2];});
|
||||
callback(statuss, headerss, contentss);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,7 +263,7 @@ function getAceFile(callback) {
|
|||
var filename = item.match(/"([^"]*)"/)[1];
|
||||
var request = require('request');
|
||||
|
||||
var baseURI = 'http://localhost:' + settings.port
|
||||
var baseURI = 'http://localhost:' + settings.port;
|
||||
var resourceURI = baseURI + path.normalize(path.join('/static/', filename));
|
||||
resourceURI = resourceURI.replace(/\\/g, '/'); // Windows (safe generally?)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* The Settings Modul reads the settings out of settings.json and provides
|
||||
* The Settings Modul reads the settings out of settings.json and provides
|
||||
* this information to the other modules
|
||||
*/
|
||||
|
||||
|
@ -24,8 +24,10 @@ var os = require("os");
|
|||
var path = require('path');
|
||||
var argv = require('./Cli').argv;
|
||||
var npm = require("npm/lib/npm.js");
|
||||
var vm = require('vm');
|
||||
var jsonminify = require("jsonminify");
|
||||
var log4js = require("log4js");
|
||||
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||
|
||||
|
||||
/* Root path of the installation */
|
||||
exports.root = path.normalize(path.join(npm.dir, ".."));
|
||||
|
@ -33,7 +35,7 @@ exports.root = path.normalize(path.join(npm.dir, ".."));
|
|||
/**
|
||||
* The app title, visible e.g. in the browser window
|
||||
*/
|
||||
exports.title = "Etherpad Lite";
|
||||
exports.title = "Etherpad";
|
||||
|
||||
/**
|
||||
* The app favicon fully specified url, visible e.g. in the browser window
|
||||
|
@ -46,7 +48,7 @@ exports.faviconTimeslider = "../../" + exports.favicon;
|
|||
* The IP ep-lite should listen to
|
||||
*/
|
||||
exports.ip = "0.0.0.0";
|
||||
|
||||
|
||||
/**
|
||||
* The Port ep-lite should listen to
|
||||
*/
|
||||
|
@ -75,7 +77,7 @@ exports.dbSettings = { "filename" : path.join(exports.root, "dirty.db") };
|
|||
/**
|
||||
* The default Text of a new pad
|
||||
*/
|
||||
exports.defaultPadText = "Welcome to Etherpad Lite!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad Lite on Github: http:\/\/j.mp/ep-lite\n";
|
||||
exports.defaultPadText = "Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad on Github: http:\/\/j.mp/ep-lite\n";
|
||||
|
||||
/**
|
||||
* A flag that requires any user to have a valid session (via the api) before accessing a pad
|
||||
|
@ -107,11 +109,26 @@ exports.abiword = null;
|
|||
*/
|
||||
exports.loglevel = "INFO";
|
||||
|
||||
/**
|
||||
* Disable IP logging
|
||||
*/
|
||||
exports.disableIPlogging = false;
|
||||
|
||||
/*
|
||||
* log4js appender configuration
|
||||
*/
|
||||
exports.logconfig = { appenders: [{ type: "console" }]};
|
||||
|
||||
/*
|
||||
* Session Key, do not sure this.
|
||||
*/
|
||||
exports.sessionKey = false;
|
||||
|
||||
/*
|
||||
* Trust Proxy, whether or not trust the x-forwarded-for header.
|
||||
*/
|
||||
exports.trustProxy = false;
|
||||
|
||||
/* This setting is used if you need authentication and/or
|
||||
* authorization. Note: /admin always requires authentication, and
|
||||
* either authorization by a module, or a user with is_admin set */
|
||||
|
@ -130,14 +147,12 @@ exports.abiwordAvailable = function()
|
|||
{
|
||||
return "no";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
exports.reloadSettings = function reloadSettings() {
|
||||
// Discover where the settings file lives
|
||||
var settingsFilename = argv.settings || "settings.json";
|
||||
settingsFilename = path.resolve(path.join(root, settingsFilename));
|
||||
settingsFilename = path.resolve(path.join(exports.root, settingsFilename));
|
||||
|
||||
var settingsStr;
|
||||
try{
|
||||
|
@ -151,7 +166,8 @@ exports.reloadSettings = function reloadSettings() {
|
|||
var settings;
|
||||
try {
|
||||
if(settingsStr) {
|
||||
settings = vm.runInContext('exports = '+settingsStr, vm.createContext(), "settings.json");
|
||||
settingsStr = jsonminify(settingsStr).replace(",]","]").replace(",}","}");
|
||||
settings = JSON.parse(settingsStr);
|
||||
}
|
||||
}catch(e){
|
||||
console.error('There was an error processing your settings.json file: '+e.message);
|
||||
|
@ -179,15 +195,20 @@ exports.reloadSettings = function reloadSettings() {
|
|||
console.warn("Unknown Setting: '" + i + "'. This setting doesn't exist or it was removed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log4js.configure(exports.logconfig);//Configure the logging appenders
|
||||
log4js.setGlobalLogLevel(exports.loglevel);//set loglevel
|
||||
log4js.replaceConsole();
|
||||
|
||||
if(exports.dbType === "dirty"){
|
||||
console.warn("DirtyDB is used. This is fine for testing but not recommended for production.")
|
||||
if(!exports.sessionKey){ // If the secretKey isn't set we also create yet another unique value here
|
||||
exports.sessionKey = randomString(32);
|
||||
console.warn("You need to set a sessionKey value in settings.json, this will allow your users to reconnect to your Etherpad Instance if your instance restarts");
|
||||
}
|
||||
}
|
||||
|
||||
if(exports.dbType === "dirty"){
|
||||
console.warn("DirtyDB is used. This is fine for testing but not recommended for production.");
|
||||
}
|
||||
};
|
||||
|
||||
// initially load settings
|
||||
exports.reloadSettings();
|
||||
|
|
|
@ -23,7 +23,7 @@ var util = require('util');
|
|||
var settings = require('./Settings');
|
||||
var semver = require('semver');
|
||||
|
||||
var existsSync = (semver.satisfies(process.version, '>=0.8.0')) ? fs.existsSync : path.existsSync
|
||||
var existsSync = (semver.satisfies(process.version, '>=0.8.0')) ? fs.existsSync : path.existsSync;
|
||||
|
||||
var CACHE_DIR = path.normalize(path.join(settings.root, 'var/'));
|
||||
CACHE_DIR = existsSync(CACHE_DIR) ? CACHE_DIR : undefined;
|
||||
|
@ -133,7 +133,7 @@ CachingMiddleware.prototype = new function () {
|
|||
old_res.write = res.write;
|
||||
old_res.end = res.end;
|
||||
res.write = function(data, encoding) {};
|
||||
res.end = function(data, encoding) { respond() };
|
||||
res.end = function(data, encoding) { respond(); };
|
||||
} else {
|
||||
res.writeHead(status, headers);
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ CachingMiddleware.prototype = new function () {
|
|||
} else if (req.method == 'GET') {
|
||||
var readStream = fs.createReadStream(pathStr);
|
||||
res.writeHead(statusCode, headers);
|
||||
util.pump(readStream, res);
|
||||
readStream.pipe(res);
|
||||
} else {
|
||||
res.writeHead(statusCode, headers);
|
||||
res.end();
|
||||
|
|
|
@ -68,7 +68,7 @@ PadDiff.prototype._isClearAuthorship = function(changeset){
|
|||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype._createClearAuthorship = function(rev, callback){
|
||||
var self = this;
|
||||
|
@ -84,7 +84,7 @@ PadDiff.prototype._createClearAuthorship = function(rev, callback){
|
|||
|
||||
callback(null, changeset);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype._createClearStartAtext = function(rev, callback){
|
||||
var self = this;
|
||||
|
@ -107,7 +107,7 @@ PadDiff.prototype._createClearStartAtext = function(rev, callback){
|
|||
callback(null, newAText);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype._getChangesetsInBulk = function(startRev, count, callback) {
|
||||
var self = this;
|
||||
|
@ -124,7 +124,7 @@ PadDiff.prototype._getChangesetsInBulk = function(startRev, count, callback) {
|
|||
async.forEach(revisions, function(rev, callback){
|
||||
self._pad.getRevision(rev, function(err, revision){
|
||||
if(err){
|
||||
return callback(err)
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var arrayNum = rev-startRev;
|
||||
|
@ -137,7 +137,7 @@ PadDiff.prototype._getChangesetsInBulk = function(startRev, count, callback) {
|
|||
}, function(err){
|
||||
callback(err, changesets, authors);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype._addAuthors = function(authors) {
|
||||
var self = this;
|
||||
|
@ -147,7 +147,7 @@ PadDiff.prototype._addAuthors = function(authors) {
|
|||
self._authors.push(author);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype._createDiffAtext = function(callback) {
|
||||
var self = this;
|
||||
|
@ -219,7 +219,7 @@ PadDiff.prototype._createDiffAtext = function(callback) {
|
|||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype.getHtml = function(callback){
|
||||
//cache the html
|
||||
|
@ -279,7 +279,7 @@ PadDiff.prototype.getAuthors = function(callback){
|
|||
} else {
|
||||
callback(null, self._authors);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PadDiff.prototype._extendChangesetWithAuthor = function(changeset, author, apool) {
|
||||
//unpack
|
||||
|
@ -312,7 +312,7 @@ PadDiff.prototype._extendChangesetWithAuthor = function(changeset, author, apool
|
|||
|
||||
//return the modified changeset
|
||||
return Changeset.pack(unpacked.oldLen, unpacked.newLen, assem.toString(), unpacked.charBank);
|
||||
}
|
||||
};
|
||||
|
||||
//this method is 80% like Changeset.inverse. I just changed so instead of reverting, it adds deletions and attribute changes to to the atext.
|
||||
PadDiff.prototype._createDeletionChangeset = function(cs, startAText, apool) {
|
||||
|
@ -331,14 +331,6 @@ PadDiff.prototype._createDeletionChangeset = function(cs, startAText, apool) {
|
|||
}
|
||||
}
|
||||
|
||||
function lines_length() {
|
||||
if ((typeof lines.length) == "number") {
|
||||
return lines.length;
|
||||
} else {
|
||||
return lines.length();
|
||||
}
|
||||
}
|
||||
|
||||
function alines_get(idx) {
|
||||
if (alines.get) {
|
||||
return alines.get(idx);
|
||||
|
@ -347,14 +339,6 @@ PadDiff.prototype._createDeletionChangeset = function(cs, startAText, apool) {
|
|||
}
|
||||
}
|
||||
|
||||
function alines_length() {
|
||||
if ((typeof alines.length) == "number") {
|
||||
return alines.length;
|
||||
} else {
|
||||
return alines.length();
|
||||
}
|
||||
}
|
||||
|
||||
var curLine = 0;
|
||||
var curChar = 0;
|
||||
var curLineOpIter = null;
|
||||
|
@ -463,7 +447,7 @@ PadDiff.prototype._createDeletionChangeset = function(cs, startAText, apool) {
|
|||
// If the text this operator applies to is only a star, than this is a false positive and should be ignored
|
||||
if (csOp.attribs && textBank != "*") {
|
||||
var deletedAttrib = apool.putAttrib(["removed", true]);
|
||||
var authorAttrib = apool.putAttrib(["author", ""]);;
|
||||
var authorAttrib = apool.putAttrib(["author", ""]);
|
||||
|
||||
attribKeys.length = 0;
|
||||
attribValues.length = 0;
|
||||
|
@ -473,7 +457,7 @@ PadDiff.prototype._createDeletionChangeset = function(cs, startAText, apool) {
|
|||
|
||||
if(apool.getAttribKey(n) === "author"){
|
||||
authorAttrib = n;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
var undoBackToAttribs = cachedStrFunc(function (attribs) {
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
, "Changeset.js"
|
||||
, "ChangesetUtils.js"
|
||||
, "skiplist.js"
|
||||
, "virtual_lines.js"
|
||||
, "cssmanager.js"
|
||||
, "colorutils.js"
|
||||
, "undomodule.js"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue