node-riner 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.ts +60 -11
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -28,6 +28,8 @@ export default class Ride {
28
28
  * - 文字列: `{...}` を評価して置換(既存挙動を維持)
29
29
  * - 配列: 各要素を <item> でラップして連結
30
30
  * - オブジェクト: 各キーをタグ名として再帰的にレンダリング
31
+ *
32
+ * 注意: '@_' で始まるキー(属性)はここではタグ化しない。
31
33
  */
32
34
  private renderValue(value: any): string {
33
35
  // null / undefined
@@ -47,7 +49,6 @@ export default class Ride {
47
49
  const out = execSync("node runs.js").toString()
48
50
  newValue = newValue.replace(m, out)
49
51
  } catch (e) {
50
- // 評価失敗時は空文字に置換(または元の {..} のままにする選択も可能)
51
52
  newValue = newValue.replace(m, '')
52
53
  }
53
54
  })
@@ -61,21 +62,69 @@ export default class Ride {
61
62
  return value.map((item: any) => `<item>${this.renderValue(item)}</item>`).join('')
62
63
  }
63
64
 
64
- // オブジェクト: キーごとにタグ化して再帰処理
65
+ // オブジェクト: 属性(@_...) を無視して子要素だけタグ化する
65
66
  if (typeof value === 'object') {
66
- return Object.keys(value).map(key => {
67
- // fast-xml-parser の場合、テキストノードはキーが '#text' '_text' の可能性があるので考慮
68
- if (key === '#text' || key === '_text') {
69
- return this.renderValue(value[key])
70
- }
71
- return `<${key}>${this.renderValue(value[key])}</${key}>`
72
- }).join('')
67
+ return Object.keys(value)
68
+ .filter(key => !key.startsWith('@_')) // 属性はここで無視
69
+ .map(key => {
70
+ // テキストノードは直接中身を出力
71
+ if (key === '#text' || key === '_text') {
72
+ return this.renderValue(value[key])
73
+ }
74
+ return `<${key}>${this.renderValue(value[key])}</${key}>`
75
+ }).join('')
73
76
  }
74
77
 
75
78
  // その他(数値や真偽値など)はそのまま文字列化
76
79
  return String(value)
77
80
  }
78
81
 
82
+ /**
83
+ * タグ名とその値から、属性を正しく反映した HTML を生成する
84
+ * - value が配列ならタグを複数分生成
85
+ * - value がオブジェクトで属性(@_...)を持つ場合、属性を開タグに組み込む
86
+ */
87
+ private renderContentTag(tag: string, value: any): string {
88
+ // 配列の場合は各要素で同じタグを生成
89
+ if (Array.isArray(value)) {
90
+ return value.map((item: any) => this.renderContentTag(tag, item)).join('')
91
+ }
92
+
93
+ // プリミティブ(文字列等)の場合はタグでラップ
94
+ if (value === null || value === undefined || typeof value !== 'object') {
95
+ return `<${tag}>${this.renderValue(value)}</${tag}>`
96
+ }
97
+
98
+ // オブジェクトの場合、属性を抽出
99
+ const entries = Object.entries(value)
100
+ const attrEntries = entries.filter(([k]) => k.startsWith('@_'))
101
+ const childEntries = entries.filter(([k]) => !k.startsWith('@_'))
102
+
103
+ // 属性文字列を組み立て(@_ を取り除く)
104
+ const attrs = attrEntries.map(([k, v]) => {
105
+ const name = k.replace(/^@_/, '')
106
+ const safe = String(v).replace(/"/g, '&quot;')
107
+ return ` ${name}="${safe}"`
108
+ }).join('')
109
+
110
+ // 子要素・テキストを組み立て
111
+ let inner = ''
112
+ // 優先してテキストノードを出す
113
+ if (value['#text'] !== undefined) {
114
+ inner += this.renderValue(value['#text'])
115
+ } else if (value['_text'] !== undefined) {
116
+ inner += this.renderValue(value['_text'])
117
+ }
118
+
119
+ // その他の子要素をレンダリング
120
+ childEntries.forEach(([k, v]) => {
121
+ if (k === '#text' || k === '_text') return
122
+ inner += `<${k}>${this.renderValue(v)}</${k}>`
123
+ })
124
+
125
+ return `<${tag}${attrs}>${inner}</${tag}>`
126
+ }
127
+
79
128
  /**
80
129
  * XML を解析して pages に HTML を格納
81
130
  */
@@ -104,8 +153,8 @@ export default class Ride {
104
153
  // 各タグを再帰的にレンダリングして結合
105
154
  const generatedhtml = Object.keys(content).map(tag => {
106
155
  const value = content[tag]
107
- const inner = this.renderValue(value)
108
- return `<${tag}>${inner}</${tag}>`
156
+ // 属性付きタグなどを正しく扱う helper を使う
157
+ return this.renderContentTag(tag, value)
109
158
  }).join('')
110
159
 
111
160
  // ページを格納(タイトルを付与)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-riner",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",