You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2041 lines
48 KiB
2041 lines
48 KiB
|
|
/* Common objects :*/ |
|
|
|
|
|
/* row in a list (<li>)*/ |
|
function listEntry(nr,rawcontent,content,level ) |
|
{ |
|
this.rawcontent=rawcontent; |
|
this.content=content; |
|
this.level=level; |
|
this.nr=nr; |
|
this.listType=""; |
|
this.parent=0; |
|
this.getListType = function () { |
|
return this.rawcontent.substr(this.level-1,1); |
|
} |
|
} |
|
|
|
/*internal wiki link */ |
|
function internalHyperlink(rawcontent,a_prefix, a_href, a_chapter, a_caption ,internalHyperlinks) |
|
{ |
|
this.rawcontent=rawcontent; |
|
this.a_prefix=a_prefix; |
|
this.a_href=a_href; |
|
this.a_chapter=a_chapter; |
|
this.a_caption=a_caption; |
|
this.renderInternalHyperLink = function () { |
|
var ret=""; |
|
if(a_chapter!="") |
|
a_chapter="#"+a_chapter; |
|
switch (a_prefix) { |
|
case "bild": |
|
ret+=renderImage(a_href,a_caption,internalHyperlinks); |
|
break; |
|
case "image": |
|
ret+=renderImage(a_href,a_caption,internalHyperlinks); |
|
break; |
|
case "kategorie": |
|
ret+="<span class=\"categoryPrefix\">Kategorie:</span><span class=\"categorySuffix\">"+a_caption+"</span>"; |
|
break; |
|
default: |
|
//normal hyperlink: |
|
ret+=createStartTag("a","href",a_href+a_chapter); |
|
if(a_caption=="") |
|
ret+=mwLink2Name(a_href); |
|
else |
|
ret+=a_caption; |
|
ret+=createEndTag("a"); |
|
break; |
|
} |
|
|
|
return ret; |
|
} |
|
} |
|
|
|
/* templates can have options (properties delimited by | ) */ |
|
function templateUsed(nr,templateName,templateParams,internalHyperlinks ) |
|
{ |
|
this.nr=nr; |
|
this.templateName=templateName; |
|
this.templateParams=templateParams; |
|
var templateParamArray = templateParams.split(/\|/); |
|
var paramCount=templateParamArray.length; |
|
var templateOptionName= new Array(paramCount); |
|
var templateOptionValue= new Array(paramCount); |
|
for(var k=0;k < templateParamArray.length;k++) |
|
{ |
|
var templateOptionDelim=templateParamArray[k].indexOf("="); |
|
templateOptionName[k]=""; |
|
templateOptionValue[k]=""; |
|
if(templateOptionDelim==-1) |
|
{ |
|
templateOptionName[k]=""; |
|
templateOptionValue[k]=templateParamArray[k].trim(); |
|
|
|
} |
|
else |
|
{ |
|
templateOptionName[k]=templateParamArray[k].substr(0,templateOptionDelim).trim(); |
|
templateOptionValue[k]=templateParamArray[k].substr(templateOptionDelim+1).trim(); |
|
|
|
} |
|
} |
|
|
|
this.renderTemplate = function () { |
|
var ret="<mwTemplate>"; |
|
switch(templateName) { |
|
case "ImageTile": |
|
ret+="<ImageTile>"; |
|
if(templateOptionName[0] && templateOptionName[0]=="imgsrc") |
|
{ |
|
ret+="<imgsrc>"+templateOptionValue[0].trim(); |
|
ret+="</imgsrc>"; |
|
} |
|
if(templateOptionName[1] && templateOptionName[1]=="link" && templateOptionValue[1].trim()!="") |
|
{ |
|
ret+="<href>"+templateOptionValue[1].trim(); |
|
|
|
var newLink = new internalHyperlink("","", templateOptionValue[1], "", templateOptionValue[1],internalHyperlinks); |
|
if(newLink) |
|
{ |
|
internalHyperlinks.push(newLink); |
|
//ret+=newLink.renderInternalHyperLink() ; |
|
} |
|
|
|
|
|
ret+="</href>"; |
|
} |
|
|
|
|
|
if(templateOptionValue[2] && templateOptionValue[2] !="") |
|
{ |
|
caption=templateOptionValue[2]; |
|
|
|
ret+="<subtitle>"+caption; |
|
|
|
if(templateOptionName[1] && templateOptionName[1]=="href" && templateOptionValue[1].trim()!="") |
|
{ |
|
var newLink = new internalHyperlink("","", templateOptionValue[1].trim(), "", caption,internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
//ret+=newLink.renderInternalHyperLink() ; |
|
} |
|
|
|
ret+="</subtitle>"; |
|
} |
|
ret+="</ImageTile>"; |
|
if(templateOptionName[0] && templateOptionName[0]=="imgsrc") |
|
{ |
|
//register the image src: |
|
var newLink = new internalHyperlink("","image", templateOptionValue[0], "", caption,internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
} |
|
|
|
break; |
|
case "Article_img_left": |
|
ret+="<Article_img_left>"; |
|
for(var i=0; i < templateOptionName.length;i++) |
|
{ |
|
if(templateOptionName[i]=="imgsrc") |
|
{ |
|
ret+="<imgsrc>"+templateOptionValue[i].trim(); |
|
ret+="</imgsrc>"; |
|
} |
|
if(templateOptionName[i]=="link") |
|
{ |
|
ret+="<href>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</href>"; |
|
var newLink = new internalHyperlink("","", templateOptionValue[i].trim(), "", "",internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
|
|
|
|
} |
|
if(templateOptionName[i]=="text") |
|
{ |
|
ret+="<text>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</text>"; |
|
|
|
} |
|
} |
|
ret+="</Article_img_left>"; |
|
//register the image src: |
|
var newLink = new internalHyperlink("","image", templateOptionValue[0], "", templateOptionValue[0],internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
|
|
|
|
|
|
break; |
|
case "drawio": |
|
var imageFile=this.templateParams+".png"; |
|
ret+="<ImagePara><param><paramName>imgsrc</paramName><paramValue>"+imageFile+"</paramValue></param>"; |
|
|
|
ret+="</ImagePara>"; |
|
if(this.templateParams !="") |
|
{ |
|
//register the image src: |
|
var newLink = new internalHyperlink("","image", imageFile, "", this.templateParams,internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
} |
|
|
|
break; |
|
case "CardWithImgHeaderandFooter": |
|
ret+="<CardWithImgHeaderandFooter>"; |
|
for(var i=0; i < templateOptionName.length;i++) |
|
{ |
|
if(templateOptionName[i]=="imgsrc") |
|
{ |
|
ret+="<imgsrc>"+templateOptionValue[i].trim(); |
|
ret+="</imgsrc>"; |
|
} |
|
if(templateOptionName[i]=="link") |
|
{ |
|
ret+="<link>"; |
|
ret+=wikiLink2Xml(templateOptionValue[i],internalHyperlinks); |
|
|
|
ret+="</link>"; |
|
|
|
|
|
} |
|
if(templateOptionName[i]=="title") |
|
{ |
|
ret+="<title>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</title>"; |
|
|
|
} |
|
if(templateOptionName[i]=="subtitle") |
|
{ |
|
ret+="<subtitle>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</subtitle>"; |
|
|
|
} |
|
/*if(templateOptionName[i]=="link1") |
|
{ |
|
ret+="<link1>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</link1>"; |
|
|
|
} |
|
|
|
if(templateOptionName[i]=="link2") |
|
{ |
|
ret+="<link2>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</link2>"; |
|
|
|
}*/ |
|
if(templateOptionName[i]=="content") |
|
{ |
|
ret+="<content>"; |
|
ret+=templateOptionValue[i]; |
|
ret+="</content>"; |
|
|
|
} |
|
} |
|
ret+="</CardWithImgHeaderandFooter>"; |
|
//register the image src: |
|
//var newLink = new internalHyperlink("","image", templateOptionValue[0], "", templateOptionValue[0],internalHyperlinks); |
|
//internalHyperlinks.push(newLink); |
|
|
|
|
|
|
|
break; |
|
default: |
|
if(templateName.indexOf(" ") > -1) |
|
templateName=templateName.replace(" ","_"); |
|
|
|
ret+="<"+templateName+">"; |
|
if(templateParams.indexOf("[[") ==-1) |
|
{ |
|
for(var k=0;k < templateParamArray.length;k++) |
|
{ |
|
ret+="<param>"; |
|
ret+="<paramName>"+templateOptionName[k]+"</paramName>"; |
|
ret+="<paramValue>"+templateOptionValue[k]+"</paramValue>"; |
|
ret+="</param>"; |
|
if(templateOptionName[k].trim()=="link") |
|
{ |
|
var newLink = new internalHyperlink("","", templateOptionValue[k].trim(), "", templateOptionValue[k].trim(),internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
} |
|
|
|
} |
|
} |
|
else |
|
ret+=templateParams+"\n"; |
|
|
|
ret+="</"+templateName+">"; |
|
break; |
|
} |
|
ret+="</mwTemplate>"; |
|
return ret; |
|
} |
|
|
|
|
|
} |
|
|
|
/* passages in a <nowiki> tag, are excluded prior to transformation. */ |
|
function nowikiPassage(nr,content) |
|
{ |
|
this.content=content; |
|
this.nr=nr; |
|
this.renderContent = function () { |
|
var ret=renderHtmlEntities(this.content); |
|
return ret; |
|
} |
|
|
|
} |
|
/* <h... tags */ |
|
function header(nr,name,level,number ) |
|
{ |
|
this.nr=nr; |
|
this.name=name; |
|
this.level=level; |
|
this.number=number; |
|
this.renderHeader = function () { |
|
var ret=""; |
|
ret+="<h"+this.level+">"+this.getAnchor()+this.name+"</h"+this.level+">"; |
|
return ret; |
|
}; |
|
this.getAnchor = function () { |
|
var ret=""; |
|
ret+="<a name=\""+encodeURI(this.name.replace(/ /g,"_"))+"\"></a>"; |
|
return ret; |
|
} |
|
} |
|
/* inline wiki formatting, e.g. italics*/ |
|
function inlineTag(mwsyntax,htmlsyntax ) |
|
{ |
|
this.mwsyntax=mwsyntax; |
|
this.htmlsyntax=htmlsyntax; |
|
} |
|
|
|
/* Whole wiki Model*/ |
|
|
|
var wikiModel = function(mw) { |
|
var wikiHtml=""; |
|
var nowikiPassages=[]; |
|
var internalHyperlinks= []; |
|
var headers=[]; |
|
var inlineTags= []; |
|
var templatesUsed= []; |
|
var counterPerLevel=[]; |
|
|
|
|
|
initInlineTags(inlineTags); |
|
//First exclude all nowiki passages since they are to be ignored: |
|
wikiHtml=maskNowiki(mw,nowikiPassages); |
|
wikiHtml=removeComments(wikiHtml); |
|
//then identify all REAL xml tags and replace non-xml-"<>" with html entities |
|
wikiHtml=parseXmlTags(wikiHtml); |
|
//then parse the chapters and fill the headers array |
|
wikiHtml=mwChaptersParser(wikiHtml,headers); |
|
//then go through the document and identify the sections (lists, tables etc.) |
|
//and render them to html |
|
wikiHtml=mwTemplatesParser(wikiHtml,templatesUsed,internalHyperlinks); |
|
//then sections: |
|
wikiHtml=mwSectionsParser(wikiHtml,internalHyperlinks,templatesUsed); |
|
//after all paragraph level transformations |
|
//the inline tags are replaced, incl. hyperlinks |
|
wikiHtml=replaceInlineTags(wikiHtml,inlineTags,internalHyperlinks,templatesUsed); |
|
//finally, reinsert all nowiki Passages |
|
wikiHtml=reinsertNowiki(wikiHtml,nowikiPassages); |
|
|
|
//serialize Arrays: |
|
var finalChar=-1; |
|
var headersStr=""; |
|
var headersLevelsStr=""; |
|
for (var i=0;i<headers.length;i++) |
|
{ |
|
headersStr+=headers[i].name.trim()+"^"; |
|
headersLevelsStr+=headers[i].level+"^"; |
|
} |
|
//delete final char: |
|
finalChar=headersStr.lastIndexOf("^"); |
|
if(finalChar>-1) |
|
headersStr=headersStr.substring(0,finalChar); |
|
finalChar=headersLevelsStr.lastIndexOf("^"); |
|
if(finalChar>-1) |
|
headersLevelsStr=headersLevelsStr.substring(0,finalChar); |
|
|
|
var internalHyperlinksStr=""; |
|
for (var i=0;i<internalHyperlinks.length;i++) |
|
{ |
|
if(internalHyperlinks[i].a_href.trim() !="") |
|
{ |
|
if(internalHyperlinks[i].a_prefix !="") |
|
internalHyperlinksStr+= internalHyperlinks[i].a_prefix.trim(); |
|
internalHyperlinksStr+=":"; |
|
internalHyperlinksStr+=internalHyperlinks[i].a_href.trim(); |
|
if(internalHyperlinks[i].a_chapter !="") |
|
internalHyperlinksStr+= "#"+internalHyperlinks[i].a_chapter.trim(); |
|
internalHyperlinksStr+="^"; |
|
} |
|
} |
|
finalChar=internalHyperlinksStr.lastIndexOf("^"); |
|
if(finalChar>-1) |
|
internalHyperlinksStr=internalHyperlinksStr.substring(0,finalChar); |
|
|
|
var templatesUsedStr=""; |
|
var templateOptionsStr=""; |
|
for (var i=0;i<templatesUsed.length;i++) |
|
{ |
|
templateOptionsStr+=templatesUsed[i].templateName.trim()+":"+templatesUsed[i].templateParams.trim()+"^"; |
|
} |
|
finalChar=templateOptionsStr.lastIndexOf("^"); |
|
if(finalChar>-1) |
|
templateOptionsStr=templateOptionsStr.substring(0,finalChar); |
|
|
|
return { |
|
wikiSrc: mw, |
|
wikiHtml: wikiHtml, |
|
headersStr:headersStr, |
|
headersLevelsStr:headersLevelsStr, |
|
internalHyperlinksStr:internalHyperlinksStr, |
|
templateOptionsStr:templateOptionsStr |
|
}; |
|
}; |
|
|
|
/* main function that transforms an input string in MediaWiki notation |
|
to xhtml */ |
|
|
|
function mw2xhtml(mw) |
|
{ |
|
var newWikiModel = new wikiModel(mw); |
|
return newWikiModel.wikiHtml; |
|
} |
|
|
|
|
|
|
|
/* parse the wiki source for headings |
|
they are transformed to HTML headers and saved in an array for |
|
later purposes. |
|
*/ |
|
function mwChaptersParser(mwlines,headers) |
|
{ |
|
var ret=""; |
|
var startTag=""; |
|
var prevStartTag=""; |
|
var lines = (typeof mwlines == 'string')? mwlines.replace(/\r/g,'').split(/\n/): mwlines; // lines mw |
|
var rownr = lines.length; |
|
|
|
var headerTag=""; |
|
for(var i=0;i<rownr;i++) |
|
{ |
|
startTag=lines[i].substr(0,1); |
|
switch (startTag) { |
|
case "=": |
|
headerTag=mw2header(lines[i],headers); |
|
ret+= headerTag+"\n"; |
|
break; |
|
default: |
|
ret+= lines[i]+"\n"; |
|
break; |
|
} |
|
} |
|
return ret; |
|
} |
|
/* parse the source text for templates */ |
|
function mwTemplatesParser(wikitext,templatesUsed,internalHyperlinks) |
|
{ |
|
var mwTemplatesParserOutput=""; |
|
var startTag=wikitext.indexOf("{{"); |
|
if(startTag!=-1) |
|
{ |
|
mwTemplatesParserOutput+=wikitext.substring(0,startTag); |
|
var endTag=wikitext.indexOf("}}",startTag+2); |
|
if(endTag ==-1) |
|
mwTemplatesParserOutput+=wikitext.substr(startTag+2); //invalid Template, ignored |
|
else |
|
{ |
|
var templateRendered=getTemplate(wikitext,startTag,endTag,templatesUsed,internalHyperlinks); |
|
mwTemplatesParserOutput+=templateRendered+wikitext.substr(endTag+2); |
|
//rekursion: |
|
mwTemplatesParserOutput=mwTemplatesParser(mwTemplatesParserOutput,templatesUsed,internalHyperlinks); |
|
} |
|
} |
|
else |
|
mwTemplatesParserOutput=wikitext; |
|
|
|
return mwTemplatesParserOutput; |
|
} |
|
/* parse the source text for multi-line sections, e.g. lists or tables */ |
|
function mwSectionsParser(mwlines,internalHyperlinks,templateOptions) |
|
{ |
|
var mwSectionsParserOutput=""; |
|
var cursor=0; |
|
var sectionStartLine=0; |
|
var sectionEndLine=-1; |
|
var iInSection=false; |
|
var lines = mwlines.replace(/\r/g,'').split(/\n/); |
|
var rownr = lines.length; |
|
for(var i=0;i<rownr;i++) |
|
{ |
|
|
|
//console.log("Line "+ i + ": "+lines[i]); |
|
var startTag=lines[i].substr(0,1); |
|
//alert(rownr+" " +startTag); |
|
switch (startTag) { |
|
case ("*"): |
|
case ("#"): |
|
if(iInSection==false) |
|
{ |
|
iInSection=true; |
|
sectionStartLine=i; |
|
sectionEndLine=getSectionEndLine(lines,sectionStartLine,startTag); |
|
} |
|
|
|
//alert(i+" "+sectionStartLine+"-"+sectionEndLine+":"+iInSection); |
|
if(i==sectionEndLine) |
|
{ |
|
mwSectionsParserOutput+=getList(lines,sectionStartLine,sectionEndLine,startTag); |
|
//sectionStartLine=0; |
|
iInSection=false; |
|
} |
|
|
|
break; |
|
case " ": |
|
if(iInSection==false) |
|
{ |
|
iInSection=true; |
|
sectionStartLine=i; |
|
sectionEndLine=getSectionEndLine(lines,sectionStartLine,startTag); |
|
} |
|
if(i==sectionEndLine) |
|
{ |
|
mwSectionsParserOutput+=getPreformatted(lines,sectionStartLine,sectionEndLine); |
|
//sectionStartLine=0; |
|
iInSection=false; |
|
} |
|
|
|
break; |
|
|
|
case "{": |
|
if(iInSection==false) |
|
{ |
|
iInSection=true; |
|
sectionStartLine=i; |
|
sectionEndLine=getSectionEndDelim(lines,sectionStartLine,lines.length,"}"); |
|
|
|
if(lines[i].substr(0,2)=="{|") |
|
{ |
|
mwSectionsParserOutput+=getTable(lines,sectionStartLine,sectionEndLine-1,internalHyperlinks,templateOptions); |
|
} |
|
if(lines[i].substr(0,2)=="{{") |
|
{ |
|
var dummy=getTemplate(lines,sectionStartLine,sectionEndLine,templateOptions,internalHyperlinks); |
|
mwSectionsParserOutput+=dummy; //getTemplate(lines,sectionStartLine,sectionEndLine,templateOptions); |
|
} |
|
|
|
i=sectionEndLine; |
|
iInSection=false; |
|
} |
|
|
|
break; |
|
case ";": |
|
var ddlistDelim=getCharposOutsideLinks(lines[i],":"); |
|
|
|
if(ddlistDelim ==-1) |
|
{ |
|
mwSectionsParserOutput+="<p><b>"+lines[i].substr(1)+"</b></p>"; |
|
} |
|
else |
|
{ |
|
mwSectionsParserOutput+="<dt>"+lines[i].substr(1,ddlistDelim)+"</dt>\n"; |
|
mwSectionsParserOutput+="<dd>"+lines[i].substr(ddlistDelim+1)+"</dd>\n"; |
|
} |
|
break; |
|
case "<": |
|
if(iInSection==false) |
|
{ |
|
iInSection=true; |
|
sectionStartLine=i; |
|
sectionEndLine=getSectionEndDelim(lines,sectionStartLine,lines.length,">"); |
|
|
|
if(lines[i].indexOf("<source")==0) |
|
{ |
|
sectionEndLine=getSectionEndDelim(lines,sectionStartLine,lines.length,"</source>"); |
|
mwSectionsParserOutput+=getSource(lines,sectionStartLine,sectionEndLine); |
|
} |
|
else if(lines[i].indexOf("<gallery")==0) |
|
{ |
|
sectionEndLine=getSectionEndDelim(lines,sectionStartLine,lines.length,"</gallery>"); |
|
mwSectionsParserOutput+=getGallery(lines,sectionStartLine,sectionEndLine,internalHyperlinks); |
|
} |
|
else if(lines[i].indexOf("<mwTemplate")==0) |
|
{ |
|
sectionEndLine=getSectionEndDelim(lines,sectionStartLine,lines.length,"</mwTemplate>"); |
|
for(var j=i;j<=sectionEndLine;j++) |
|
{ |
|
mwSectionsParserOutput+=lines[j]+"<br />"; |
|
} |
|
} |
|
|
|
else |
|
mwSectionsParserOutput+=lines[i]+"\n"; |
|
|
|
i=sectionEndLine; |
|
iInSection=false; |
|
} |
|
break; |
|
default: |
|
if(!iInSection) |
|
{ |
|
if(startTag !="<") |
|
mwSectionsParserOutput+="<p>"+lines[i]+"</p>\n"; |
|
else |
|
mwSectionsParserOutput+=lines[i]+"\n"; |
|
} |
|
break; |
|
} |
|
} |
|
return mwSectionsParserOutput; //mwSectionsParser(mwSectionsParserOutput); |
|
|
|
} |
|
/* identify the line where a section ends. In lists or preformatted sections |
|
it's the first occurence of a diferent character beginning a line*/ |
|
|
|
function getSectionEndLine(lines, sectionStartLine,sectionType) |
|
{ |
|
var rownr = lines.length; |
|
var endLineFound=false; |
|
var getSectionEndLine=sectionStartLine; |
|
for(var i=sectionStartLine+1;i<rownr;i++) |
|
{ |
|
if(!endLineFound) |
|
{ |
|
var startTag=lines[i].substr(0,1); |
|
if(startTag!=sectionType) |
|
{ |
|
getSectionEndLine=i-1; |
|
endLineFound=true; |
|
} |
|
} |
|
} |
|
return getSectionEndLine; |
|
|
|
} |
|
/* identify the final position where a section ends, if the section ends inline */ |
|
function getSectionEndDelim(lines, sectionStartLine,sectionEndLine,endTag) |
|
{ |
|
var rownr = lines.length; |
|
var endLineFound=false; |
|
var sectionEndDelim=-1; |
|
for(var i=sectionStartLine;i<sectionEndLine;i++) |
|
{ |
|
if(!endLineFound) |
|
{ |
|
if(lines[i].indexOf(endTag)>-1) |
|
{ |
|
sectionEndDelim=i; |
|
endLineFound=true; |
|
} |
|
} |
|
} |
|
return sectionEndDelim; |
|
|
|
} |
|
/* transform preformatted sections to <pre> Sections */ |
|
function getPreformatted(lines, sectionStartLine,sectionEndLine) |
|
{ |
|
var getPreformattedOutput="<pre>"; |
|
//alert(sectionStartLine+" "+sectionEndLine); |
|
for(var i=sectionStartLine;i<=sectionEndLine;i++) |
|
{ |
|
getPreformattedOutput+=lines[i].trim()+"\n"; |
|
|
|
} |
|
getPreformattedOutput+="</pre>\n"; |
|
return getPreformattedOutput; |
|
} |
|
|
|
/* load a template into a content string, and transform it. |
|
Result ist a simple dt/dd list with properties |
|
TODO: load the real wiki template |
|
|
|
|
|
*/ |
|
|
|
function getTemplate(wikitext, sectionStart,sectionEnd,templatesUsed,internalHyperlinks) |
|
{ |
|
var ret=""; |
|
var content=wikitext.substring(sectionStart+2,sectionEnd); |
|
var templateName=getTemplateName(content).trim(); |
|
var startParams=content.indexOf("|"); |
|
if(startParams==-1) |
|
startParams=content.indexOf(":"); //Wiki quellcode sample: |
|
// {{#navigation:searchStudyStudies}} |
|
//becomes: <mwTemplate><navigation><param><paramName></paramName><paramValue>searchStudyStudies</paramValue></param></navigation></mwTemplate> |
|
if(content.indexOf("[[")>-1 || startParams==-1) |
|
{ |
|
|
|
|
|
myNewTemplate=new templateUsed(0,templateName,content.substr(templateName.length+1),internalHyperlinks); |
|
templatesUsed.push(myNewTemplate); |
|
} |
|
else |
|
{ |
|
|
|
|
|
var templateParams = content.substr(startParams+1); |
|
myNewTemplate=new templateUsed(0,templateName,templateParams,internalHyperlinks); |
|
templatesUsed.push(myNewTemplate); |
|
} |
|
|
|
|
|
return myNewTemplate.renderTemplate(); |
|
} |
|
|
|
/* get the first Word, delimited by " " or "|"*/ |
|
function getTemplateName(str) |
|
{ |
|
var returnTemplateName=""; |
|
var templateNameEnd=-1; |
|
var i=0; |
|
var endFound=false; |
|
do{ |
|
var myChar=str.substr(i,1); |
|
if(myChar=="|" || myChar=="\n"|| myChar==":") |
|
{ |
|
endFound=true; |
|
templateNameEnd=i; |
|
} |
|
else |
|
i++; |
|
} |
|
while (endFound==false && i<=str.length); |
|
if(templateNameEnd==-1) |
|
templateNameEnd=str.length; |
|
if(str.substr(0,1)=="#") |
|
returnTemplateName=str.substr(1,templateNameEnd-1); |
|
else |
|
returnTemplateName=str.substr(0,templateNameEnd); |
|
return returnTemplateName; |
|
} |
|
|
|
function getTemplateClass(templateName) |
|
{ |
|
var ret=""; |
|
ret=searchReplace(templateName, " ","_").toLowerCase(); |
|
return ret; |
|
|
|
} |
|
|
|
/* render a template to a dt/dd list */ |
|
function renderTemplate_old(templateName,myNewOption) |
|
{ |
|
//simplified output of Templates: |
|
var ret=""; |
|
/*switch(templateName) { |
|
case "Hinweis": |
|
ret+="<div class=\"templateHinweis\"><table><tbody><tr style=\"vertical-align: top\">"; |
|
ret+="<td><strong>Hinweis</strong></td>"; |
|
for(var i=0;i < templateOptions.length;i++) |
|
{ |
|
if(templateOptions[i].value=="") |
|
ret+="<td>"+templateOptions[i].name+"</td>\n"; |
|
else |
|
ret+="<td>"+templateOptions[i].name+": "+templateOptions[i].value+"</td>\n"; |
|
} |
|
ret+="</tr></tbody></table></div>"; |
|
break; |
|
case "#navigation": |
|
switch(templateOptions){ |
|
case "standardReportsHisinone_administrate_bia": |
|
ret+="<i>Standardberichte</i> "; |
|
break; |
|
case "standardReportsHisinonebi": |
|
ret+="<i>Abfragen</i> "; |
|
default: |
|
ret+="Navigation:"+templateOptions+" "; |
|
break; |
|
} |
|
break; |
|
default: |
|
ret+="<dt>"+templateName+"</dt>\n"; |
|
for(var i=0;i < templateOptions.length;i++) |
|
{ |
|
if(templateOptions[i].value=="") |
|
ret+="<dd>"+templateOptions[i].name+"</dd>\n"; |
|
else |
|
ret+="<dd>"+templateOptions[i].name+": "+templateOptions[i].value+"</dd>\n"; |
|
} |
|
break; |
|
} |
|
*/ |
|
var ret="<template name=\""+templateName+"\">"; |
|
for(var i=0;i < myNewOption.length;i++) |
|
{ |
|
if(templateOptions[i].value=="") |
|
ret+="<templateOption><name>"+templateOptions[i].name+"</name></templateOption>\n"; |
|
else |
|
ret+="<templateOption><name>"+templateOptions[i].name+"</name><value>"+templateOptions[i].value+"</value></templateOption>\n"; |
|
} |
|
ret+="</template>"; |
|
|
|
return ret; |
|
} |
|
/* identify sections <source>... </source and transform it to <pre><code>... HTML */ |
|
function getSource(lines, sectionStartLine,sectionEndLine) |
|
{ |
|
var ret="<div class=\"control\"><textarea class=\"textarea\" readonly=\"readonly\">"; |
|
var startSource=lines[sectionStartLine].indexOf(">"); |
|
//wenn source Element in gleicher Zeile beendet wird: |
|
if(sectionStartLine==sectionEndLine) |
|
{ |
|
if(startSource >-1) |
|
{ |
|
var endSource=lines[sectionEndLine].indexOf("</source>"); |
|
if(endSource >-1) |
|
ret+=lines[sectionEndLine].substr(startSource,endSource); |
|
else |
|
ret+=lines[sectionEndLine].substr(startSource); |
|
} |
|
else |
|
ret+=lines[sectionEndLine]; |
|
} |
|
else |
|
{ |
|
//source über mehrere Zeilen: |
|
if(startSource >-1) |
|
ret+=lines[sectionStartLine].substr(startSource+1); |
|
else |
|
ret+=lines[sectionStartLine]; |
|
for(var i=sectionStartLine+1;i< sectionEndLine;i++) |
|
{ |
|
ret+=lines[i]+"\n"; |
|
} |
|
var endSource=lines[sectionEndLine].indexOf("</source>"); |
|
if(endSource >-1) |
|
ret+=lines[sectionEndLine].substr(0,endSource); |
|
else |
|
ret+=lines[sectionEndLine]; |
|
} |
|
return ret+"</textarea></div>"; |
|
} |
|
|
|
function getGallery(lines, sectionStartLine,sectionEndLine,internalHyperlinks) |
|
{ |
|
var ret="<mwTemplate>"; |
|
var startGallery=lines[sectionStartLine].indexOf(">"); |
|
ret+=lines[sectionStartLine].substr(0,startGallery+1); |
|
//wenn source Element in gleicher Zeile beendet wird: |
|
if(sectionStartLine==sectionEndLine) |
|
{ |
|
if(startGallery >-1) |
|
{ |
|
var endGallery=lines[sectionEndLine].indexOf("</gallery>"); |
|
if(endGallery >-1) |
|
ret+=getGalleryImage(lines[sectionEndLine].substr(startGallery,endGallery),internalHyperlinks); |
|
else |
|
ret+=getGalleryImage(lines[sectionEndLine].substr(startGallery),internalHyperlinks); |
|
} |
|
else |
|
ret+=lines[sectionEndLine]; |
|
} |
|
else |
|
{ |
|
//Gallery über mehrere Zeilen: |
|
if(startGallery >-1) |
|
ret+=getGalleryImage(lines[sectionStartLine].substr(startGallery+1),internalHyperlinks); |
|
else |
|
ret+=getGalleryImage(lines[sectionStartLine],internalHyperlinks); |
|
for(var i=sectionStartLine+1;i< sectionEndLine;i++) |
|
{ |
|
ret+=getGalleryImage(lines[i],internalHyperlinks)+"\n"; |
|
} |
|
var endGallery=lines[sectionEndLine].indexOf("</gallery>"); |
|
if(endGallery >-1) |
|
ret+=lines[sectionEndLine].substr(0,endGallery); |
|
else |
|
ret+=lines[sectionEndLine]; |
|
} |
|
return ret+"</gallery></mwTemplate>"; |
|
} |
|
function getGalleryImage(str,internalHyperlinks) |
|
{ |
|
var ret=""; |
|
if(str.trim() !="") |
|
{ |
|
ret+="<GalleryImage>"; |
|
|
|
var a_prefix="image"; |
|
var a_caption="Bild"; |
|
var a_href=""; |
|
var imgsrc=""; |
|
var remStr=""; |
|
if(str.indexOf("|") >-1) |
|
{ |
|
var imgparams = str.split(/\|/); |
|
for(var k=0;k < imgparams.length;k++) |
|
{ |
|
if(k==0) |
|
imgsrc=imgparams[k]; |
|
if(k==1) |
|
a_caption=imgparams[k]; |
|
if(k==2 && imgparams[k].indexOf("link=")>-1) |
|
a_href=imgparams[k].substr(5); |
|
} |
|
|
|
} |
|
else |
|
{ |
|
|
|
imgsrc=str; |
|
} |
|
ret+="<imgsrc>"+ imgsrc+"</imgsrc>"; |
|
var newLink = new internalHyperlink("",a_prefix, imgsrc, "", a_caption,internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
|
|
if(a_href!="") |
|
{ |
|
var newLink2 = new internalHyperlink("","", a_href, "", a_caption); |
|
internalHyperlinks.push(newLink2); |
|
ret+="<href>"+a_href+"</href>"; |
|
} |
|
else |
|
ret+="<href>"+imgsrc+"</href>"; |
|
|
|
|
|
|
|
|
|
|
|
if(a_caption.trim() !="") |
|
{ |
|
ret+="<subtitle>"; |
|
ret+=a_caption.trim(); |
|
ret+="</subtitle>"; |
|
} |
|
ret+="</GalleryImage>"; |
|
} |
|
return ret; |
|
} |
|
|
|
/*render a wiki table to HTML |
|
TODO: collapsed cells, cell formatting, table captions*/ |
|
function getTable(lines, sectionStartLine,sectionEndLine,internalHyperlinks,templatesUsed) |
|
{ |
|
var ret="<table"; |
|
var tdContent=""; |
|
var tdStyle=""; |
|
var attributes=lines[sectionStartLine].substr(2).trim(); |
|
if(attributes !="") |
|
ret+=" " + attributes; |
|
else |
|
ret+=" border=\"1\""; |
|
ret+=">"; |
|
for(var i=sectionStartLine+1;i<=sectionEndLine;i++) |
|
{ |
|
var srcRow=lines[i]; |
|
if(srcRow.substr(0,2)=="|+" ) |
|
{ |
|
//caption: |
|
ret+="<caption>"+srcRow.substr(2).trim()+"</caption>"; |
|
i++ |
|
srcRow=lines[i]; |
|
} |
|
// first |- is optional |
|
if(srcRow.trim()=="|-" ) |
|
{ |
|
i++; |
|
srcRow=lines[i]; |
|
} |
|
ret+="<tr>"; |
|
|
|
if(srcRow.substr(0,1)=="!" ) |
|
{ |
|
//table header |
|
var endTrRow=getSectionEndDelim(lines,i,sectionEndLine,"|-")-1; |
|
if(endTrRow==-2) |
|
endTrRow=sectionEndLine; |
|
var trContent=""; |
|
for(var k=i;k<= endTrRow;k++) |
|
{ |
|
var str=lines[k]; |
|
//duplicate ! if ! in first Col: |
|
if(str.substr(0,1)=="!") |
|
str="!"+str.trim(); |
|
trContent+=str.trim()+"\n"; |
|
} |
|
var cols = trContent.split(/!!/); |
|
var thContent=""; |
|
//first elem. of List is emtpy, ignored: |
|
for(var k=1;k < cols.length;k++) |
|
{ |
|
thContent=cols[k].trim(); |
|
ret+="<th>"+thContent.trim()+"</th>"; |
|
} |
|
i=endTrRow; |
|
ret+="</tr>\n"; |
|
|
|
} |
|
else |
|
{ |
|
//normal table row, no header: |
|
var endTrRow=getSectionEndDelim(lines,i,sectionEndLine,"|-")-1; |
|
if(endTrRow==-2) |
|
endTrRow=sectionEndLine; |
|
var trContent=""; |
|
var startTrRow=i; |
|
for(var k=i;k<= endTrRow;k++) |
|
{ |
|
var str=lines[k]; |
|
if(str.trim()=="") |
|
{ |
|
//ignore empty lines |
|
startTrRow++; |
|
} |
|
else |
|
{ |
|
str=str.replace(/\|\|/g,"<cellsep />"); |
|
if(str.substr(0,1)=="|") |
|
trContent+="<cellsep />"+str.substr(1).trim(); |
|
else |
|
trContent+="\n"+str.trim(); |
|
} |
|
} |
|
//Cols can be separated by | and || (inline): |
|
var cols = trContent.split("<cellsep />"); |
|
//first elem. of List is emtpy, ignored: |
|
for(var k=1;k < cols.length;k++) |
|
{ |
|
tdContent=cols[k].trim(); |
|
if(stringStartsWith(tdContent,"style=") || stringStartsWith(tdContent,"colspan=") ) |
|
{ |
|
tdStyle=tdContent; |
|
k++; |
|
} |
|
else |
|
tdStyle=""; |
|
|
|
ret+="<td "+ tdStyle+">"+getTableCell(cols[k],internalHyperlinks,templatesUsed)+"</td>"; |
|
} |
|
ret+="</tr>\n"; |
|
i=endTrRow; |
|
|
|
} |
|
} |
|
ret+="</table>\n"; |
|
|
|
return ret; |
|
} |
|
/* render a table cell. It can contain wiki sections like lists etc., |
|
therefore call the getSection Function before rendering the content. */ |
|
function getTableCell(str,internalHyperlinks,templatesUsed) |
|
{ |
|
var ret=""; |
|
var tdContent=str.trim(); |
|
//if(tdContent.substr(0,1)=="|") |
|
// tdContent=tdContent.substr(1).trim(); |
|
|
|
ret=mwSectionsParser(tdContent,internalHyperlinks,templatesUsed); |
|
return ret; |
|
} |
|
/* transform a wiki list to an array of listEntries |
|
rendering is quite complicated, because of recursive calls. |
|
*/ |
|
function getList(lines, sectionStartLine,sectionEndLine,listType) |
|
{ |
|
var getListOutput=""; |
|
var listEntries= []; |
|
listEntries=getListEntries(lines, sectionStartLine,sectionEndLine,listType,listEntries); |
|
getListOutput+=getListMarkup(listEntries,-1); |
|
return getListOutput; |
|
} |
|
|
|
/*Transform listEntries into HTML:*/ |
|
|
|
function getListMarkup(listEntries,parent) |
|
{ |
|
var listLength=listEntries.length; |
|
var getListMarkupOutput=""; |
|
var isFirstElem=true; |
|
var listType=""; |
|
var firstElemListType=""; |
|
var previousElemListType=""; |
|
/*if(parent==-1) |
|
{ |
|
listType=listEntries[0].getListType(); |
|
previousElemListType=listType; |
|
getListMarkupOutput+="<"+getListElement(listType)+">\n"; |
|
}*/ |
|
|
|
//init |
|
for(var i=0;i<listLength;i++) |
|
{ |
|
if(listEntries[i].parent==parent) |
|
{ |
|
listType=listEntries[i].getListType(); |
|
if(isFirstElem) |
|
{ |
|
firstElemListType=listType; |
|
previousElemListType=listType; |
|
getListMarkupOutput+="<"+getListElement(listType)+">\n"; |
|
isFirstElem=false; |
|
|
|
} |
|
if(previousElemListType != listType) |
|
{ |
|
getListMarkupOutput+="</"+getListElement(previousElemListType)+">\n"; |
|
previousElemListType=listType; |
|
getListMarkupOutput+="<"+getListElement(listType)+">\n"; |
|
|
|
} |
|
|
|
getListMarkupOutput+="<li>"+listEntries[i].content; |
|
getListMarkupOutput+=getListMarkup(listEntries,i); |
|
getListMarkupOutput+="</li>\n"; |
|
|
|
} |
|
|
|
} |
|
//Last Element only closed if content |
|
if(getListMarkupOutput != "") |
|
getListMarkupOutput+="</"+getListElement(listType)+">\n"; |
|
|
|
/*if(parent==-1) |
|
getListMarkupOutput+="</"+getListElement(listEntries[0].getListType())+">\n";*/ |
|
//else |
|
// getListMarkupOutput+="</"+getListElement(listEntries[parent].getListType())+">\n"; |
|
|
|
return getListMarkupOutput; |
|
} |
|
|
|
/*Convert list into an array :*/ |
|
function getListEntries(lines, sectionStartLine,sectionEndLine,listType,listEntries) |
|
{ |
|
var getListOutput=""; |
|
var counter=0; |
|
for(var i=sectionStartLine;i<=sectionEndLine;i++) |
|
{ |
|
counter++; |
|
listEntries.push(new listEntry(counter,lines[i],getListEntryContent(lines[i]),getListEntryLevel(lines[i]) )); |
|
|
|
} |
|
//parent ermitteln: |
|
|
|
for(var i=0;i<counter;i++) |
|
{ |
|
listEntries[i].parent=getListEntryParent(listEntries,i); |
|
} |
|
return listEntries; |
|
} |
|
|
|
/*get ListEntry content */ |
|
function getListEntryContent(content) |
|
{ |
|
var ret=content.trim(); |
|
var i=0; |
|
while(i<ret.length && (ret.substr(i,1)=="*" || ret.substr(i,1)=="#")) |
|
{ |
|
i++; |
|
} |
|
ret=ret.substr(i); |
|
return ret; |
|
} |
|
|
|
/*get ListEntry level */ |
|
function getListEntryLevel(content) |
|
{ |
|
|
|
var i=0; |
|
while(i<content.length && (content.substr(i,1)=="*" || content.substr(i,1)=="#")) |
|
{ |
|
i++; |
|
} |
|
return i; |
|
} |
|
|
|
/*Search List Array for first Element with listLevel smaller than self*/ |
|
function getListEntryParent(listEntries,i) |
|
{ |
|
//alert(listEntries.toString()); |
|
var parent=-1; |
|
var currLevel=0; |
|
var prevLevel=0; |
|
for(var k=i;k>=0;k--) |
|
{ |
|
if(k >= 0) |
|
{ |
|
currLevel=listEntries[i].level; |
|
prevLevel=listEntries[k].level; |
|
if(prevLevel < currLevel && parent==-1) |
|
parent=k; |
|
} |
|
} |
|
return parent; |
|
} |
|
function getListElement(listType) |
|
{ |
|
var listElement=""; |
|
switch (listType) { |
|
case "*": |
|
listElement="ul"; |
|
break; |
|
case "#": |
|
listElement="ol"; |
|
break; |
|
default: |
|
listElement=""; |
|
break; |
|
} |
|
return listElement; |
|
} |
|
/* obsolete: |
|
function mwLinesParser(mwlines) |
|
{ |
|
var mwLinesParserOutput=""; |
|
var startTag=""; |
|
var prevStartTag=""; |
|
var lines = (typeof mwlines == 'string')? mwlines.replace(/\r/g,'').split(/\n/): mwlines; // lines mw |
|
var rownr = lines.length; |
|
|
|
var headerTag=""; |
|
for(var i=0;i<rownr;i++) |
|
{ |
|
startTag=lines[i].substr(0,1); |
|
switch (startTag) { |
|
case "=": |
|
headerTag=mw2header(lines[i]); |
|
if(headerTag.startsWith("<h")) |
|
{ |
|
Headers[headersCount][3]= mwLinesParserOutput.length+1; //startPos |
|
Headers[headersCount][4]= mwLinesParserOutput.length+headerTag.length; //endPos |
|
} |
|
mwLinesParserOutput+= headerTag; |
|
break; |
|
default: |
|
mwLinesParserOutput+= mw2paragraph(lines[i]) |
|
break; |
|
} |
|
} |
|
return mwLinesParserOutput; |
|
}*/ |
|
|
|
/* identify wiki headers, count the "=" characters, |
|
and transform them to HTML headers <h1...hn>*/ |
|
function mw2header(str,headers) |
|
{ |
|
var ret=""; |
|
var startTag="="; |
|
var endPos=0; |
|
var level=1; |
|
var remStr=""; |
|
var content=""; |
|
var number=""; |
|
var parent=0; |
|
var parent_level=0; |
|
var previous_level=0; |
|
var headersCount=headers.length; |
|
str=str.trim(); |
|
startTag=str.substr(0,endTagPos(str,"=")); |
|
level=startTag.length; |
|
//endsWith starttag? |
|
if(str.substr(str.lenght-startTag.length).indexOf(startTag)>-1) |
|
{ |
|
remStr=str.substr(level); |
|
content=remStr.substr(0,remStr.length-level); |
|
/* TODO: |
|
number=getHeaderNumber(headersCount,headers); |
|
parent=... |
|
parent_level=... |
|
previous_level=... |
|
counterPerLevel[]++; |
|
*/ |
|
headersCount++; |
|
var newHeader = new header(headersCount,content, level, number); |
|
headers.push(newHeader); |
|
ret+=newHeader.renderHeader(); |
|
|
|
} |
|
else |
|
ret=str; |
|
return ret; |
|
} |
|
|
|
function getHeaderNumber(currentHeader,headers) |
|
{ |
|
|
|
} |
|
|
|
/* inline tags like '' are simply replaced by HTML notations. |
|
It gets more complicated with hyperlinks [[ */ |
|
function replaceInlineTags(str,inlineTags,internalHyperlinks,templatesUsed) |
|
{ |
|
var ret=str; |
|
for (var i=0;i<inlineTags.length;i++) |
|
{ |
|
ret=replaceInlineTag(ret,inlineTags[i].mwsyntax,inlineTags[i].htmlsyntax); |
|
} |
|
ret=parseHyperlinks(ret,internalHyperlinks); |
|
ret=parseInlineTemplates(ret,templatesUsed); |
|
|
|
ret=escapeHtmlEntities(ret); |
|
return ret; |
|
} |
|
|
|
/* parse single lines for xml notation |
|
if there is no space char or it contains " |
|
and it has a closing element, then it's treated as xml |
|
If not, it's treated as a html entity and transformed |
|
TODO: use regular expressions to identify XML an non-XML |
|
Wiki Src like <<Variable>> doesn't work yet |
|
|
|
*/ |
|
function parseXmlTags(str) |
|
{ |
|
var ret=""; |
|
var strlines = str.replace(/\r/g,'').split(/\n/); |
|
var rownr = strlines.length; |
|
for(var i=0;i<rownr;i++) |
|
{ |
|
var line=strlines[i]; |
|
var foundPos=line.indexOf("<"); |
|
var remStr=""; |
|
var offset=0; |
|
|
|
if(foundPos >-1) |
|
{ |
|
while(foundPos >-1) |
|
{ |
|
|
|
var endTag=line.indexOf(">"); |
|
if(endTag==-1) |
|
{ |
|
//no valid xml, therefore replace: |
|
ret+=line.substr(offset,foundPos)+"<"+line.substr(foundPos+1); |
|
line=line.substr(foundPos+1); |
|
} |
|
else |
|
{ |
|
// |
|
var prefix=line.substr(0,endTag); |
|
var suffix=line.substr(endTag+1); |
|
var xmltest=line.slice(foundPos,endTag+1); |
|
var isxml=false; |
|
//if there is a space character and no ", and no emtpy XML Tag, then it's no xml |
|
if(xmltest=="" || (xmltest.indexOf(" ")>-1 && xmltest.indexOf("\"")==-1 && !stringEndsWith(xmltest.trim()," />"))) |
|
{ |
|
isxml=false; |
|
//no valid xml, therefore replace: |
|
ret+=prefix+xmltest.replace(/</g,"<").replace(/>/g,">") ; //++suffix line.substr(foundPos+1); |
|
line=line.substr(endTag+1); |
|
} |
|
else |
|
{ |
|
//this is an xml Tag, therefore no replace: |
|
ret+=line.substr(0,endTag+1); |
|
line=line.substr(endTag+1); |
|
foundPos=line.indexOf("<"); |
|
if(foundPos==-1) |
|
ret+=suffix+"\n"; |
|
} |
|
|
|
} |
|
|
|
foundPos=line.indexOf("<"); |
|
} |
|
} |
|
else |
|
ret+=line; |
|
ret+="\n"; |
|
} |
|
return ret; |
|
} |
|
|
|
/* replace a single inline tag */ |
|
function replaceInlineTag(str,searchtag,replacetag) |
|
{ |
|
var ret=""; |
|
var foundPos=-1; |
|
var remStr=""; |
|
foundPos=str.indexOf(searchtag); |
|
if(foundPos>-1) |
|
{ |
|
ret+=str.substr(0,foundPos)+createStartTag(replacetag,"",""); |
|
remStr=str.substring(foundPos+searchtag.length); |
|
|
|
foundPos=remStr.indexOf(searchtag); |
|
if(foundPos>-1) |
|
{ |
|
ret+=remStr.substr(0,foundPos)+createEndTag(replacetag); |
|
ret+=remStr.substr(foundPos+searchtag.length); |
|
} |
|
else |
|
//EndTag existiert nicht: |
|
ret+=remStr; |
|
|
|
|
|
//Rekursion: |
|
ret=replaceInlineTag(ret,searchtag,replacetag); |
|
} |
|
else |
|
ret=str; |
|
return ret; |
|
} |
|
|
|
function parseInlineTemplates(str,templatesUsed) |
|
{ |
|
var ret=""; |
|
var templateName=""; |
|
var templateValues=""; //TODO |
|
var ret2=""; |
|
var templateStart=str.indexOf("{{"); |
|
if(templateStart !=-1) |
|
{ |
|
ret+=str.substr(0,templateStart); |
|
var templateEnd=str.indexOf("}}"); |
|
if(templateEnd==-1) |
|
{ |
|
templateEnd=str.length; |
|
ret2=""; |
|
} |
|
else |
|
ret2=str.substr(templateEnd+2); |
|
templateName=getTemplateName(str.substring(templateStart+2,templateEnd)); |
|
templateValues=str.substring(templateStart+3+templateName.length,templateEnd); |
|
templatesUsed.push(new templateOption(0,templateName,"",templateValues)); |
|
ret+= renderTemplate(templateName,templateOptions)+ret2; |
|
return parseInlineTemplates(ret,templatesUsed); |
|
} |
|
else |
|
return str; |
|
|
|
} |
|
/* hyperlinks are quite difficult to transform |
|
First internal links enclosed in [...] are identified. |
|
Then URLs starting with http... are directly transformed to external links |
|
Then external links enclosed in [[...]] are transformed. |
|
The order is important. |
|
*/ |
|
function parseHyperlinks(str,internalHyperlinks) |
|
{ |
|
var ret=""; |
|
ret=parseInternalLinks(str,internalHyperlinks); |
|
ret=parseEmbeddedHyperlink(ret); |
|
ret=parseExternalHyperlink(ret); |
|
//ret=parseHyperlink(ret,"[","]"," "); |
|
|
|
//ret=parseHyperlinks(ret); |
|
return ret; |
|
|
|
} |
|
|
|
/* URLs starting with http... are directly transformed to external links |
|
*/ |
|
function parseEmbeddedHyperlink(str) |
|
{ |
|
var ret=""; |
|
var a_href=""; |
|
var lastFound=0; |
|
var foundPos=str.indexOf("http",lastFound); |
|
if(foundPos==-1) |
|
return str; |
|
|
|
do{ |
|
ret+=str.substring(lastFound,foundPos); |
|
|
|
var previousChar=""; |
|
var nextChars=""; |
|
if(foundPos>0) |
|
previousChar=str.substr(foundPos-1,1); |
|
if(str.length >foundPos+7) |
|
nextChars=str.substr(foundPos+3,5); //should entail "//" as in "https://" |
|
|
|
if(previousChar !="[" && previousChar !="\"" && nextChars.indexOf("//")>-1 ) |
|
{ |
|
var href_end=getHrefEnd(str,foundPos); |
|
if(href_end==-1) |
|
{ |
|
//Link to EOL: |
|
a_href=str.substr(foundPos); |
|
href_end=str.length; |
|
} |
|
else |
|
{ |
|
a_href=str.substring(foundPos,href_end); |
|
lastFound=href_end; |
|
} |
|
ret+="<a href=\""+a_href+"\">"+a_href+"</a>"; |
|
|
|
|
|
} |
|
else |
|
{ //not a valid Hyperlink with http://... |
|
ret+=str.substr(foundPos,1); |
|
lastFound=foundPos+1; |
|
} |
|
foundPos=str.indexOf("http",lastFound+1); |
|
if(foundPos ==-1) |
|
ret+=str.substr(lastFound); |
|
} |
|
while (foundPos >-1); |
|
|
|
return ret; |
|
} |
|
|
|
/* External links enclosed in [...] are transformed. |
|
*/ |
|
function parseExternalHyperlink(str) |
|
{ |
|
var ret=""; |
|
var foundPos=str.indexOf("["); |
|
|
|
if(foundPos>-1) |
|
{ |
|
|
|
var remStr=""; |
|
var a_href=""; |
|
var a_name=""; |
|
ret+=str.substr(0,foundPos); |
|
remStr=str.substr(foundPos+1); |
|
var linkEnd=remStr.indexOf("]"); |
|
//delimiter for external Links can either be "|" or " ": |
|
if(linkEnd>-1) |
|
foundPos=remStr.substr(0,linkEnd).indexOf("|"); |
|
else |
|
foundPos=remStr.indexOf("|"); |
|
if(foundPos==-1) |
|
foundPos=remStr.indexOf(" "); |
|
if(foundPos>linkEnd || foundPos==-1) |
|
{ |
|
//this is no external Link: |
|
ret+= "__#bracketOpen#__"+remStr.substr(0,linkEnd)+"__#bracketClosed#__"+remStr.substr(linkEnd+1); |
|
} |
|
else |
|
{ |
|
if(foundPos>-1) |
|
{ |
|
a_href=remStr.substr(0,foundPos).trim(); |
|
remStr=remStr.substr(foundPos+1); |
|
foundPos=remStr.indexOf("]"); |
|
if(foundPos>-1) |
|
{ |
|
a_name=remStr.substr(0,foundPos).trim(); |
|
remStr=remStr.substr(foundPos+1); |
|
} |
|
else |
|
{ |
|
a_name=mwLink2Name(a_href); |
|
remStr=""; |
|
} |
|
} |
|
else |
|
{ |
|
//no caption |
|
foundPos=remStr.indexOf("]"); |
|
if(foundPos>-1) |
|
{ |
|
a_href=remStr.substr(0,foundPos).trim(); |
|
remStr=remStr.substr(foundPos+1); |
|
} |
|
a_name=mwLink2Name(a_href); |
|
|
|
} |
|
//normal link: |
|
ret+=createStartTag("a","href",a_href); |
|
ret+=a_name; |
|
ret+=createEndTag("a"); |
|
ret+=remStr; |
|
} |
|
ret=parseExternalHyperlink(ret); |
|
} |
|
else |
|
ret=str; |
|
return ret; |
|
|
|
} |
|
|
|
/* internal links enclosed in [...] are transformed |
|
and saved in an array for later purposes |
|
*/ |
|
function parseInternalLinks(str,internalHyperlinks) |
|
{ |
|
var ret=""; |
|
var foundPos=str.indexOf("[["); |
|
if(foundPos>-1) |
|
{ |
|
var remStr=""; |
|
var myLink=""; |
|
var a_href=""; |
|
var a_caption=""; |
|
var a_chapter=""; |
|
var a_prefix=""; |
|
ret+=str.substr(0,foundPos); |
|
remStr=str.substr(foundPos+2); |
|
foundPos=remStr.indexOf("]]"); |
|
if(foundPos != -1) |
|
{ |
|
myLink=remStr.substr(0,remStr.indexOf("]]")); |
|
remStr=remStr.substr(remStr.indexOf("]]")+2); |
|
} |
|
else |
|
{ |
|
//no endTag ->stop Link parsing |
|
return ret+"[["+ remStr; |
|
} |
|
ret+=parseInternalLink(myLink,internalHyperlinks)+remStr; |
|
|
|
ret=parseInternalLinks(ret,internalHyperlinks); |
|
} |
|
else |
|
ret=str; |
|
return ret; |
|
|
|
} |
|
|
|
/* recursive call of internal Links transformation */ |
|
function parseInternalLink(str,internalHyperlinks) |
|
{ |
|
var ret=""; |
|
var remStr=""; |
|
var a_href=""; |
|
var a_caption=""; |
|
var a_chapter=""; |
|
var a_prefix=""; |
|
|
|
if(str.indexOf(":") >-1) |
|
{ |
|
a_prefix=str.substr(0,str.indexOf(":")); |
|
remStr=str.substr(str.indexOf(":")+1).trim(); |
|
|
|
} |
|
else |
|
remStr=str; |
|
|
|
switch (a_prefix.toLowerCase()) { |
|
case "kategorie": |
|
a_caption=remStr; |
|
break; |
|
default: |
|
foundPos=remStr.indexOf("|"); |
|
if(foundPos>-1) |
|
{ |
|
//piped link |
|
a_href=remStr.substr(0,foundPos).trim(); |
|
a_caption=remStr.substr(foundPos+1).trim(); |
|
} |
|
else |
|
a_href=remStr; |
|
foundPos=a_href.indexOf("#"); |
|
if(foundPos>-1) |
|
{ |
|
a_chapter=a_href.substr(a_href.indexOf("#")+1); |
|
a_href=a_href.substr(0,a_href.indexOf("#")); |
|
} |
|
break; |
|
} |
|
|
|
//Keine Leerzeichen in Links: |
|
if(a_href.indexOf(" ")>0) |
|
a_href=a_href.replace(/ /g,"_"); |
|
//now we've got all attributes: |
|
var newLink = new internalHyperlink(str,a_prefix.toLowerCase(), a_href, a_chapter, a_caption,internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
ret=newLink.renderInternalHyperLink(); |
|
return ret; |
|
} |
|
|
|
|
|
/* images are special types of internal links |
|
rendering takes place here */ |
|
function renderImage(imgsrc,options,internalHyperlinks) |
|
{ |
|
//options are separated by pipe, the last option is the caption |
|
var ret=""; |
|
var remStr=""; |
|
var optionsArray = options.split("|"); |
|
var lastRow = optionsArray.length-1; |
|
var imgAttributes="border=\"0\" "; |
|
var imgCaption=imgsrc; |
|
var a_href=imgsrc; |
|
for(var i=0;i<=lastRow;i++) |
|
{ |
|
var option=optionsArray[i]; |
|
if(option== "border") |
|
{ |
|
imgAttributes += " class=\"thumbborder\" "; |
|
} |
|
if(i==lastRow && option.indexOf("=")==-1) |
|
imgCaption=option; |
|
if(option.indexOf("px") !=-1) |
|
{ |
|
var size1=""; |
|
var size2=""; |
|
var width=""; |
|
var height=""; |
|
var size=option.substr(0,option.indexOf("px")); |
|
if(size.indexOf("x")==0) |
|
{ |
|
//only height defined: |
|
height=size.substr(1); |
|
imgAttributes += " height=\""+height+"px\""; |
|
} |
|
if(size.indexOf("x")==-1) |
|
{ |
|
//only width defined: |
|
width=size.substr(0); |
|
imgAttributes += " width=\""+width+"px\""; |
|
|
|
} |
|
if(size.indexOf("x")>0) |
|
{ |
|
//width and height defined: |
|
var delim=size.indexOf("x"); |
|
width=size.substr(0,delim); |
|
imgAttributes += " width=\""+width+"px\""; |
|
height=size.substr(delim+1); |
|
imgAttributes += " height=\""+height+"px\""; |
|
} |
|
} |
|
if(option.indexOf("link=") !=-1) |
|
{ |
|
a_href=option.substr(option.indexOf("=")+1); |
|
var newLink = new internalHyperlink("","", a_href, "", a_href,internalHyperlinks); |
|
if(newLink) |
|
{ |
|
internalHyperlinks.push(newLink); |
|
} |
|
|
|
} |
|
|
|
} |
|
ret+="<a href=\""+a_href+"\" title=\""+imgCaption+"\"><img src=\""+imgsrc+"\" alt=\""+imgCaption+"\" "+imgAttributes+" /></a>"; |
|
return ret; |
|
} |
|
|
|
/* generic function that creates a HTML tag with attributes */ |
|
function createStartTag(elementname,attributename,attritutevalue) |
|
{ |
|
var ret=""; |
|
if(!elementname=="") |
|
{ |
|
ret+="<"+elementname; |
|
if(attributename.length>0) |
|
ret+=" "+attributename+"=\""+attritutevalue+"\""; |
|
ret+=">"; |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
/* generic function that creates a HTML end tag */ |
|
function createEndTag(elementname) |
|
{ |
|
var ret=""; |
|
if(!elementname==("")) |
|
ret+="</"+elementname+">"; |
|
return ret; |
|
} |
|
|
|
/* generic function that creates a HTML end tag plus linefeed*/ |
|
function endTagWithLineFeed(elementname) |
|
{ |
|
var ret=""; |
|
if(!elementname.equals("")) |
|
ret+=endTag(elementname)+"\n"; |
|
return ret; |
|
} |
|
|
|
/* generic function that searches/replaces a string. |
|
Regular expressions may be used. |
|
*/ |
|
|
|
function searchReplace(instr,remove, replace) |
|
{ |
|
var ret=""; |
|
ret=replaceRegexp(instr,remove,replace,false); |
|
return ret; |
|
} |
|
|
|
/* generic function that searches/replaces a string optionally using Regular expressions |
|
*/ |
|
|
|
function replaceRegexp(instr,remove, outstr,isRegExp) { |
|
var returnString=""; |
|
if (instr==null || remove==null || !(typeof instr == 'string') || remove.length==0) return instr; |
|
if(isRegExp) |
|
{ |
|
returnString=instr.replace(remove,outstr); |
|
} |
|
else |
|
{ |
|
var sb = ""; |
|
var oldIndex = 0; |
|
var newIndex = 0; |
|
var remLength = remove.length; |
|
while ( (newIndex = instr.indexOf(remove,oldIndex)) > -1) { |
|
//copy from last to new appearance |
|
sb+=(instr.substring(oldIndex,newIndex)); |
|
sb+=outstr; |
|
//set old index to end of last apperance. |
|
oldIndex = newIndex + remLength; |
|
} |
|
var inLength = instr.length; |
|
//add part after last appearance of string to remove |
|
if(oldIndex<inLength) sb+=(instr.substring(oldIndex,inLength)); |
|
returnString= sb; |
|
} |
|
return returnString; |
|
} |
|
|
|
/* transform HTML entities &, < and > */ |
|
function renderHtmlEntities(str) { |
|
return str.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">") |
|
} |
|
|
|
/* return the first non matching character position between two strings*/ |
|
function endTagPos(str, tag) |
|
{ |
|
var i=0; |
|
while(str.substr(i,1)==tag && i < str.length) |
|
{ |
|
i++; |
|
} |
|
return i |
|
} |
|
|
|
function replaceNoRegexp(str,search, replace) { |
|
|
|
return str.split(search).join(replace); |
|
} |
|
|
|
|
|
/* replace a string with space characters to underscore "_". |
|
This is used for internal links */ |
|
function mwName2Link(str) |
|
{ |
|
return replaceNoRegexp(str," ","_"); |
|
} |
|
|
|
/* replace a string with underscore character "_" to space character |
|
This is used for internal links */ |
|
function mwLink2Name(str) |
|
{ |
|
return replaceNoRegexp(str,"_"," "); |
|
} |
|
|
|
/* replace <nowiki> passages with placeholders */ |
|
function maskNowiki(str,nowikiPassages) |
|
{ |
|
var i=0; |
|
var sourceElem=""; |
|
|
|
if(str.indexOf("<nowiki>")!=-1) |
|
{ |
|
var nowikiStart=str.indexOf("<nowiki>"); |
|
while(nowikiStart !=-1) |
|
{ |
|
var nowikiEnd=str.indexOf("</nowiki>",nowikiStart); |
|
if(nowikiEnd!=-1) |
|
{ |
|
//nowikiEnd=nowikiEnd+nowikiStart; |
|
nowikiPassages.push(new nowikiPassage(i,str.substring(nowikiStart+8,nowikiEnd))); |
|
str=str.substr(0,nowikiStart)+"_nowiki_"+i+"_"+ str.substr(nowikiEnd+9); |
|
i++; |
|
nowikiStart=str.indexOf("<nowiki>",nowikiEnd+10); |
|
} |
|
else |
|
return str; //invalid nowiki use, ignored |
|
|
|
|
|
} |
|
} |
|
|
|
if(str.indexOf("<source lang")!=-1) |
|
{ |
|
sourceElem=""; |
|
//var strStartBeforeNowiki=0; |
|
var nowikiStart=str.indexOf("<source lang"); |
|
while(nowikiStart !=-1) |
|
{ |
|
var sourceStart=str.indexOf(">",nowikiStart); |
|
var nowikiEnd=str.indexOf("</source>",nowikiStart); |
|
if(nowikiEnd!=-1 && sourceStart!=-1) |
|
{ |
|
//nowikiEnd=nowikiEnd+nowikiStart; |
|
sourceElem="<div class=\"control\"><textarea class=\"textarea\" readonly=\"readonly\">" ; |
|
sourceElem+= str.substring(sourceStart+1,nowikiEnd); |
|
sourceElem+="</textarea></div>\n"; |
|
nowikiPassages.push(new nowikiPassage(i,sourceElem)); |
|
str=str.substr(0,nowikiStart)+"_nowiki_"+i+"_\n"+str.substr(nowikiEnd+10); |
|
i++; |
|
//strStartBeforeNowiki=nowikiEnd+11; |
|
nowikiStart=str.indexOf("<source lang",0); |
|
} |
|
else |
|
return str; //invalid source use, ignored |
|
|
|
|
|
} |
|
} |
|
else |
|
return str; |
|
return str; |
|
} |
|
|
|
/* replace a string containing placeholders with nowiki passages.*/ |
|
|
|
function reinsertNowiki(str,nowikiPassages) |
|
{ |
|
var ret=""; |
|
var nowikiPassagesCount=nowikiPassages.length; |
|
if(nowikiPassagesCount==0) |
|
return str; |
|
else |
|
{ |
|
for(var i=0;i<nowikiPassagesCount;i++) |
|
{ |
|
ret=str.replace("_nowiki_"+i+"_",nowikiPassages[i].content); |
|
str=ret; |
|
} |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
/* inline tags that are simply replaced are initialized |
|
by filling an array. This makes it easily extensible. */ |
|
|
|
function initInlineTags(inlineTags) |
|
{ |
|
inlineTags.push(new inlineTag("'''","b")); |
|
inlineTags.push(new inlineTag("''","i")); |
|
} |
|
|
|
/* replace common HTML entities except "<" and ">" */ |
|
function escapeHtmlEntities(str) |
|
{ |
|
/*str=str.replace(/&/g,"&"); |
|
str=str.replace(/ü/g,"ü"); |
|
str=str.replace(/Ü/g,"Ü"); |
|
str=str.replace(/ö/g,"ö"); |
|
str=str.replace(/Ö/g,"Ö"); |
|
str=str.replace(/ä/g,"ä"); |
|
str=str.replace(/Ä/g,"Ä"); |
|
str=str.replace(/ß/g,"ß");*/ |
|
//empty <br>-Elements become well-formed XML: |
|
str=str.replace(/\<br\>/g,"<br></br>"); |
|
//reserved delims: |
|
str=str.replace(/__#bracketOpen#__/g,"["); |
|
str=str.replace(/__#bracketClosed#__/g,"]"); |
|
|
|
return str; |
|
} |
|
|
|
/* remove all comments from the string */ |
|
function removeComments(str) |
|
{ |
|
if(str.indexOf("<!--") >-1 && str.indexOf("-->")>-1) |
|
{ |
|
var srcstr=str; |
|
while(srcstr.indexOf("<!--") >-1) |
|
{ |
|
var startPos=srcstr.indexOf("<!--"); |
|
var endPos=srcstr.indexOf("-->",startPos); |
|
srcstr=srcstr.substr(0,startPos)+srcstr.substr(endPos+3); |
|
} |
|
return srcstr; |
|
} |
|
else |
|
return str; |
|
} |
|
|
|
function getHrefEnd(str,foundPos) |
|
{ |
|
var hrefEnd=-1; |
|
var i=foundPos; |
|
var endFound=false; |
|
do{ |
|
var myChar=str.substr(i,1); |
|
if(myChar=="<" || myChar==" "|| myChar=="\n") |
|
{ |
|
endFound=true; |
|
hrefEnd=i; |
|
} |
|
else |
|
i++; |
|
} |
|
while (endFound==false); |
|
return hrefEnd; |
|
} |
|
|
|
|
|
|
|
/* find searchstr in str, but not inside [[...]] |
|
*/ |
|
function getCharposOutsideLinks(str,searchstr) |
|
{ |
|
var charpos=-1; |
|
var openLink=str.indexOf("[["); |
|
var closeLink=str.indexOf("]]"); |
|
if(openLink>-1 && closeLink>openLink) |
|
{ |
|
charpos=str.substr(0,openLink).indexOf(searchstr); |
|
if(charpos==-1) |
|
charpos=str.indexOf(searchstr,closeLink); |
|
} |
|
else |
|
charpos=str.indexOf(searchstr); |
|
return charpos; |
|
|
|
} |
|
|
|
function stringStartsWith(str,lookfor) |
|
{ |
|
var itDoes=false; |
|
if(str.substring(0,lookfor.length)==lookfor) |
|
itDoes=true; |
|
return itDoes; |
|
} |
|
|
|
function stringEndsWith(str, lookfor) { |
|
return str.indexOf(lookfor, str.length - lookfor.length) !== -1; |
|
} |
|
|
|
function wikiLink2Xml(str,internalHyperlinks) |
|
{ |
|
var ret=""; |
|
var href="Link"; |
|
var linkTypeExternal=true; |
|
var linkTagLength=1; |
|
if(stringStartsWith(str,"[[")) |
|
{ |
|
linkTypeExternal=false; |
|
linkTagLength=2; |
|
} |
|
var linkContentLeft=str.substr(linkTagLength); |
|
var linkContentRight=linkContentLeft.substring(0,linkContentLeft.length-linkTagLength); |
|
var firstBlankPos=linkContentRight.indexOf(" "); |
|
ret+="<href>"; |
|
if(firstBlankPos >0) |
|
{ |
|
href=linkContentRight.substring(0,firstBlankPos); |
|
ret+=href; |
|
|
|
} |
|
else |
|
ret+=linkContentRight; |
|
ret+="</href>"; |
|
|
|
var linkName=""; |
|
ret+="<name>"; |
|
if(firstBlankPos>1) |
|
{ |
|
linkName=linkContentRight.substr(firstBlankPos); |
|
ret+=linkName.trim(); |
|
} |
|
ret+="</name>"; |
|
if(!linkTypeExternal) |
|
{ |
|
//interne Links verarbeiten |
|
var newLink = new internalHyperlink("","", href.trim(), "", linkName,internalHyperlinks); |
|
internalHyperlinks.push(newLink); |
|
} |
|
|
|
|
|
return ret; |
|
}
|
|
|