📰 IT NachrichtenSatellit FLEX macht Photosynthese weltweit sichtbar(10.09.2026 um 10:45 Uhr)
📰 IT NachrichtenPolestar kündigt ein neues Design ab 2027 an(07.09.2026 um 14:56 Uhr)
📰 IT NachrichtenSkoda denkt laut über elektrischen Fabia nach(07.09.2026 um 19:12 Uhr)
📰 IT NachrichtenJaguar Land Rover will Stellen vor dem großen Neustart abbauen(08.09.2026 um 08:48 Uhr)
📰 IT NachrichtenVolkswagen spart (schon wieder) bei der Software(08.09.2026 um 09:00 Uhr)
📰 IT NachrichtenDacia zeigt den komplett neuen Spring(08.09.2026 um 09:14 Uhr)
📰 IT NachrichtenVolkswagen will sich von weiterer Marke trennen(08.09.2026 um 12:14 Uhr)
📰 IT NachrichtenMercedes VLE wird günstiger: Das sind die neuen Preise(08.09.2026 um 13:08 Uhr)
📰 IT NachrichtenSatellit FLEX macht Photosynthese weltweit sichtbar(10.09.2026 um 10:45 Uhr)
📰 IT NachrichtenPolestar kündigt ein neues Design ab 2027 an(07.09.2026 um 14:56 Uhr)
📰 IT NachrichtenSkoda denkt laut über elektrischen Fabia nach(07.09.2026 um 19:12 Uhr)
📰 IT NachrichtenJaguar Land Rover will Stellen vor dem großen Neustart abbauen(08.09.2026 um 08:48 Uhr)
📰 IT NachrichtenVolkswagen spart (schon wieder) bei der Software(08.09.2026 um 09:00 Uhr)
📰 IT NachrichtenDacia zeigt den komplett neuen Spring(08.09.2026 um 09:14 Uhr)
📰 IT NachrichtenVolkswagen will sich von weiterer Marke trennen(08.09.2026 um 12:14 Uhr)
📰 IT NachrichtenMercedes VLE wird günstiger: Das sind die neuen Preise(08.09.2026 um 13:08 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 5 Min Lesezeit
0

I made a plugin that enables PDF export in GROWI.

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht





About the Code



The code is available at






About the Code



This plugin uses Remark Directive to convert ::pdf into a button (actually an a tag), and then processes PDF export within the component.




CODE
const activate = (): void => {
if (growiFacade == null || growiFacade.markdownRenderer == null) {
return;
}
const { optionsGenerators } = growiFacade.markdownRenderer;
const originalCustomViewOptions = optionsGenerators.customGenerateViewOptions;
optionsGenerators.customGenerateViewOptions = (...args) => {
const options = originalCustomViewOptions ? originalCustomViewOptions(...args) : optionsGenerators.generateViewOptions(...args);
// Convert Remark Directive into a button
options.remarkPlugins.push(remarkPlugin as any);
// Handle PDF export
const { a } = options.components;
options.components.a = pdfExport(a);
return options;
};

// For preview
const originalGeneratePreviewOptions = optionsGenerators.customGeneratePreviewOptions;
optionsGenerators.customGeneratePreviewOptions = (...args) => {
const preview = originalGeneratePreviewOptions ? originalGeneratePreviewOptions(...args) : optionsGenerators.generatePreviewOptions(...args);
preview.remarkPlugins.push(remarkPlugin as any);
const { a } = preview.components;
preview.components.a = pdfExport(a);
return preview;
};
};









Remark Directive Processing



Remark Directive handles the process of displaying the button at the top of the screen. A Node is added to hChildren.




CODE
export const remarkPlugin: Plugin = () => {
return (tree: Node) => {
visit(tree, 'leafDirective', (node: Node) => {
const n = node as unknown as GrowiNode;
if (n.name !== 'pdf') return;
const data = n.data || (n.data = {});
// Add a floating button to the top-right
data.hChildren = [
{
tagName: 'div',
type: 'element',
properties: { className: 'pdf-export-float-button' },
children: [
{
tagName: 'a',
type: 'element',
properties: { className: 'material-symbols-outlined me-1 grw-page-control-dropdown-icon pdf-export' },
children: [
{ type: 'text', value: 'cloud_download' },
],
},
],
},
];
});
};
};






This process adds the following DOM:




CODE
<div class="pdf-export-float-button">
<a class="material-symbols-outlined me-1 grw-page-control-dropdown-icon pdf-export">
cloud_download
</a>
</div>









Component Processing



Next, the component adds click handling to a.pdf-export.




CODE
export const pdfExport = (Tag: React.FunctionComponent<any>): React.FunctionComponent<any> => {
return ({ children, ...props }) => {
try {
// If the class is not `pdf-export`, process as a normal `a` tag
if (!props.className.split(' ').includes('pdf-export')) {
return (<a {...props}>{children}</a>);
}
// Click event
const onClick = async(e: MouseEvent) => {
};
// Add click event and return
return (
<a {...props} onClick={onClick}>{children}</a>
);
}
catch (err) {
// console.error(err);
}
// Return the original component if an error occurs
return (
<a {...props}>{children}</a>
);
};
};









Handling Button Clicks



The following is the content of the onClick function. The implementation supports multiple pages, based on






About the GROWI Community



If you have any questions or requests about using this plugin, feel free to reach out to the GROWI community. If feasible, I’ll try to accommodate your requests. There are also help channels available, so be sure to join!



Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
2 Quellen
T-Mobile will give you the iPhone 18 Pro for free – here’s how to preorder
1 Quelle
Asus: Erster Mini-Desktop mit Snapdragon X2 Elite - zu Mondpreisen
1 Quelle
Luna: Diese 11 neuen Spiele verschenkt Amazon im September 2026
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten I made a plugin that enables PDF export in GROWI.

Thematisch verwandte Begriffe: made, plugin, that, enables · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...