diff --git a/ui/builder.html b/ui/builder.html index ed8f1cb..b3f3275 100644 --- a/ui/builder.html +++ b/ui/builder.html @@ -230,7 +230,6 @@ input,textarea,button,select{font-family:inherit} // 상수 // ════════════════════════════════════════════════════════ const VALUE_TYPES = [ - {v:'list', lbl:'리스트 (List)'}, {v:'node', lbl:'노드 (Node)'}, {v:'string', lbl:'문자열 (String)'}, {v:'integer', lbl:'정수 (Integer)'}, @@ -631,8 +630,9 @@ function renderValue(nid, val){ } const SEP_CFG = [ - {v:'none', lbl:'없음'}, - {v:'blank', lbl:'빈 줄'}, + {v:'none', lbl:'없음'}, + {v:'newline', lbl:'줄바꿈'}, + {v:'blank', lbl:'빈 줄'}, ]; function setSep(nid, field, val){ @@ -712,49 +712,63 @@ function renderSetting(nid, key, val){ function parseNames(raw){ return (raw??'').trim().split(/[\s,\n]+/).filter(Boolean) } function toText(){ - const lines=[]; - const title=S.title.trim(); - if(title){ lines.push(`${S.titleMark}${title}`); lines.push(''); } - - function applySep(sep){ + // 구분자 값 → 실제 문자열 + function ss(sep){ const s=sep??'blank'; - if(s==='none') return; - if(s==='blank'){ lines.push(''); return; } - for(const l of String(s).replace(/\\n/g,'\n').split('\n')) lines.push(l); + if(s==='none') return ''; + if(s==='newline') return '\n'; + if(s==='blank') return '\n\n'; + return String(s); // 직접 입력값 (예: '/', ', ') } + // 노드 하나를 문자열로 렌더링 function rNode(node){ - lines.push(`${node.mark??''}${node.content||''}`); + let t=`${node.mark??''}${node.content||''}`; + let pendingSep=null; // 다음 child node 앞에 붙일 구분자 let prevWasList=false; + for(let i=0;ilines.push((j===0?pre:'')+n)); - else if(npl>0) for(let j=0;j(j===0?pre:'')+n).join('\n'); + else if(npl>0) lt=Array.from({length:Math.ceil(ns.length/npl)},(_,j)=>(j===0?pre:'')+ns.slice(j*npl,(j+1)*npl).join(lsep)).join('\n'); + else lt=pre+ns.join(lsep); + t+='\n'+lt+'\n'; // list는 항상 줄 단위 prevWasList=true; + pendingSep=null; + } else if(v.type==='node'){ - if(!prevWasList) applySep(node.childSep); // list가 없을 때만 childSep 적용 - rNode(v.node); - if(nextV&&nextV.type==='node') applySep(v.node.nextSep); // 다음도 노드면 nextSep + // 이 child node 앞에 붙일 구분자 결정 + if(!prevWasList){ + t+=(pendingSep!==null) ? pendingSep : ss(node.childSep??'blank'); + } + t+=rNode(v.node); prevWasList=false; + // 다음 형제가 노드면 nextSep을 예약 + pendingSep=(nextV&&nextV.type==='node') ? ss(v.node.nextSep??'blank') : null; + } else { - if(v.data) lines.push(String(v.data)); + if(v.data) t+='\n'+String(v.data); prevWasList=false; + pendingSep=null; } } + return t; } + const title=S.title.trim(); + let out=title?`${S.titleMark}${title}\n\n`:''; for(let i=0;i