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 ContentBlockThe metadata writtenblockAnd 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:

  1. 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

  1. 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

  1. Cursor handling
  2. mutable

The next step

Supports adding/deleting rows and columns