@tfw.in/structura-lib 0.2.5 → 0.2.6
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.
- package/README.md +31 -10
- package/dist/cjs/HtmlViewer.js +11 -9
- package/dist/esm/HtmlViewer.js +12 -9
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -121,28 +121,49 @@ function App() {
|
|
|
121
121
|
|
|
122
122
|
## Math Rendering
|
|
123
123
|
|
|
124
|
-
The
|
|
124
|
+
The Structura component automatically renders LaTeX math expressions (`$m^2$`, `$L/m^2$`, etc.) when `mathRendering={true}` (the default).
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
- Display math: `$$\sum_{i=1}^{n} x_i$$`
|
|
126
|
+
If you extract text from the response structure (e.g. Gemini corrected output) and render it in your own components, the raw LaTeX delimiters will appear as plain text. Use `renderMathInHtml` to convert them to rendered math:
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
```jsx
|
|
129
|
+
import { renderMathInHtml } from '@tfw.in/structura-lib';
|
|
130
|
+
|
|
131
|
+
// Convert LaTeX delimiters to rendered HTML
|
|
132
|
+
const rawText = "Total membrane area required 0.02$m^2$";
|
|
133
|
+
const rendered = renderMathInHtml(rawText);
|
|
134
|
+
// Use with dangerouslySetInnerHTML
|
|
135
|
+
<div dangerouslySetInnerHTML={{ __html: rendered }} />
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Utilities
|
|
139
|
+
|
|
140
|
+
| Export | Type | Description |
|
|
141
|
+
|--------|------|-------------|
|
|
142
|
+
| `renderMathInHtml(html)` | `function` | Converts `$...$` (inline) and `$$...$$` (display) math to KaTeX HTML. Use this when rendering extracted text in your own components. |
|
|
143
|
+
| `containsMath(html)` | `function` | Returns `true` if the string contains math delimiters. |
|
|
144
|
+
| `MathContent` | `React component` | Renders HTML with math expressions. Props: `html`, `className`, `as` (element type). |
|
|
145
|
+
| `useMathHtml(html)` | `React hook` | Returns rendered math HTML string via `useMemo`. |
|
|
130
146
|
|
|
131
147
|
```jsx
|
|
132
|
-
import { MathContent, renderMathInHtml, containsMath } from '@tfw.in/structura-lib';
|
|
148
|
+
import { MathContent, renderMathInHtml, containsMath, useMathHtml } from '@tfw.in/structura-lib';
|
|
133
149
|
|
|
134
|
-
// React component
|
|
150
|
+
// As a React component
|
|
135
151
|
<MathContent html="The formula is $E = mc^2$" />
|
|
136
152
|
|
|
137
|
-
//
|
|
138
|
-
|
|
153
|
+
// As a hook
|
|
154
|
+
function MyComponent({ text }) {
|
|
155
|
+
const rendered = useMathHtml(text);
|
|
156
|
+
return <span dangerouslySetInnerHTML={{ __html: rendered }} />;
|
|
157
|
+
}
|
|
139
158
|
|
|
140
|
-
// Check
|
|
159
|
+
// Check before processing
|
|
141
160
|
if (containsMath(text)) {
|
|
142
|
-
|
|
161
|
+
const html = renderMathInHtml(text);
|
|
143
162
|
}
|
|
144
163
|
```
|
|
145
164
|
|
|
165
|
+
> **Note:** Ensure you import the library styles (`@tfw.in/structura-lib/styles.css`) — this loads the KaTeX CSS required for proper math rendering.
|
|
166
|
+
|
|
146
167
|
## Semantic Tags
|
|
147
168
|
|
|
148
169
|
Parse and render semantic tags for document corrections:
|
package/dist/cjs/HtmlViewer.js
CHANGED
|
@@ -8,6 +8,7 @@ var vsc = require('react-icons/vsc');
|
|
|
8
8
|
var index_esm = require('./node_modules/react-icons/fa/index.esm.js');
|
|
9
9
|
var Table = require('./Table.js');
|
|
10
10
|
var EditableContent = require('./EditableContent.js');
|
|
11
|
+
var MathRenderer = require('./MathRenderer.js');
|
|
11
12
|
var accuracyMetrics = require('./accuracyMetrics.js');
|
|
12
13
|
var SemanticTagParser = require('./SemanticTagParser.js');
|
|
13
14
|
|
|
@@ -248,19 +249,19 @@ const FaTagsIcon = index_esm.FaTags;
|
|
|
248
249
|
function GeminiCorrectedBlock({
|
|
249
250
|
html,
|
|
250
251
|
isEditMode,
|
|
251
|
-
onContentChange
|
|
252
|
+
onContentChange,
|
|
253
|
+
enableMathRendering = true
|
|
252
254
|
}) {
|
|
253
255
|
const ref = React.useRef(null);
|
|
254
|
-
|
|
256
|
+
const processedHtml = React.useMemo(() => {
|
|
257
|
+
return enableMathRendering ? MathRenderer.renderMathInHtml(html) : html;
|
|
258
|
+
}, [html, enableMathRendering]);
|
|
255
259
|
// Set initial HTML only once via ref — never via dangerouslySetInnerHTML on a contentEditable
|
|
256
260
|
React.useEffect(() => {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (ref.current && ref.current.innerHTML !== html) {
|
|
260
|
-
ref.current.innerHTML = html;
|
|
261
|
-
console.log('[GeminiCorrectedBlock] innerHTML set, length:', ref.current.innerHTML.length);
|
|
261
|
+
if (ref.current && ref.current.innerHTML !== processedHtml) {
|
|
262
|
+
ref.current.innerHTML = processedHtml;
|
|
262
263
|
}
|
|
263
|
-
}, [
|
|
264
|
+
}, [processedHtml]);
|
|
264
265
|
React.useEffect(() => {
|
|
265
266
|
var _a;
|
|
266
267
|
console.log('[GeminiCorrectedBlock] isEditMode changed to:', isEditMode, '— contentEditable on div:', (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentEditable);
|
|
@@ -665,7 +666,8 @@ function HtmlViewer({
|
|
|
665
666
|
}) : ((_b = node.id) === null || _b === void 0 ? void 0 : _b.endsWith('/GeminiCorrected')) ? jsxRuntime.jsx(GeminiCorrectedBlock, {
|
|
666
667
|
html: node.html || '',
|
|
667
668
|
isEditMode: viewMode === 'edit',
|
|
668
|
-
onContentChange: newHtml => handleContentChange(node.id, newHtml)
|
|
669
|
+
onContentChange: newHtml => handleContentChange(node.id, newHtml),
|
|
670
|
+
enableMathRendering: enableMathRendering
|
|
669
671
|
}) : jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
670
672
|
children: [jsxRuntime.jsx(EditableContent.default, {
|
|
671
673
|
id: node.id,
|
package/dist/esm/HtmlViewer.js
CHANGED
|
@@ -5,6 +5,7 @@ import { VscJson } from 'react-icons/vsc';
|
|
|
5
5
|
import { FaEdit, FaTags, FaFileDownload, FaChartBar } from './node_modules/react-icons/fa/index.esm.js';
|
|
6
6
|
import Table from './Table.js';
|
|
7
7
|
import EditableContent from './EditableContent.js';
|
|
8
|
+
import { renderMathInHtml } from './MathRenderer.js';
|
|
8
9
|
import { calculateDifferences } from './accuracyMetrics.js';
|
|
9
10
|
import { getTagTypeInfo } from './SemanticTagParser.js';
|
|
10
11
|
|
|
@@ -247,18 +248,19 @@ var FaTagsIcon = FaTags;
|
|
|
247
248
|
function GeminiCorrectedBlock(_ref6) {
|
|
248
249
|
var html = _ref6.html,
|
|
249
250
|
isEditMode = _ref6.isEditMode,
|
|
250
|
-
onContentChange = _ref6.onContentChange
|
|
251
|
+
onContentChange = _ref6.onContentChange,
|
|
252
|
+
_ref6$enableMathRende = _ref6.enableMathRendering,
|
|
253
|
+
enableMathRendering = _ref6$enableMathRende === void 0 ? true : _ref6$enableMathRende;
|
|
251
254
|
var ref = useRef(null);
|
|
252
|
-
|
|
255
|
+
var processedHtml = useMemo(function () {
|
|
256
|
+
return enableMathRendering ? renderMathInHtml(html) : html;
|
|
257
|
+
}, [html, enableMathRendering]);
|
|
253
258
|
// Set initial HTML only once via ref — never via dangerouslySetInnerHTML on a contentEditable
|
|
254
259
|
useEffect(function () {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (ref.current && ref.current.innerHTML !== html) {
|
|
258
|
-
ref.current.innerHTML = html;
|
|
259
|
-
console.log('[GeminiCorrectedBlock] innerHTML set, length:', ref.current.innerHTML.length);
|
|
260
|
+
if (ref.current && ref.current.innerHTML !== processedHtml) {
|
|
261
|
+
ref.current.innerHTML = processedHtml;
|
|
260
262
|
}
|
|
261
|
-
}, [
|
|
263
|
+
}, [processedHtml]);
|
|
262
264
|
useEffect(function () {
|
|
263
265
|
var _a;
|
|
264
266
|
console.log('[GeminiCorrectedBlock] isEditMode changed to:', isEditMode, '— contentEditable on div:', (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contentEditable);
|
|
@@ -748,7 +750,8 @@ function HtmlViewer(_ref7) {
|
|
|
748
750
|
isEditMode: viewMode === 'edit',
|
|
749
751
|
onContentChange: function onContentChange(newHtml) {
|
|
750
752
|
return handleContentChange(node.id, newHtml);
|
|
751
|
-
}
|
|
753
|
+
},
|
|
754
|
+
enableMathRendering: enableMathRendering
|
|
752
755
|
}) : jsxs(Fragment, {
|
|
753
756
|
children: [jsx(EditableContent, {
|
|
754
757
|
id: node.id,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tfw.in/structura-lib",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Structura Library Components",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"test:watch": "vitest"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"react": "^18.2.0",
|
|
33
|
-
"react-dom": "^18.2.0",
|
|
32
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
33
|
+
"react-dom": "^18.2.0 || ^19.0.0",
|
|
34
34
|
"tailwindcss": "^3.3.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"class-variance-authority": "^0.7.0",
|
|
45
45
|
"katex": "^0.16.27",
|
|
46
46
|
"lucide-react": "^0.509.0",
|
|
47
|
-
"pdfjs-dist": "4.8.69",
|
|
47
|
+
"pdfjs-dist": "^4.8.69",
|
|
48
48
|
"postcss-cli": "^11.0.1",
|
|
49
49
|
"react-icons": "^4.12.0",
|
|
50
50
|
"react-pdf": "^9.2.1",
|