The import
My requirement is to implement an online paper typesetting editor and export the PDF generated by LaTeX
Project address: Eorg
Successful examples include Overleaf, a resume builder called Resumake.
Because of my preference for react. js, I chose draft. js, a rich text editor developed by Facebook. Table insertion cannot be avoided when writing papers. Draft.js does not have a ready-made table plug-in to generate tables. However, it is convenient for developers and troublesome for users. The table does not need to be complicated and can be exported as a three-line table. Therefore, I plan to try table insertion myself
The body of the
Implementation idea:
High-end tablesImplementation isnew ContentBlock
The metadata writtenblock
And conforms to the implementation of draft.js
I realize more was catnip, copy the official TeX example, using AtomicBlockUtils. InsertAtomicBlock (newEditorState entityKey, ‘ ‘) API directly to React. Js props:
- The ranks of value
const contentStateWithEntity = contentState.createEntity(
'TABLE'.'IMMUTABLE',
{
row, column, caption, // data},)// ...
const { row, column, caption } = props // Table Component
Copy the code
Tabular data
// createTable.js
Cell = {/ * * * * 0: [" cell - 0, 0, "" cell - 0, 1,...," cell - 0, m "], * 1: [" cell 1, 0, "" cell - 1, 1,...," m "cell - 1,], *... , * n: ["cell-n,0", "cell-n,1", ..., "cell-n,m"], * } */
const cell = Object.fromEntries(Array.from(
{ length: row },
(_, i) = > [
i,
Array.from({ length: column }, (_, j) = > `cell-${i}.${j}`)))const contentStateWithEntity = contentState.createEntity(
'TABLE'.'IMMUTABLE',
{
..., cell, // data},)// ...
const { ..., cell } = props // Table Component
Copy the code
Then initialize the table:
// TableBlock.js
// tbody -- version 1
const coordinate = []
if (row > 1) {
for (let i = 1; i < row; i += 1) {
const cols = []
for (let j = 0; j < column; j += 1) {
cols.push(
<td key={i + j} >
{cell[i][j]}
</td>,
)
}
rows.push(<tr key={i}>{cols}</tr>)}}Copy the code
Row, column, Caption, and cell are passed to props
- Get cell position:
The initial idea was to closest(‘table’) the closest element by calculating the Dom Node position
// TableBlock.js
// tbody -- version 2
const coordinate = []
if (row > 1) { // thead is calculated separately
for (let i = 1; i < row; i += 1) {
const cols = []
for (let j = 0; j < column; j += 1) {
cols.push(
<td
key={i + j} / /TODO key-1
onDoubleClick={()= > coordinate.push([i, j])}
>
{cell[i][j]}
</td>,
)
}
rows.push(<tr key={i}>{cols}</tr>)}}Copy the code
Key-1 in the above code is unstable and can be used by nanoid library, that is:
key = {`i+j+${nanoid()}`}
Copy the code
Make it stable so that you can save the contents of the modified cells:
// find the coordinate of the node clicked
const x1 = coordinate[coordinate.length - 1] [0]
const y1 = coordinate[coordinate.length - 1] [1]
// update cell[i][j]
cell[x1][y1] = evt.target.innerHTML
Copy the code
The contents of cell-2,1 can be modified to store props
conclusion
Tables are not fully functional, for example
- Cursor handling
- mutable
The next step
Supports adding/deleting rows and columns