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