QIDNLF commited on
Commit
036a152
ยท
verified ยท
1 Parent(s): 4632401

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -28
app.py CHANGED
@@ -112,35 +112,51 @@ def reset_comp():
112
  return None, None, None
113
 
114
  # --------------------------
115
- # ๐Ÿ”ฅ diff ํ•จ์ˆ˜ (ํ•ต์‹ฌ)
116
  # --------------------------
117
- def highlight_comp_only(base_text, comp_text):
118
  if pd.isna(base_text): base_text = ""
119
  if pd.isna(comp_text): comp_text = ""
120
 
121
  base_words = str(base_text).split()
122
  comp_words = str(comp_text).split()
123
 
124
- d = difflib.ndiff(base_words, comp_words)
125
 
126
- result = []
 
127
 
128
- for diff in d:
129
- code = diff[0]
130
- word = diff[2:]
 
131
 
132
  if code == ' ':
133
- result.append(word)
 
134
 
135
- elif code == '+': # ์ถ”๊ฐ€
136
- result.append(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  f"<span style='color:#2ecc71; font-weight:600'>{word}</span>"
138
  )
139
 
140
- elif code == '-':
141
- continue
142
 
143
- return " ".join(result)
144
 
145
  # --------------------------
146
  # ๋ฐ์ดํ„ฐ ์กฐํšŒ
@@ -164,17 +180,10 @@ def display_data(standard, version, selection):
164
  cols = cols_info['name'].tolist()
165
  lower_cols = [c.lower().strip() for c in cols]
166
 
167
- real_section = None
168
- real_desc = None
169
- real_ch = None
170
- real_cat = None
171
 
172
  for c, lc in zip(cols, lower_cols):
173
- if lc == "section":
174
- real_section = c
175
- elif lc == "description":
176
- real_desc = c
177
- elif lc == "chapter":
178
  real_ch = c
179
  elif lc == "category":
180
  real_cat = c
@@ -241,14 +250,14 @@ def unified_search(bs, bv, bc, cs, cv, cc):
241
  "description_y": f"Description_{cv}"
242
  })
243
 
244
- # ๐Ÿ”ฅ diff ์ ์šฉ (comp์—๋งŒ)
245
  base_col = f"Description_{bv}"
246
  comp_col = f"Description_{cv}"
247
 
 
248
  for idx, row in merged.iterrows():
249
- base_text = row.get(base_col, "")
250
- comp_text = row.get(comp_col, "")
251
- merged.at[idx, comp_col] = highlight_comp_only(base_text, comp_text)
252
 
253
  merged = merged.sort_values(
254
  by="section",
@@ -281,8 +290,7 @@ with gr.Blocks() as demo:
281
  comp_category = gr.Dropdown(label="Category")
282
  comp_reset_btn = gr.Button("โ†บ ์ดˆ๊ธฐํ™”")
283
 
284
- with gr.Row():
285
- search_btn = gr.Button("๐Ÿ” ์กฐํšŒ")
286
 
287
  gr.Markdown("### ๐Ÿ“Š ๋น„๊ต ๊ฒฐ๊ณผ")
288
 
@@ -320,6 +328,26 @@ if __name__ == "__main__":
320
  font-family: 'Pretendard', sans-serif;
321
  }
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  thead th {
324
  position: sticky !important;
325
  top: 0;
@@ -328,15 +356,18 @@ thead th {
328
  border-bottom: 2px solid #ddd;
329
  }
330
 
 
331
  .dataframe {
332
  max-height: 700px;
333
  overflow-y: auto;
334
  }
335
 
 
336
  td {
337
  white-space: normal !important;
338
  word-break: break-word !important;
339
  line-height: 1.6;
 
340
  }
341
  """
342
  )
 
112
  return None, None, None
113
 
114
  # --------------------------
115
+ # ๐Ÿ”ฅ diff ํ•จ์ˆ˜
116
  # --------------------------
117
+ def highlight_diff(base_text, comp_text):
118
  if pd.isna(base_text): base_text = ""
119
  if pd.isna(comp_text): comp_text = ""
120
 
121
  base_words = str(base_text).split()
122
  comp_words = str(comp_text).split()
123
 
124
+ d = list(difflib.ndiff(base_words, comp_words))
125
 
126
+ base_result = []
127
+ comp_result = []
128
 
129
+ i = 0
130
+ while i < len(d):
131
+ code = d[i][0]
132
+ word = d[i][2:]
133
 
134
  if code == ' ':
135
+ base_result.append(word)
136
+ comp_result.append(word)
137
 
138
+ elif code == '-' and i + 1 < len(d) and d[i + 1][0] == '+':
139
+ old_word = word
140
+ new_word = d[i + 1][2:]
141
+
142
+ base_result.append(f"<span style='color:#ff4d4f; font-weight:600'>{old_word}</span>")
143
+ comp_result.append(f"<span style='color:#ff4d4f; font-weight:600'>{new_word}</span>")
144
+
145
+ i += 1
146
+
147
+ elif code == '-':
148
+ base_result.append(
149
+ f"<span style='color:#ff4d4f; text-decoration:line-through'>{word}</span>"
150
+ )
151
+
152
+ elif code == '+':
153
+ comp_result.append(
154
  f"<span style='color:#2ecc71; font-weight:600'>{word}</span>"
155
  )
156
 
157
+ i += 1
 
158
 
159
+ return " ".join(base_result), " ".join(comp_result)
160
 
161
  # --------------------------
162
  # ๋ฐ์ดํ„ฐ ์กฐํšŒ
 
180
  cols = cols_info['name'].tolist()
181
  lower_cols = [c.lower().strip() for c in cols]
182
 
183
+ real_ch, real_cat = None, None
 
 
 
184
 
185
  for c, lc in zip(cols, lower_cols):
186
+ if lc == "chapter":
 
 
 
 
187
  real_ch = c
188
  elif lc == "category":
189
  real_cat = c
 
250
  "description_y": f"Description_{cv}"
251
  })
252
 
 
253
  base_col = f"Description_{bv}"
254
  comp_col = f"Description_{cv}"
255
 
256
+ # ๐Ÿ”ฅ diff ์ ์šฉ
257
  for idx, row in merged.iterrows():
258
+ b, c = highlight_diff(row.get(base_col, ""), row.get(comp_col, ""))
259
+ merged.at[idx, base_col] = b
260
+ merged.at[idx, comp_col] = c
261
 
262
  merged = merged.sort_values(
263
  by="section",
 
290
  comp_category = gr.Dropdown(label="Category")
291
  comp_reset_btn = gr.Button("โ†บ ์ดˆ๊ธฐํ™”")
292
 
293
+ search_btn = gr.Button("๐Ÿ” ์กฐํšŒ")
 
294
 
295
  gr.Markdown("### ๐Ÿ“Š ๋น„๊ต ๊ฒฐ๊ณผ")
296
 
 
328
  font-family: 'Pretendard', sans-serif;
329
  }
330
 
331
+ /* ํ…Œ์ด๋ธ” ๋ ˆ์ด์•„์›ƒ */
332
+ table {
333
+ table-layout: fixed;
334
+ width: 100%;
335
+ }
336
+
337
+ /* section ๊ณ ์ • */
338
+ th:first-child, td:first-child {
339
+ width: 120px;
340
+ min-width: 120px;
341
+ max-width: 120px;
342
+ }
343
+
344
+ /* description ๋™์ผ ๋ถ„ํ•  */
345
+ th:nth-child(2), td:nth-child(2),
346
+ th:nth-child(3), td:nth-child(3) {
347
+ width: calc((100% - 120px) / 2);
348
+ }
349
+
350
+ /* ํ—ค๋” ๊ณ ์ • */
351
  thead th {
352
  position: sticky !important;
353
  top: 0;
 
356
  border-bottom: 2px solid #ddd;
357
  }
358
 
359
+ /* ์Šคํฌ๋กค */
360
  .dataframe {
361
  max-height: 700px;
362
  overflow-y: auto;
363
  }
364
 
365
+ /* ํ…์ŠคํŠธ */
366
  td {
367
  white-space: normal !important;
368
  word-break: break-word !important;
369
  line-height: 1.6;
370
+ padding: 10px;
371
  }
372
  """
373
  )