diff --git a/ui/builder.html b/ui/builder.html
index b3f3275..5d66cdd 100644
--- a/ui/builder.html
+++ b/ui/builder.html
@@ -105,8 +105,8 @@ input,textarea,button,select{font-family:inherit}
.npl-inp:disabled{background:var(--surface-alt);color:var(--muted)}
.opt-hint{font-size:10px;color:var(--muted)}
-/* ── 구분자 설정 바 ───────────────────────── */
-.sep-bar{background:var(--surface-alt);border:1px solid var(--border);border-radius:5px;padding:5px 8px;display:flex;flex-direction:column;gap:4px}
+/* ── 구분자/이름줄바꿈 설정 (노드 설정 내부) ─ */
+.struct-sep{display:flex;flex-direction:column;gap:4px;padding-bottom:6px;margin-bottom:6px;border-bottom:1px dashed var(--border)}
.sep-bar-row{display:flex;align-items:center;gap:5px}
.sep-bar-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);width:52px;flex-shrink:0}
@@ -283,7 +283,7 @@ function uid(){ return Math.random().toString(36).slice(2,9) }
function mkNode(mark='', content=''){
return { id:uid(), mark, content, hidden:false, values:[], settings:{},
- nextSep:'blank', childSep:'blank' };
+ nextSep:'blank', childSep:'blank', nameNewline:true };
}
function mkListVal(names='', category=''){
return { id:uid(), type:'list', names, sep:' ', namesPerLine:0, category };
@@ -332,8 +332,9 @@ function load(){
}
function normalizeNode(n){
- if(n.nextSep===undefined) n.nextSep='blank';
- if(n.childSep===undefined) n.childSep='blank';
+ if(n.nextSep===undefined) n.nextSep='blank';
+ if(n.childSep===undefined) n.childSep='blank';
+ if(n.nameNewline===undefined) n.nameNewline=true;
for(const v of n.values||[]) if(v.type==='node') normalizeNode(v.node);
}
function normalizeState(s){
@@ -523,7 +524,6 @@ function renderNode(node, nested){
${!node.hidden?`
- ${renderSepBar(node)}
@@ -547,12 +547,12 @@ function renderNode(node, nested){
onchange="addSetting('${node.id}',this.value);this.selectedIndex=0">
${setOpts}
- `
- :`모두 설정됨`}
+ `:''}
+
+
+ ${renderStructSettings(node)}
+ ${settingItems}
- ${settingItems
- ?`
${settingItems}
`
- :'
기본값 사용
'}
`:''}
`;
@@ -653,16 +653,28 @@ function renderSepChips(nid, field, current){
style="width:56px">`;
}
-function renderSepBar(node){
+function setNameNL(nid, val){
+ const n=nodeMap[nid]; if(!n) return;
+ n.nameNewline=val; refresh();
+}
+
+function renderStructSettings(node){
+ const nid=node.id;
+ const nl=node.nameNewline??true;
return `
-
+
다음 노드
- ${renderSepChips(node.id,'nextSep', node.nextSep??'blank')}
+ ${renderSepChips(nid,'nextSep', node.nextSep??'blank')}
하위 노드
- ${renderSepChips(node.id,'childSep', node.childSep??'blank')}
+ ${renderSepChips(nid,'childSep', node.childSep??'blank')}
+
+
+ 이름 뒤
+ 줄바꿈
+ 없음
`;
}
@@ -724,8 +736,10 @@ function toText(){
// 노드 하나를 문자열로 렌더링
function rNode(node){
let t=`${node.mark??''}${node.content||''}`;
- let pendingSep=null; // 다음 child node 앞에 붙일 구분자
+ const nl=(node.nameNewline??true)?'\n':''; // 이름 뒤 줄바꿈 여부
+ let pendingSep=null;
let prevWasList=false;
+ let firstContent=true; // 첫 번째 list/scalar 여부 (nameNewline 적용 대상)
for(let i=0;i
(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;
+ const pre2=firstContent?nl:'\n'; // 첫 list만 nameNewline 적용
+ t+=pre2+lt+'\n';
+ prevWasList=true; pendingSep=null; firstContent=false;
} else if(v.type==='node'){
- // 이 child node 앞에 붙일 구분자 결정
if(!prevWasList){
t+=(pendingSep!==null) ? pendingSep : ss(node.childSep??'blank');
}
t+=rNode(v.node);
- prevWasList=false;
- // 다음 형제가 노드면 nextSep을 예약
+ prevWasList=false; firstContent=false;
pendingSep=(nextV&&nextV.type==='node') ? ss(v.node.nextSep??'blank') : null;
} else {
- if(v.data) t+='\n'+String(v.data);
- prevWasList=false;
- pendingSep=null;
+ if(v.data){
+ const pre2=firstContent?nl:'\n';
+ t+=pre2+String(v.data);
+ firstContent=false;
+ }
+ prevWasList=false; pendingSep=null;
}
}
return t;