diff --git a/apps/client/src/widgets/collections/NoteList.tsx b/apps/client/src/widgets/collections/NoteList.tsx
index c613f8d39..bd007a40f 100644
--- a/apps/client/src/widgets/collections/NoteList.tsx
+++ b/apps/client/src/widgets/collections/NoteList.tsx
@@ -14,6 +14,7 @@ import { WebSocketMessage } from "@triliumnext/commons";
import froca from "../../services/froca";
import PresentationView from "./presentation";
import { ListPrintView } from "./legacy/ListPrintView";
+import TablePrintView from "./table/TablePrintView";
interface NoteListProps {
note: FNote | null | undefined;
@@ -117,9 +118,13 @@ function getComponentByViewType(viewType: ViewTypeOptions, props: ViewModeProps<
case "geoMap":
return ;
case "calendar":
- return
+ return ;
case "table":
- return
+ if (props.media !== "print") {
+ return ;
+ } else {
+ return ;
+ }
case "board":
return
case "presentation":
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.css b/apps/client/src/widgets/collections/table/TablePrintView.css
new file mode 100644
index 000000000..fef53c299
--- /dev/null
+++ b/apps/client/src/widgets/collections/table/TablePrintView.css
@@ -0,0 +1,20 @@
+.table-print-view .tabulator-print-table table,
+.table-print-view .tabulator-print-table th,
+.table-print-view .tabulator-print-table tr,
+.table-print-view .tabulator-print-table td {
+ border: 1px solid black;
+ border-collapse: collapse;
+}
+
+.table-print-view .tabulator-print-table th {
+ background-color: #f0f0f0;
+}
+
+.table-print-view .tabulator-print-table th,
+.table-print-view .tabulator-print-table td {
+ padding: 0.25rem 0.5rem;
+}
+
+.table-print-view .tabulator-print-table td[aria-checked] svg path {
+ fill: currentColor;
+}
\ No newline at end of file
diff --git a/apps/client/src/widgets/collections/table/TablePrintView.tsx b/apps/client/src/widgets/collections/table/TablePrintView.tsx
new file mode 100644
index 000000000..534ba5764
--- /dev/null
+++ b/apps/client/src/widgets/collections/table/TablePrintView.tsx
@@ -0,0 +1,49 @@
+import { useEffect, useRef, useState } from "preact/hooks";
+import { ViewModeProps } from "../interface";
+import useData, { TableConfig } from "./data";
+import { ExportModule, FormatModule, Tabulator as VanillaTabulator} from 'tabulator-tables';
+import Tabulator from "./tabulator";
+import { RawHtmlBlock } from "../../react/RawHtml";
+import "./TablePrintView.css";
+
+export default function TablePrintView({ note, noteIds, viewConfig, onReady }: ViewModeProps) {
+ const tabulatorRef = useRef(null);
+ const { columnDefs, rowData, hasChildren } = useData(note, noteIds, viewConfig, undefined, () => {});
+ const [ html, setHtml ] = useState();
+
+ useEffect(() => {
+ if (!html) return;
+ onReady?.();
+ }, [ html ]);
+
+ return rowData && (
+ <>
+ {note.title}
+
+
+
+ {!html ? (
+ {
+ const tabulator = tabulatorRef.current;
+ if (!tabulator) return;
+ setHtml(tabulator.getHtml());
+ }}
+ />
+ ) : (
+
+ )}
+
+ >
+
+ )
+}
diff --git a/apps/client/src/widgets/collections/table/data.tsx b/apps/client/src/widgets/collections/table/data.tsx
new file mode 100644
index 000000000..94909939d
--- /dev/null
+++ b/apps/client/src/widgets/collections/table/data.tsx
@@ -0,0 +1,77 @@
+import type { ColumnDefinition } from "tabulator-tables";
+import FNote from "../../../entities/fnote";
+import { useNoteLabelBoolean, useNoteLabelInt, useTriliumEvent } from "../../react/hooks";
+import { useEffect, useState } from "preact/hooks";
+import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows";
+import froca from "../../../services/froca";
+import { buildColumnDefinitions } from "./columns";
+import attributes from "../../../services/attributes";
+import { RefObject } from "preact";
+
+export interface TableConfig {
+ tableData: {
+ columns?: ColumnDefinition[];
+ };
+}
+
+export default function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject | undefined, resetNewAttributePosition: () => void) {
+ const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth");
+ const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
+
+ const [ columnDefs, setColumnDefs ] = useState();
+ const [ rowData, setRowData ] = useState();
+ const [ hasChildren, setHasChildren ] = useState();
+ const [ isSorted ] = useNoteLabelBoolean(note, "sorted");
+ const [ movableRows, setMovableRows ] = useState(false);
+
+ async function refresh() {
+ const info = getAttributeDefinitionInformation(note);
+
+ // Ensure all note IDs are loaded.
+ await froca.getNotes(noteIds);
+
+ const { definitions: rowData, hasSubtree: hasChildren, rowNumber } = await buildRowDefinitions(note, info, includeArchived, maxDepth);
+ const columnDefs = buildColumnDefinitions({
+ info,
+ movableRows,
+ existingColumnData: viewConfig?.tableData?.columns,
+ rowNumberHint: rowNumber,
+ position: newAttributePosition?.current ?? undefined
+ });
+ setColumnDefs(columnDefs);
+ setRowData(rowData);
+ setHasChildren(hasChildren);
+ resetNewAttributePosition();
+ }
+
+ useEffect(() => { refresh() }, [ note, noteIds, maxDepth, movableRows ]);
+
+ useTriliumEvent("entitiesReloaded", ({ loadResults}) => {
+ if (glob.device === "print") return;
+
+ // React to column changes.
+ if (loadResults.getAttributeRows().find(attr =>
+ attr.type === "label" &&
+ (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) &&
+ attributes.isAffecting(attr, note))) {
+ refresh();
+ return;
+ }
+
+ // React to external row updates.
+ if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? ""))
+ || loadResults.getNoteIds().some(noteId => noteIds.includes(noteId))
+ || loadResults.getAttributeRows().some(attr => noteIds.includes(attr.noteId!))
+ || loadResults.getAttributeRows().some(attr => attr.name === "archived" && attr.noteId && noteIds.includes(attr.noteId))) {
+ refresh();
+ return;
+ }
+ });
+
+ // Identify if movable rows.
+ useEffect(() => {
+ setMovableRows(!isSorted && note.type !== "search" && !hasChildren);
+ }, [ isSorted, note, hasChildren ]);
+
+ return { columnDefs, rowData, movableRows, hasChildren };
+}
diff --git a/apps/client/src/widgets/collections/table/index.tsx b/apps/client/src/widgets/collections/table/index.tsx
index f6ae82009..d557f12d3 100644
--- a/apps/client/src/widgets/collections/table/index.tsx
+++ b/apps/client/src/widgets/collections/table/index.tsx
@@ -1,10 +1,9 @@
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "preact/hooks";
import { ViewModeProps } from "../interface";
-import { buildColumnDefinitions } from "./columns";
-import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } from "./rows";
-import { useLegacyWidget, useNoteLabelBoolean, useNoteLabelInt, useTriliumEvent } from "../../react/hooks";
+import { TableData } from "./rows";
+import { useLegacyWidget } from "../../react/hooks";
import Tabulator from "./tabulator";
-import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule, Options, RowComponent} from 'tabulator-tables';
+import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, DataTreeModule, Options, RowComponent} from 'tabulator-tables';
import { useContextMenu } from "./context_menu";
import { ParentComponent } from "../../react/react_utils";
import FNote from "../../../entities/fnote";
@@ -14,16 +13,8 @@ import "./index.css";
import useRowTableEditing from "./row_editing";
import useColTableEditing from "./col_editing";
import AttributeDetailWidget from "../../attribute_widgets/attribute_detail";
-import attributes from "../../../services/attributes";
-import { RefObject } from "preact";
import SpacedUpdate from "../../../services/spaced_update";
-import froca from "../../../services/froca";
-
-interface TableConfig {
- tableData: {
- columns?: ColumnDefinition[];
- };
-}
+import useData, { TableConfig } from "./data";
export default function TableView({ note, noteIds, notePath, viewConfig, saveConfig }: ViewModeProps) {
const tabulatorRef = useRef(null);
@@ -118,67 +109,7 @@ function usePersistence(viewConfig: TableConfig | null | undefined, saveConfig:
return () => {
spacedUpdate.updateNowIfNecessary();
};
- }, [ viewConfig, saveConfig ])
+ }, [ viewConfig, saveConfig ]);
return persistenceProps;
}
-
-function useData(note: FNote, noteIds: string[], viewConfig: TableConfig | undefined, newAttributePosition: RefObject, resetNewAttributePosition: () => void) {
- const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
- const [ includeArchived ] = useNoteLabelBoolean(note, "includeArchived");
-
- const [ columnDefs, setColumnDefs ] = useState();
- const [ rowData, setRowData ] = useState();
- const [ hasChildren, setHasChildren ] = useState();
- const [ isSorted ] = useNoteLabelBoolean(note, "sorted");
- const [ movableRows, setMovableRows ] = useState(false);
-
- async function refresh() {
- const info = getAttributeDefinitionInformation(note);
-
- // Ensure all note IDs are loaded.
- await froca.getNotes(noteIds);
-
- const { definitions: rowData, hasSubtree: hasChildren, rowNumber } = await buildRowDefinitions(note, info, includeArchived, maxDepth);
- const columnDefs = buildColumnDefinitions({
- info,
- movableRows,
- existingColumnData: viewConfig?.tableData?.columns,
- rowNumberHint: rowNumber,
- position: newAttributePosition.current ?? undefined
- });
- setColumnDefs(columnDefs);
- setRowData(rowData);
- setHasChildren(hasChildren);
- resetNewAttributePosition();
- }
-
- useEffect(() => { refresh() }, [ note, noteIds, maxDepth, movableRows ]);
-
- useTriliumEvent("entitiesReloaded", ({ loadResults}) => {
- // React to column changes.
- if (loadResults.getAttributeRows().find(attr =>
- attr.type === "label" &&
- (attr.name?.startsWith("label:") || attr.name?.startsWith("relation:")) &&
- attributes.isAffecting(attr, note))) {
- refresh();
- return;
- }
-
- // React to external row updates.
- if (loadResults.getBranchRows().some(branch => branch.parentNoteId === note.noteId || noteIds.includes(branch.parentNoteId ?? ""))
- || loadResults.getNoteIds().some(noteId => noteIds.includes(noteId))
- || loadResults.getAttributeRows().some(attr => noteIds.includes(attr.noteId!))
- || loadResults.getAttributeRows().some(attr => attr.name === "archived" && attr.noteId && noteIds.includes(attr.noteId))) {
- refresh();
- return;
- }
- });
-
- // Identify if movable rows.
- useEffect(() => {
- setMovableRows(!isSorted && note.type !== "search" && !hasChildren);
- }, [ isSorted, note, hasChildren ]);
-
- return { columnDefs, rowData, movableRows, hasChildren };
-}
diff --git a/apps/client/src/widgets/collections/table/tabulator.tsx b/apps/client/src/widgets/collections/table/tabulator.tsx
index 6301d5b38..31fb8d4f8 100644
--- a/apps/client/src/widgets/collections/table/tabulator.tsx
+++ b/apps/client/src/widgets/collections/table/tabulator.tsx
@@ -14,9 +14,10 @@ interface TableProps extends Omit;
index: keyof T;
footerElement?: string | HTMLElement | JSX.Element;
+ onReady?: () => void;
}
-export default function Tabulator({ className, columns, data, modules, tabulatorRef: externalTabulatorRef, footerElement, events, index, dataTree, ...restProps }: TableProps) {
+export default function Tabulator({ className, columns, data, modules, tabulatorRef: externalTabulatorRef, footerElement, events, index, dataTree, onReady, ...restProps }: TableProps) {
const parentComponent = useContext(ParentComponent);
const containerRef = useRef(null);
const tabulatorRef = useRef(null);
@@ -43,6 +44,7 @@ export default function Tabulator({ className, columns, data, modules, tabula
tabulator.on("tableBuilt", () => {
tabulatorRef.current = tabulator;
externalTabulatorRef.current = tabulator;
+ onReady?.();
});
return () => tabulator.destroy();
diff --git a/apps/client/src/widgets/ribbon/NoteActions.tsx b/apps/client/src/widgets/ribbon/NoteActions.tsx
index d7e344dd8..33017221b 100644
--- a/apps/client/src/widgets/ribbon/NoteActions.tsx
+++ b/apps/client/src/widgets/ribbon/NoteActions.tsx
@@ -49,7 +49,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
const canBeConvertedToAttachment = note?.isEligibleForConversionToAttachment();
const isSearchable = ["text", "code", "book", "mindMap", "doc"].includes(note.type);
const isInOptionsOrHelp = note?.noteId.startsWith("_options") || note?.noteId.startsWith("_help");
- const isPrintable = ["text", "code"].includes(note.type) || (note.type === "book" && ["presentation", "list"].includes(note.getLabelValue("viewType") ?? ""));
+ const isPrintable = ["text", "code"].includes(note.type) || (note.type === "book" && ["presentation", "list", "table"].includes(note.getLabelValue("viewType") ?? ""));
const isElectron = getIsElectron();
const isMac = getIsMac();
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(note.type);
diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
index 35ae5862b..2e3b2c92c 100644
--- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
+++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.html
@@ -59,9 +59,9 @@ class="admonition note">
orientation, size. However, there are a few Attributes to adjust some of the settings:
- - To print in landscape mode instead of portrait (useful for big diagrams
+
- To print in landscape mode instead of portrait (useful for big diagrams
or slides), add
#printLandscape.
- - By default, the resulting PDF will be in Letter format. It is possible
+
- By default, the resulting PDF will be in Letter format. It is possible
to adjust it to another page size via the
#printPageSize attribute,
with one of the following values: A0, A1, A2, A3, A4, A5, A6, Legal, Letter, Tabloid, Ledger.
@@ -71,12 +71,12 @@ class="admonition note">
Printing multiple notes
Since v0.100.0, it is possible to print more than one note at the time
- by using Collections:
+ by using Collections:
- - First create a collection.
- - Configure it to use List View.
+ - First create a collection.
+ - Configure it to use List View.
- Print the collection note normally.
+ data-list-item-id="ecaad5f90dcbfd65da21689c54b063ff9">Print the collection note normally.
The resulting collection will contain all the children of the collection,
while maintaining the hierarchy.
@@ -86,9 +86,9 @@ class="admonition note">
href="#root/_help_4TIF1oA4VQRO">Options and assigning a key combination
for:
- - Print Active Note
+
- Print Active Note
- - Export Active Note as PDF
+
- Export Active Note as PDF
Constraints & limitations
@@ -96,28 +96,39 @@ class="admonition note">
supported when printing, in which case the Print and Export as PDF options
will be disabled.
- - For Code notes:
+
- For Code notes:
- - Line numbers are not printed.
- - Syntax highlighting is enabled, however a default theme (Visual Studio)
+
- Line numbers are not printed.
+ - Syntax highlighting is enabled, however a default theme (Visual Studio)
is enforced.
- - For Collections:
+
- For Collections,
+ the following are supported:
- - List View is
- supported, allowing to print multiple notes at once while preserving hierarchy
- (similar to a book).
- - Presentation is
- also supported, where each slide/subnote is displayed.
- - The rest of the collections are not supported, but we plan to add support
+
- List View, allowing
+ to print multiple notes at once while preserving hierarchy (similar to
+ a book).
+ - Presentation,
+ where each slide/sub-note is displayed.
+ - Table,
+ where the table is rendered in a print-friendly way.
+
+ - Tables that are too complex (especially if they have multiple columns)
+ might not fit properly, however tables with a large number of rows are
+ supported thanks to pagination.
+ - Consider printing in landscape mode, or using
#printLandscape if
+ exporting to PDF.
+
+
+ - The rest of the collections are not supported, but we plan to add support
for all the collection types at some point.
- - Using Custom app-wide CSS for
+
- Using Custom app-wide CSS for
printing is not longer supported, due to a more stable but isolated mechanism.
- - We plan to introduce a new mechanism specifically for a print CSS.
+ - We plan to introduce a new mechanism specifically for a print CSS.
@@ -128,10 +139,10 @@ class="admonition note">
printing.
To do so:
- - Create a CSS code note.
- - On the note being printed, apply the
~printCss relation to
+ - Create a CSS code note.
+ - On the note being printed, apply the
~printCss relation to
point to the newly created CSS code note.
- - To apply the CSS to multiple notes, consider using inheritable attributes or
+
- To apply the CSS to multiple notes, consider using inheritable attributes or
Templates.
@@ -142,11 +153,11 @@ class="admonition note">
}
To remark:
- - Multiple CSS notes can be add by using multiple
~printCss relations.
+ - Multiple CSS notes can be add by using multiple
~printCss relations.
- If the note pointing to the
printCss doesn't have the right
+ data-list-item-id="e5989879c4432018bf90fecc5e31e090b">If the note pointing to the printCss doesn't have the right
note type or mime type, it will be ignored.
- - If migrating from a previous version where If migrating from a previous version where Custom app-wide CSS, there's no need for
@media print { since
the style-sheet is used only for printing.
diff --git a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
index 64c09e024..4c8a97257 100644
--- a/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
+++ b/apps/server/src/assets/doc_notes/en/User Guide/User Guide/Collections/List View.html
@@ -12,22 +12,21 @@
as a single continuous document.
Interaction
- - Each note can be expanded or collapsed by clicking on the arrow to the
+
- Each note can be expanded or collapsed by clicking on the arrow to the
left of the title.
- - In the Ribbon,
+
- In the Ribbon,
in the Collection tab there are options to expand and to collapse
all notes easily.
Printing and exporting to PDF
-Since v0.100.0, list collections can be printed or exported to PDF.
+Since v0.100.0, list collections can be printed or exported to PDF.
A printed list collection will print all the notes in the collection,
in the right order and preserving the full hierarchy.
If exported to PDF within the desktop application, there is additional
functionality:
- - The table of contents of the PDF will reflect the structure of the notes.
- - Reference and inline links to other notes within the same hierarchy will
+
- The table of contents of the PDF will reflect the structure of the notes.
+ - Reference and inline links to other notes within the same hierarchy will
be functional (will jump to the corresponding page). If a link refers to
a note that is not in the printed hierarchy, it will be unlinked.
\ No newline at end of file
diff --git a/docs/Developer Guide/Developer Guide/Documentation.md b/docs/Developer Guide/Developer Guide/Documentation.md
index b8eca125b..6e7ea215f 100644
--- a/docs/Developer Guide/Developer Guide/Documentation.md
+++ b/docs/Developer Guide/Developer Guide/Documentation.md
@@ -1,5 +1,5 @@
# Documentation
-There are multiple types of documentation for Trilium:
+There are multiple types of documentation for Trilium:
* The _User Guide_ represents the user-facing documentation. This documentation can be browsed by users directly from within Trilium, by pressing F1.
* The _Developer's Guide_ represents a set of Markdown documents that present the internals of Trilium, for developers.
diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json
index 7b77cb46a..014f86614 100644
--- a/docs/User Guide/!!!meta.json
+++ b/docs/User Guide/!!!meta.json
@@ -4062,66 +4062,73 @@
{
"type": "relation",
"name": "internalLink",
- "value": "4TIF1oA4VQRO",
+ "value": "GTwFsgaA0lCt",
"isInheritable": false,
"position": 40
},
{
"type": "relation",
"name": "internalLink",
- "value": "KSZ04uQ2D1St",
+ "value": "mULW0Q3VojwY",
"isInheritable": false,
"position": 50
},
{
"type": "relation",
"name": "internalLink",
- "value": "6f9hih2hXXZk",
+ "value": "4TIF1oA4VQRO",
"isInheritable": false,
"position": 60
},
{
"type": "relation",
"name": "internalLink",
- "value": "GTwFsgaA0lCt",
+ "value": "KSZ04uQ2D1St",
"isInheritable": false,
"position": 70
},
{
"type": "relation",
"name": "internalLink",
- "value": "zP3PMqaG71Ct",
+ "value": "6f9hih2hXXZk",
"isInheritable": false,
"position": 80
},
{
"type": "relation",
"name": "internalLink",
- "value": "AlhDUqhENtH7",
+ "value": "zP3PMqaG71Ct",
"isInheritable": false,
"position": 90
},
{
"type": "relation",
"name": "internalLink",
- "value": "bwZpz2ajCEwO",
+ "value": "AlhDUqhENtH7",
"isInheritable": false,
"position": 100
},
{
"type": "relation",
"name": "internalLink",
- "value": "KC1HB96bqqHX",
+ "value": "bwZpz2ajCEwO",
"isInheritable": false,
"position": 110
},
{
"type": "relation",
"name": "internalLink",
- "value": "0ESUbbAxVnoK",
+ "value": "KC1HB96bqqHX",
"isInheritable": false,
"position": 120
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "0ESUbbAxVnoK",
+ "isInheritable": false,
+ "position": 130
+ },
{
"type": "label",
"name": "iconClass",
@@ -4139,9 +4146,9 @@
{
"type": "relation",
"name": "internalLink",
- "value": "mULW0Q3VojwY",
+ "value": "2FvYrpmOXm29",
"isInheritable": false,
- "position": 130
+ "position": 140
}
],
"format": "markdown",
@@ -10472,6 +10479,13 @@
"isInheritable": false,
"position": 20
},
+ {
+ "type": "relation",
+ "name": "internalLink",
+ "value": "NRnIZmSMc5sj",
+ "isInheritable": false,
+ "position": 30
+ },
{
"type": "label",
"name": "iconClass",
@@ -10485,13 +10499,6 @@
"value": "list",
"isInheritable": false,
"position": 30
- },
- {
- "type": "relation",
- "name": "internalLink",
- "value": "NRnIZmSMc5sj",
- "isInheritable": false,
- "position": 40
}
],
"format": "markdown",
diff --git a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
index 083ad6ec7..56b0adb74 100644
--- a/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
+++ b/docs/User Guide/User Guide/Basic Concepts and Features/Notes/Printing & Exporting as PDF.md
@@ -73,9 +73,12 @@ Not all Note Types
* For Code notes:
* Line numbers are not printed.
* Syntax highlighting is enabled, however a default theme (Visual Studio) is enforced.
-* For Collections:
- * List View is supported, allowing to print multiple notes at once while preserving hierarchy (similar to a book).
- * Presentation is also supported, where each slide/subnote is displayed.
+* For Collections, the following are supported:
+ * List View, allowing to print multiple notes at once while preserving hierarchy (similar to a book).
+ * Presentation, where each slide/sub-note is displayed.
+ * Table, where the table is rendered in a print-friendly way.
+ * Tables that are too complex (especially if they have multiple columns) might not fit properly, however tables with a large number of rows are supported thanks to pagination.
+ * Consider printing in landscape mode, or using `#printLandscape` if exporting to PDF.
* The rest of the collections are not supported, but we plan to add support for all the collection types at some point.
* Using Custom app-wide CSS for printing is not longer supported, due to a more stable but isolated mechanism.
* We plan to introduce a new mechanism specifically for a print CSS.