File names start with 4 equal signs, then an optional space. Optionally, they can have equal signs at the end of the line. You escape a line by adding an extra equals to all lines that begin with 4 equals signs. An empty filename is used for comments
testMultidoc()
function writeMultidoc(x){
let s = ""
if("" in x){
s += escapeEquals(x[""])
}
for(let k in x){
if(k == "") continue
if(s.length) s += "\n"
s += `==== ${k} ====\n`
s += escapeEquals(x[k])
}
return s
function escapeEquals(s){
let lines = s.split("\n")
for(let i=0; i<lines.length; ++i){
if(lines[i].indexOf("====") == 0){
lines[i] = "=" + lines[i]
}
}
return lines.join("\n")
}
}
function readMultidoc(s){
let docs = {}
let lines = s.split("\n")
let filename = ""
docs[""] = ""
for(let i=0; i<lines.length; ++i){
let line = lines[i]
if(line.indexOf("====") == 0){
if(line.indexOf("=====") == 0){ // escaped line
line = line.substring(1)
}else{
while(line.length > 4 && line[line.length-1] == "="){
line = line.substring(0, line.length - 1)
}
line = line.substring(4).trim()
filename = line
console.log('newfile', filename)
if(!docs.hasOwnProperty(filename)){
docs[filename] = ""
}
continue
}
}
if(docs[filename].length > 0){
docs[filename] += "\n"
}
docs[filename] += line
}
return docs
}
function trimlines(parts, args){ // tagged template literal
let tabindent = 4
let s = ""
for(let i=0; i<parts.length; ++i){
s += parts[i]
if(i < args.length) s += args[i]
}
let lines = s.split('\n')
let minindent = 1000*1000
for(let i=0; i<lines.length; ++i){
let line = lines[i]
let indent = 0
for(let j=0; j<line.length; ++j){
let c = line[j]
if(c == '\t'){ indent += tabindent }
else if(c == ' '){ ++indent }
else{
minindent = Math.min(indent, minindent)
break
}
}
}
let result = ""
for(let i=0; i<lines.length; ++i){
let line = lines[i]
if(result.length > 0) result += "\n"
result += line.substring(minindent)
}
return result
}
function testMultidoc(){
let src = trimlines`
Here is a demo of a multifile archive
==== hello.html ====
<${''}!doctype html>
<${''}html>
<${''}head>
<${''}title> Hello Demo <${''}/title>
<${''}meta name="viewport" content= "width=device-width, initial-scale=1.0">
<${''}link rel="stylesheet" href="css/style.css'>
<${''}/head>
<${''}body>
<${''}h1> Hello <${''}/h1>
<${''}h3> Demo App <${''}/h3>
<${''}script src="js/main.js"><${''}/script>
<${''}/body>
<${''}/html>
==== js/main.js ====
console.log("Hello")
==== css/style.css ====
body{
font-family: sans-serif;
}
====
More comments go here in an empty file name
Five equals signs escapes an equals sign line
===== This is escaped so it will stay in the content.
`
console.info('src', src.split('\n').join('||'))
let doc = readMultidoc(src)
console.log('test multidoc', JSON.stringify(doc))
console.info('test multidoc', doc)
console.info('write', writeMultidoc(doc))
}