Created
January 15, 2025 03:25
-
-
Save jakob-stoeck/2d1e2e774ab20ad8f4ff84c585f63814 to your computer and use it in GitHub Desktop.
Create LaTeX booktabs-like tables in Google Docs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create a table with less bloat in Google Docs | |
// No vertical lines, and no horizontal lines except for header and footer | |
// Inspired by https://ctan.org/pkg/booktabs | |
function createBooktabsTable() { | |
// Table configuration | |
const numRows = 5; // Adjust as needed | |
const numCols = 4; // Adjust as needed | |
const doc = DocumentApp.getActiveDocument(); | |
createBooktabsTableInternal(numRows, numCols, doc) | |
} | |
// Apply Booktabs-style formatting | |
function createBooktabsTableInternal(numRows, numCols, doc) { | |
const body = doc.getBody(); | |
// Insert a table | |
const table = body.appendTable(); | |
// Populate the table with rows and cells | |
for (let i = 0; i < numRows; i++) { | |
const row = table.appendTableRow(); | |
for (let j = 0; j < numCols; j++) { | |
const content = i === 0 ? `Header ${j + 1}` : `Row ${i}, Col ${j + 1}` | |
const cell = row.appendTableCell(content); | |
// Style header row | |
// TODO this can be an updateTableStyle with tableRange https://googleapis.dev/nodejs/googleapis/latest/docs/interfaces/Schema$UpdateTableCellStyleRequest.html#tableStartLocation | |
// but I haven’t checked how to set TextStyle inside a table cell, yet | |
cell.getChild(0).asText().setBold(i === 0 ? true : false); | |
} | |
} | |
doc.saveAndClose(); | |
// Google Apps Script alone has no means to change cell properties like borders. | |
// That’s why we use Docs service. If you use this inside an Apps Script ensure to under: "Services +" add "Docs" | |
const docId = doc.getId(); | |
const i = body.getChildIndex(table); | |
const index = Docs.Documents.get(docId).body.content[i + 1].startIndex; | |
const noBorder = { dashStyle: "SOLID", width: { magnitude: 0, unit: "PT" }, color: { color: {} } }; | |
const thinBorder = { dashStyle: "SOLID", width: { magnitude: 1, unit: "PT" }, color: { color: {} } }; | |
const thickBorder = { dashStyle: "SOLID", width: { magnitude: 1.5, unit: "PT" }, color: { color: {} } }; | |
const noBorders = { | |
updateTableCellStyle: { | |
tableCellStyle: { | |
borderRight: noBorder, | |
borderLeft: noBorder, | |
borderTop: noBorder, | |
borderBottom: noBorder, | |
}, | |
tableStartLocation: { index }, | |
fields: "borderRight,borderLeft,borderTop,borderBottom", | |
} | |
} | |
const tableHeader = { | |
updateTableCellStyle: { | |
tableCellStyle: { | |
borderTop: thickBorder, | |
borderBottom: thinBorder, | |
}, | |
tableRange: { | |
tableCellLocation: { | |
columnIndex: 0, | |
rowIndex: 0, | |
tableStartLocation: { index } | |
}, | |
columnSpan: numCols, // optional ? | |
rowSpan: 1, // optional ? | |
}, | |
fields: "borderTop,borderBottom", | |
} | |
} | |
const tableFooter = { | |
updateTableCellStyle: { | |
tableCellStyle: { | |
borderBottom: thickBorder | |
}, | |
tableRange: { | |
tableCellLocation: { | |
columnIndex: 0, | |
rowIndex: numRows-1, | |
tableStartLocation: { index } | |
}, | |
columnSpan: numCols, // optional ? | |
rowSpan: 1, // optional ? | |
}, | |
fields: "borderBottom", | |
} | |
} | |
const requests = [noBorders, tableHeader, tableFooter]; | |
const resp = Docs.Documents.batchUpdate({ requests }, docId); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment