@gendive/chatllm 0.6.1 → 0.6.3

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.
@@ -1819,13 +1819,16 @@ var LinkChip = ({
1819
1819
 
1820
1820
  // src/react/components/MarkdownRenderer.tsx
1821
1821
  var import_jsx_runtime6 = require("react/jsx-runtime");
1822
- var LINK_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
1822
+ var IMAGE_REGEX = /!\[([^\]]*)\]\(([^)]+)\)/g;
1823
+ var LINK_REGEX = /(?<!!)\[([^\]]+)\]\(([^)]+)\)/g;
1823
1824
  var SOURCE_LINKS_REGEX = /(\*{0,2}출처:?\*{0,2}\s*)?((?:\[`?[^\]]+`?\]\([^)]+\)\s*)+)/gi;
1824
1825
  var CODE_BLOCK_REGEX = /```(\w*)\n?([\s\S]*?)```/g;
1825
1826
  var INLINE_CODE_REGEX = /`([^`]+)`/g;
1826
1827
  var BOLD_REGEX = /\*\*([^*]+)\*\*/g;
1827
1828
  var ITALIC_REGEX = /(?<!\*)\*([^*]+)\*(?!\*)/g;
1828
1829
  var HR_REGEX = /^---+$/gm;
1830
+ var TABLE_ROW_REGEX = /^\|(.+)\|$/;
1831
+ var TABLE_SEPARATOR_REGEX = /^\|[\s\-:|]+\|$/;
1829
1832
  var parseSourceLinks = (text) => {
1830
1833
  const links = [];
1831
1834
  let match;
@@ -1845,8 +1848,9 @@ var parseInlineElements = (text, key) => {
1845
1848
  currentText = currentText.replace(INLINE_CODE_REGEX, "\xA7CODE\xA7$1\xA7/CODE\xA7");
1846
1849
  currentText = currentText.replace(BOLD_REGEX, "\xA7BOLD\xA7$1\xA7/BOLD\xA7");
1847
1850
  currentText = currentText.replace(ITALIC_REGEX, "\xA7ITALIC\xA7$1\xA7/ITALIC\xA7");
1851
+ currentText = currentText.replace(IMAGE_REGEX, "\xA7IMAGE\xA7$1\xA7URL\xA7$2\xA7/IMAGE\xA7");
1848
1852
  currentText = currentText.replace(LINK_REGEX, "\xA7LINK\xA7$1\xA7URL\xA7$2\xA7/LINK\xA7");
1849
- const parts = currentText.split(/(§CODE§.*?§\/CODE§|§BOLD§.*?§\/BOLD§|§ITALIC§.*?§\/ITALIC§|§LINK§.*?§\/LINK§)/);
1853
+ const parts = currentText.split(/(§CODE§.*?§\/CODE§|§BOLD§.*?§\/BOLD§|§ITALIC§.*?§\/ITALIC§|§IMAGE§.*?§\/IMAGE§|§LINK§.*?§\/LINK§)/);
1850
1854
  parts.forEach((part, index) => {
1851
1855
  if (part.startsWith("\xA7CODE\xA7")) {
1852
1856
  const content = part.replace("\xA7CODE\xA7", "").replace("\xA7/CODE\xA7", "");
@@ -1873,6 +1877,28 @@ var parseInlineElements = (text, key) => {
1873
1877
  } else if (part.startsWith("\xA7ITALIC\xA7")) {
1874
1878
  const content = part.replace("\xA7ITALIC\xA7", "").replace("\xA7/ITALIC\xA7", "");
1875
1879
  elements.push(/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: content }, `${key}-italic-${index}`));
1880
+ } else if (part.startsWith("\xA7IMAGE\xA7")) {
1881
+ const match = part.match(/§IMAGE§(.*)§URL§(.+?)§\/IMAGE§/);
1882
+ if (match) {
1883
+ elements.push(
1884
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1885
+ "img",
1886
+ {
1887
+ src: match[2],
1888
+ alt: match[1] || "",
1889
+ className: "chatllm-image",
1890
+ style: {
1891
+ maxWidth: "100%",
1892
+ borderRadius: "8px",
1893
+ margin: "8px 0",
1894
+ display: "block"
1895
+ },
1896
+ loading: "lazy"
1897
+ },
1898
+ `${key}-image-${index}`
1899
+ )
1900
+ );
1901
+ }
1876
1902
  } else if (part.startsWith("\xA7LINK\xA7")) {
1877
1903
  const match = part.match(/§LINK§(.+?)§URL§(.+?)§\/LINK§/);
1878
1904
  if (match) {
@@ -1899,6 +1925,64 @@ var parseInlineElements = (text, key) => {
1899
1925
  });
1900
1926
  return elements;
1901
1927
  };
1928
+ var parseTableAlignment = (separatorRow) => {
1929
+ const cells = separatorRow.split("|").filter((cell) => cell.trim() !== "");
1930
+ return cells.map((cell) => {
1931
+ const trimmed = cell.trim();
1932
+ const hasLeftColon = trimmed.startsWith(":");
1933
+ const hasRightColon = trimmed.endsWith(":");
1934
+ if (hasLeftColon && hasRightColon) return "center";
1935
+ if (hasRightColon) return "right";
1936
+ return "left";
1937
+ });
1938
+ };
1939
+ var parseTableRow = (row) => {
1940
+ return row.split("|").slice(1, -1).map((cell) => cell.trim());
1941
+ };
1942
+ var MarkdownTable = ({ data }) => {
1943
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1944
+ "table",
1945
+ {
1946
+ className: "chatllm-table",
1947
+ style: {
1948
+ width: "100%",
1949
+ borderCollapse: "collapse",
1950
+ margin: "12px 0",
1951
+ fontSize: "14px"
1952
+ },
1953
+ children: [
1954
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: data.headers.map((header, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1955
+ "th",
1956
+ {
1957
+ style: {
1958
+ border: "1px solid var(--chatllm-border, #e5e7eb)",
1959
+ padding: "10px 12px",
1960
+ textAlign: data.alignments[i] || "left",
1961
+ backgroundColor: "var(--chatllm-bg-secondary, #f9fafb)",
1962
+ fontWeight: 600,
1963
+ color: "var(--chatllm-text, #374151)"
1964
+ },
1965
+ children: parseInlineElements(header, `th-${i}`)
1966
+ },
1967
+ i
1968
+ )) }) }),
1969
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tbody", { children: data.rows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: row.map((cell, cellIndex) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1970
+ "td",
1971
+ {
1972
+ style: {
1973
+ border: "1px solid var(--chatllm-border, #e5e7eb)",
1974
+ padding: "10px 12px",
1975
+ textAlign: data.alignments[cellIndex] || "left",
1976
+ color: "var(--chatllm-text, #374151)"
1977
+ },
1978
+ children: parseInlineElements(cell, `td-${rowIndex}-${cellIndex}`)
1979
+ },
1980
+ cellIndex
1981
+ )) }, rowIndex)) })
1982
+ ]
1983
+ }
1984
+ );
1985
+ };
1902
1986
  var CodeBlock = ({ language, code }) => {
1903
1987
  const [copied, setCopied] = import_react5.default.useState(false);
1904
1988
  const handleCopy = async () => {
@@ -2036,6 +2120,35 @@ var MarkdownRenderer = ({ content, className }) => {
2036
2120
  const lines = processedContent.split("\n");
2037
2121
  let currentList = null;
2038
2122
  let blockquoteLines = [];
2123
+ let tableLines = [];
2124
+ const flushTable = () => {
2125
+ if (tableLines.length >= 2) {
2126
+ const headerLine = tableLines[0];
2127
+ const separatorLine = tableLines[1];
2128
+ const dataLines = tableLines.slice(2);
2129
+ if (TABLE_SEPARATOR_REGEX.test(separatorLine)) {
2130
+ const headers = parseTableRow(headerLine);
2131
+ const alignments = parseTableAlignment(separatorLine);
2132
+ const rows = dataLines.map((line) => parseTableRow(line));
2133
+ elements.push(
2134
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2135
+ MarkdownTable,
2136
+ {
2137
+ data: { headers, alignments, rows }
2138
+ },
2139
+ `table-${elements.length}`
2140
+ )
2141
+ );
2142
+ } else {
2143
+ tableLines.forEach((line, i) => {
2144
+ elements.push(
2145
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: { margin: "4px 0" }, children: parseInlineElements(line, `p-table-fallback-${i}`) }, `p-table-fallback-${elements.length}-${i}`)
2146
+ );
2147
+ });
2148
+ }
2149
+ }
2150
+ tableLines = [];
2151
+ };
2039
2152
  const flushList = () => {
2040
2153
  if (currentList) {
2041
2154
  if (currentList.type === "ul") {
@@ -2096,6 +2209,14 @@ var MarkdownRenderer = ({ content, className }) => {
2096
2209
  );
2097
2210
  return;
2098
2211
  }
2212
+ if (TABLE_ROW_REGEX.test(line)) {
2213
+ flushList();
2214
+ flushBlockquote();
2215
+ tableLines.push(line);
2216
+ return;
2217
+ } else if (tableLines.length > 0) {
2218
+ flushTable();
2219
+ }
2099
2220
  if (HR_REGEX.test(line)) {
2100
2221
  flushList();
2101
2222
  flushBlockquote();
@@ -2189,6 +2310,7 @@ var MarkdownRenderer = ({ content, className }) => {
2189
2310
  });
2190
2311
  flushList();
2191
2312
  flushBlockquote();
2313
+ flushTable();
2192
2314
  return elements;
2193
2315
  }, [content]);
2194
2316
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -3917,6 +4039,39 @@ var injectStyles = () => {
3917
4039
  background-color: var(--chatllm-border);
3918
4040
  border-radius: 3px;
3919
4041
  }
4042
+
4043
+ .chatllm-table {
4044
+ width: 100%;
4045
+ border-collapse: collapse;
4046
+ margin: 12px 0;
4047
+ }
4048
+
4049
+ .chatllm-table th,
4050
+ .chatllm-table td {
4051
+ border: 1px solid var(--chatllm-border, #e5e7eb);
4052
+ padding: 10px 12px;
4053
+ }
4054
+
4055
+ .chatllm-table th {
4056
+ background-color: var(--chatllm-bg-secondary, #f9fafb);
4057
+ font-weight: 600;
4058
+ }
4059
+
4060
+ .chatllm-table tr:hover {
4061
+ background-color: var(--chatllm-bg-hover, #f3f4f6);
4062
+ }
4063
+
4064
+ .chatllm-image {
4065
+ max-width: 100%;
4066
+ border-radius: 8px;
4067
+ margin: 8px 0;
4068
+ display: block;
4069
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
4070
+ }
4071
+
4072
+ .chatllm-image:hover {
4073
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
4074
+ }
3920
4075
  `;
3921
4076
  document.head.appendChild(style);
3922
4077
  };