diff --git a/DOCS/README_18_02_2026/1.gif b/DOCS/README_18_02_2026/1.gif new file mode 100644 index 00000000..f6876083 Binary files /dev/null and b/DOCS/README_18_02_2026/1.gif differ diff --git a/DOCS/README_18_02_2026/2.gif b/DOCS/README_18_02_2026/2.gif new file mode 100644 index 00000000..21ad75dd Binary files /dev/null and b/DOCS/README_18_02_2026/2.gif differ diff --git a/DOCS/README_18_02_2026/3.gif b/DOCS/README_18_02_2026/3.gif new file mode 100644 index 00000000..981186e7 Binary files /dev/null and b/DOCS/README_18_02_2026/3.gif differ diff --git a/DOCS/README_18_02_2026/4.gif b/DOCS/README_18_02_2026/4.gif new file mode 100644 index 00000000..19ca427f Binary files /dev/null and b/DOCS/README_18_02_2026/4.gif differ diff --git a/DOCS/README_18_02_2026/5.gif b/DOCS/README_18_02_2026/5.gif new file mode 100644 index 00000000..20de9be6 Binary files /dev/null and b/DOCS/README_18_02_2026/5.gif differ diff --git a/DOCS/README_18_02_2026/6.gif b/DOCS/README_18_02_2026/6.gif new file mode 100644 index 00000000..f4964739 Binary files /dev/null and b/DOCS/README_18_02_2026/6.gif differ diff --git a/DOCS/README_18_02_2026/6_2.gif b/DOCS/README_18_02_2026/6_2.gif new file mode 100644 index 00000000..69260e7f Binary files /dev/null and b/DOCS/README_18_02_2026/6_2.gif differ diff --git a/DOCS/README_18_02_2026/7.gif b/DOCS/README_18_02_2026/7.gif new file mode 100644 index 00000000..38c712d7 Binary files /dev/null and b/DOCS/README_18_02_2026/7.gif differ diff --git a/DOCS/README_18_02_2026/8.gif b/DOCS/README_18_02_2026/8.gif new file mode 100644 index 00000000..c8a57354 Binary files /dev/null and b/DOCS/README_18_02_2026/8.gif differ diff --git a/DOCS/README_18_02_2026/Screenshot_1.png b/DOCS/README_18_02_2026/Screenshot_1.png new file mode 100644 index 00000000..be5f81ca Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_1.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_10.png b/DOCS/README_18_02_2026/Screenshot_10.png new file mode 100644 index 00000000..2543d8bc Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_10.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_2.png b/DOCS/README_18_02_2026/Screenshot_2.png new file mode 100644 index 00000000..a1bc3cb1 Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_2.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_3.png b/DOCS/README_18_02_2026/Screenshot_3.png new file mode 100644 index 00000000..15db4ccb Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_3.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_4.png b/DOCS/README_18_02_2026/Screenshot_4.png new file mode 100644 index 00000000..5d577d36 Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_4.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_5.png b/DOCS/README_18_02_2026/Screenshot_5.png new file mode 100644 index 00000000..2d9633e6 Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_5.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_6.png b/DOCS/README_18_02_2026/Screenshot_6.png new file mode 100644 index 00000000..88cb1fcc Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_6.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_6_2.png b/DOCS/README_18_02_2026/Screenshot_6_2.png new file mode 100644 index 00000000..67644904 Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_6_2.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_7.png b/DOCS/README_18_02_2026/Screenshot_7.png new file mode 100644 index 00000000..ad7d2b1d Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_7.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_8.png b/DOCS/README_18_02_2026/Screenshot_8.png new file mode 100644 index 00000000..d7a217f4 Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_8.png differ diff --git a/DOCS/README_18_02_2026/Screenshot_9.png b/DOCS/README_18_02_2026/Screenshot_9.png new file mode 100644 index 00000000..c8d3d310 Binary files /dev/null and b/DOCS/README_18_02_2026/Screenshot_9.png differ diff --git a/README.md b/README.md index 13f0cac6..6519bf85 100644 --- a/README.md +++ b/README.md @@ -1,103 +1,257 @@ -# Slicer Tutorial Maker +# Slicer Tutorial Maker -The Slicer Tutorial Maker is an extension to 3D Slicer to streamline the creation of 3D Slicer tutorials in multiple languages. The sections below provide a user guide to the tool. +The Slicer Tutorial Maker is an extension for 3D Slicer that streamlines the creation of illustrated tutorials in multiple languages. It automates screenshot capture, provides a visual annotation editor, and exports finished tutorials to HTML and Markdown formats. [Documentação em Português](https://github.com/SoniaPujolLab/SlicerTutorialMaker/blob/main/README_pt-br.md) [Documentación en español](https://github.com/SoniaPujolLab/SlicerTutorialMaker/blob/main/README_esp.md) -## Installation (Using Extension Manager) -- Install [3D Slicer 5.10.0](https://download.slicer.org/) version or [latest stable available](https://download.slicer.org/) -- Go to the "Extension Manager" and search for "TutorialMaker." -![TutorialMakenAnnotation](https://github.com/user-attachments/assets/a6060e33-34bd-444c-a230-293c580962ca) -- Click to restart to get the extension loaded -![image](https://github.com/user-attachments/assets/5b035504-fcc3-42e5-9ae3-2d45615daea7) -- Proceed to [**How to use Tutorial Maker**](#how-to-use-tutorial-maker) - -## Installation (Manually) -Follow these steps if you want to get the latest version of the extension before the preview build (which occurs in the morning ~9 EST). -### We strongly recomend to disable Developer Mode, as it uses features that are currently in development and can break during the use of the extension. - -- Install the latest [3D Slicer Stable Release](https://download.slicer.org/) or [3D Slicer Preview Release](https://download.slicer.org/) -- Open the [Tutorial Maker repository on GitHub](https://github.com/SlicerLatinAmerica/TutorialMaker) -- Clone the green button Code' and select the option 'Download ZIP' as displayed in the image below to download the file 'TutorialMaker.zip' on your computer -- Unzip the 'TutorialMaker.zip' archive to access the 'TutorialMaker-main' directory -- **Windows users** : - 1. Start 3D Slicer - 2. Drag and drop the `TutorialMaker` folder to the Slicer application window - 3. A first pop-up window, 'Select a reader,' appears. Select 'Add Python scripted modules to the application' and click OK. - 4. A second pop-up window appears to load the Tutorial Maker module. Click on 'Yes'. -![TutorialMakerInstall](https://github.com/SlicerLatinAmerica/TutorialMaker/assets/28208639/17ffda20-ee58-4e52-91c8-755655725d83) - -- **MacOs users**: - 1. Start 3D Slicer - 2. Select 'Edit' in the main menu - 3. Select 'Application settings.' - 4. A 'Parameters' window appears: select 'Modules' in the left panel - 5. Select the file 'TutoriaMaker.py.' - 6. Drag and drop the file `TutorialMaker.py` located in the sub-directory 'TutorialMaker-main/TutorialMaker/'into the field 'Additional module paths' and click on OK to restart Slicer -![TutorialMakerInstallMac](https://github.com/SlicerLatinAmerica/TutorialMaker/assets/28208639/1aad7764-0eb6-4f2e-8a5e-ba46c3cf373d) - - -## How to use Tutorial Maker - -- Select the 'Tutorial Maker' module from the 'Utilities' category in the list of modules in Slicer -![image](https://github.com/user-attachments/assets/61f70e02-fd7c-4f0b-b2ec-b190021eaf5d) +--- + +## Table of Contents + +1. [Installation: Extension Manager](#installation-extension-manager) +2. [Installation: Manual / Developer](#installation-manual--developer) +3. [How to Use Tutorial Maker](#how-to-use-tutorial-maker) + - [1. Select a Tutorial](#1-select-a-tutorial) + - [2. Capture Screenshots](#2-capture-screenshots) + - [3. Annotate Your Tutorial](#3-annotate-your-tutorial) + - [4. Generate Tutorial Output](#4-generate-tutorial-output) +4. [Annotation Tool](#annotation-tool) + - [Keyboard Shortcuts](#keyboard-shortcuts) +5. [Developer Mode](#developer-mode) +6. [Writing Tutorials](#writing-tutorials) +7. [Uninstallation](#uninstallation) + +--- + +## Installation: Extension Manager + +1. Install [3D Slicer 5.10.0](https://download.slicer.org/) or the [latest stable release](https://download.slicer.org/). +2. Open the **Extension Manager** and search for `TutorialMaker`. +

TutorialMakerAnnotation

+3. Click **Install**, then restart Slicer when prompted. +

Restart prompt

+4. Continue to [**How to Use Tutorial Maker**](#how-to-use-tutorial-maker). + +--- + +## Installation: Manual / Developer + +Follow these steps to use the latest development version before it appears in the Extension Manager build (published every morning around 9 AM EST). + +> [!WARNING] +> We strongly recommend keeping **Developer Mode disabled** unless you are actively developing the extension. Developer Mode exposes experimental features that may cause instability. + +1. Install the [3D Slicer Stable Release](https://download.slicer.org/) or [Preview Release](https://download.slicer.org/). +2. Open the [TutorialMaker repository on GitHub](https://github.com/SlicerLatinAmerica/TutorialMaker). +3. Click the green **Code** button and select **Download ZIP** to download `TutorialMaker.zip`. +4. Extract the archive to obtain the `TutorialMaker-main` directory. + +**Windows** + +1. Start 3D Slicer. +2. Drag and drop the `TutorialMaker` folder onto the Slicer application window. +3. In the **Select a reader** dialog, choose **Add Python scripted modules to the application** and click **OK**. +4. When asked to load the Tutorial Maker module, click **Yes**. + +

TutorialMakerInstall

+ +**macOS / Linux** + +1. Start 3D Slicer. +2. Go to **Edit → Application Settings → Modules**. +3. In the **Additional module paths** field, drag and drop the file `TutorialMaker.py` found inside the `TutorialMaker-main/TutorialMaker/` directory. +4. Click **OK** and restart Slicer. + +

TutorialMakerInstallMac

+ +--- + +## How to Use Tutorial Maker + +### 1. Select a Tutorial + +Open the **Tutorial Maker** module from the **Utilities** category in the Slicer module selector. + +

Module selector

+ > [!IMPORTANT] -> Before starting this tutorial, switch Slicer to Full-Screen mode and set the font size to 14pt to ensure the screenshots are easy to read. -- Select `FourMinuteTutorial` -![image](https://github.com/user-attachments/assets/33bb0de0-24e6-4edc-b807-69f593443dce) +> Before capturing screenshots, switch Slicer to **Full-Screen** mode and set the application font size to **14 pt** to ensure the screenshots are easy to read. + +Select the desired tutorial from the list, for example `FourMinuteTutorial`. + +

Tutorial list

+ +--- + +### 2. Capture Screenshots + +Click **Capture Screenshots**. A preparation dialog will appear before the capture begins. + +

Capture Screenshots: preparation dialog

+ +The **Screenshot Capture Environment Setup** dialog offers three options: + +| Option | Default | Description | +|--------|---------|-------------| +| Save current scene data | Off | Opens the Save Data dialog so you can preserve your work before the scene is cleared. | +| Maximize 3D Slicer window for screen capture | On | Ensures consistent screenshot dimensions across all slides. | +| Close Python console and Error Log window | On | Hides developer panels for cleaner screenshots. | + +> [!WARNING] +> The current scene will always be cleared before capture begins, regardless of the options chosen. + +Click **OK** to proceed. A progress dialog will track each capture step and ask you not to interact with Slicer until the capture is complete. + +

Screenshot capture progress dialog

+ +When the capture finishes, Slicer returns to the Tutorial Maker module and displays a confirmation: + +> **Screenshot Capture Completed:** *Captured Tutorial: ``* + +--- + +### 3. Annotate Your Tutorial + +After capturing screenshots, the panel shows two buttons side by side: + +| Button | Behavior | +|--------|----------| +| **Edit Annotations** | Opens the Annotator with no annotations loaded. Use this button to start annotating from scratch or to discard all previous work. | +| **Resume Annotations** | Opens the Annotator **and automatically reloads** the most recently saved `annotations.json` file for the selected tutorial. Use this button to continue work from a previous session. | -- Click `Capture screenshots` and follow the instructions to close the scene and close the Python console -![image](https://github.com/user-attachments/assets/1eac96d9-150f-416c-ba40-18730ef02ccd) +

Edit Annotations and Resume Annotations buttons

-- After capturing the tutorial, click `Edit annotations.` -![image](https://github.com/user-attachments/assets/e2d1f02c-e8d6-4620-ade8-cc8dd2d30e30) +

Resume Annotations: annotator opening with saved annotations

+ +> [!NOTE] +> **Edit Annotations** is enabled as soon as a tutorial is selected. **Resume Annotations** is only enabled when an `annotations.json` file already exists for the selected tutorial (i.e., you have saved at least once). When enabled, it restores all annotations (labels, positions, styles, slide titles and descriptions) exactly as you left them. + +--- + +### 4. Generate Tutorial Output + +After saving your annotations, click **Generate Tutorial** to produce the final HTML and Markdown files. + +

Generate Tutorial button

+ +If no annotations file is found, you will see a warning: + +> **No Annotations Found:** *You don't have any annotations to export. Please annotate your screenshots first using "Edit Annotations".* + +When generation completes successfully, Slicer opens the output folder automatically and displays a confirmation: + +> **Tutorial Generated:** *Generated Tutorial: ``* + +

Output folder opened in File Explorer

+ +

Generated HTML output in browser

+ +--- ## Annotation Tool -- The screenshots will appear on the left -![image](https://github.com/user-attachments/assets/dcabfa14-8454-4458-a32a-a2040d03ef10) +The Annotator window opens as a separate modal window. + +The thumbnail strip on the left displays all captured slides. Click any thumbnail to select it. + +

Annotator window: full layout overview

+ +**Editing slide content** + +On regular screenshot slides, you can edit the **Title** and **Description** fields at the top of the panel at any time during the annotation session. + +

Slide title and description fields

+ +Special slides (such as the **Cover Slide**) do not have Title and Description fields. Instead, they contain pre-made annotations (author, date, description, etc.) that you can select and edit directly on the slide canvas. + +

Editing cover slide premade annotations

+ +**Adding annotations** + +1. Select an annotation tool from the toolbar (Rectangle, Arrow, Text, etc.). +

Annotation toolbar

+2. Choose the annotation style (color, font size, line thickness). +

Annotation style options

+3. Click on the slide area where you want to place the annotation and type the label. +

Placing a rectangle annotation

+ +**Saving** + +Click the **Save** button in the toolbar to save annotations to `Outputs/Annotations//annotations.json` inside the extension installation folder. + +

Save button in toolbar

+ +> [!NOTE] +> When closing the Annotator, a dialog will ask whether you want to **Save**, **Discard**, or **Cancel** unsaved changes. + +**Layout customization** + +You can resize or rearrange panels by dragging the dividers. + +

Dragging panel dividers to rearrange layout

+ +--- + +### Keyboard Shortcuts + +The following keyboard shortcuts are available while the Annotator window is in focus: + +| Key | Action | +|-----|--------| +| `Del` | Deletes the selected annotation. | +| `Esc` | Deselects the current annotation without deleting it. | +| `Shift` + click | Places an annotation and **keeps the same tool active**, allowing you to add multiple annotations in quick succession without reselecting the tool. | + +

Shift+click to place multiple annotations in succession

+ +--- + +## Developer Mode + +If **Developer Mode** is enabled in Slicer (**Edit → Application Settings → Developer → Enable developer mode**), additional options will appear in the Tutorial Maker panel. + +

Developer Mode extra options

+ +- **Fetch From GitHub:** Downloads tutorial scripts directly from a curated list of external repositories. Currently disabled by default to avoid issues with GitHub API rate limits. +- **Tutorial Creation Tools:** Assists in developing new tutorials by automatically recording widget names and paths. -- Each screenshot includes a title section (green arrow) and a Comments section (red arrow) -![image](https://github.com/user-attachments/assets/de1a97a9-a5e4-4cbd-8c8b-208a9b9e0ebe) +> [!WARNING] +> Developer Mode features are experimental and may cause instability. We strongly recommend keeping Developer Mode disabled for routine tutorial creation. -- Select one of the four annotation tools -![image](https://github.com/user-attachments/assets/3b345eb6-5ac3-46c8-a87f-b2bd935173a9) +--- -- After selecting a tool, specify the style -![image](https://github.com/user-attachments/assets/62acbbba-c118-40f9-9a34-97674c64d121) +## Writing Tutorials -- Then click on the element that will receive the annotation and start typing -![image](https://github.com/user-attachments/assets/32a7de11-6dc8-4bcc-a78c-5aacc1e83087) +For guidance on developing your own tutorial scripts, follow the templates and examples available at the [SlicerTutorialMakerCollection](https://github.com/SoniaPujolLab/SlicerTutorialMakerCollection). -- After creating all annotations, click on Save file -![image](https://github.com/user-attachments/assets/983da69f-78ae-4812-afa2-7d30eeec687f) +--- -The Screenshots with Annotations are now saved in the Module folder under Outputs, inside the extension installation folder. +## Uninstallation -- Click `Generate output` to generate the MD and HTML files. -![image](https://github.com/user-attachments/assets/6422a4fa-bcac-4634-8c1c-c03b20d55aee) +### Via Extension Manager (recommended) -- You will receive a message warning you about the generation -![image](https://github.com/user-attachments/assets/4f0dd1cc-6d5f-44c6-8d9b-5579145aaa04) +1. In 3D Slicer, open **View → Extension Manager** (or the **Extensions Manager** button in the toolbar). +2. Switch to the **Installed Extensions** tab. +3. Locate **TutorialMaker** in the list. +4. Click the **Uninstall** (trash / remove) button next to the extension. +5. Restart 3D Slicer when prompted to complete the removal. -- The extension will open the folder containing the screenshots annotated, and also the HTML and MD -![image](https://github.com/user-attachments/assets/3e1b91bd-0d9f-42f6-8e47-e27ceeba72d4) +

Uninstalling via Extension Manager

-![image](https://github.com/user-attachments/assets/a7201cae-30b6-4ddd-8e4f-cd60079ba9a7) +### Manual removal (developer / source installation) -You can also change the layout from the annotator, dragging the menus. -![dg](https://github.com/user-attachments/assets/b4269d5d-7c37-43f1-9e2e-f90d8aacb730) +If you installed the extension by adding it to the **Additional module paths**, follow these steps: -It's possible to change the slide title and descriptions -![dg2](https://github.com/user-attachments/assets/a0264344-6c3d-403d-ae49-db8b30507623) +1. Open **Edit → Application Settings → Modules**. +2. In the **Additional module paths** list, select the entry pointing to the `TutorialMaker` folder (or `TutorialMaker.py`). +3. Click the **Remove** (minus) button to delete the path entry. +4. Click **OK** and restart 3D Slicer. +5. After restarting, you can safely delete the `TutorialMaker-main` directory from your file system. -## Developer mode -- If you have enabled developer mode (Edit > Application Settings > Developer > Enable developer mode) in Slicer, you may notice additional options within the extension. These represent experimental features and unstable processes currently undergoing test -![image](https://github.com/user-attachments/assets/ce9478fa-e195-4cc8-b2ef-f90b3d4c9ed1) +> [!NOTE] +> Removing the module path only unregisters the extension in Slicer. You must manually delete the source folder from disk to remove all files. -- The Fetch From GitHub feature allows users to download tutorials directly from a curated list of external repositories. Currently, this feature is disabled to prevent issues regarding GitHub API rate limits. -- .Tutorial Creation Tools: These features assist in developing new tutorials by allowing you to record widget names and paths automatically. +**Removing generated output files** -## Writing tutorials -- For guidance on developing your own tutorials, please follow the template and examples hosted at the SlicerTutorialMakerCollection (https://github.com/SoniaPujolLab/SlicerTutorialMakerCollection). +Tutorial output files (screenshots, annotations, HTML and Markdown) are stored inside the extension installation folder under `TutorialMaker/Outputs/`. These files are not removed automatically. Delete the `Outputs/` directory manually if you no longer need them. diff --git a/README_esp.md b/README_esp.md index 170999fb..05986dcf 100644 --- a/README_esp.md +++ b/README_esp.md @@ -1,109 +1,257 @@ -# Tutorial Maker -Tutorial Maker es una extensión de 3D Slicer para agilizar la creación de tutoriales de 3D Slicer en multiples lenguajes. Las secciones siguientes proporcionan una guia de usuario de la herramienta. +# Slicer Tutorial Maker -## Instalación (Mediante el Manejador de Extensiones) +Slicer Tutorial Maker es una extensión para 3D Slicer que facilita la creación de tutoriales ilustrados en múltiples idiomas. Automatiza la captura de pantallas, ofrece un editor visual de anotaciones y exporta los tutoriales finalizados en formatos HTML y Markdown. -- Instale [3D Slicer versión 5.10.0](https://download.slicer.org) o [última versión estable de 3D Slicer](https://download.slicer.org) -- Abra el "Manejador de Extensiones" y coloca en el buscador "TutorialMaker". -![extensionmanager](https://github.com/user-attachments/assets/64c8e84d-688c-476a-bd35-728338b592af) +[English Documentation](https://github.com/SoniaPujolLab/SlicerTutorialMaker/blob/main/README.md) +[Documentação em Português](https://github.com/SoniaPujolLab/SlicerTutorialMaker/blob/main/README_pt-br.md) -- Instala la extensión, cuando termine la instalación haga clic para reiniciar 3D Slicer para cargar la extensión. -Captura de pantalla 2026-02-02 a la(s) 11 42 15 +--- -- Continua a [**Como usar TutorialMaker**](#cómo-utilizar-tutorial-maker) +## Tabla de Contenidos -## Instalación (Manual) +1. [Instalación: Manejador de Extensiones](#instalación-manejador-de-extensiones) +2. [Instalación: Manual / Desarrollador](#instalación-manual--desarrollador) +3. [Cómo Usar Tutorial Maker](#cómo-usar-tutorial-maker) + - [1. Seleccionar un Tutorial](#1-seleccionar-un-tutorial) + - [2. Capturar Pantallas](#2-capturar-pantallas) + - [3. Anotar el Tutorial](#3-anotar-el-tutorial) + - [4. Generar el Tutorial](#4-generar-el-tutorial) +4. [Herramienta de Anotación](#herramienta-de-anotación) + - [Atajos de Teclado](#atajos-de-teclado) +5. [Modo Desarrollador](#modo-desarrollador) +6. [Escribir Tutoriales](#escribir-tutoriales) +7. [Desinstalación](#desinstalación) -Siga estos pasos si desea obtener la última versión de la extensión antes de la compilación preliminar (que se realiza por la mañana aproximadamente a las 9 EST). +--- -### Recomendamos encarecidamente desactivar el modo de desarrollador, ya que utiliza funciones que actualmente están en desarrollo y pueden fallar durante el uso de la extensión. +## Instalación: Manejador de Extensiones -- Instale [3D Slicer versión 5.10.0](https://download.slicer.org) o [última versión estable de 3D Slicer](https://download.slicer.org) -- Abra el repositorio [Tutorial Maker](https://github.com/SoniaPujolLab/SlicerTutorialMaker/tree/main) en GitHub -- Clone el botón verde “Código” y seleccione la opción “Descargar ZIP” como se muestra en la imagen de abajo para descargar el archivo “TutorialMaker.zip” en su computadora. -![image](DOCS/Img_es/DescargarRepo.png) -- Descomprima el archivo “TutorialMaker.zip” para acceder al directorio “TutorialMaker-main” +1. Instale [3D Slicer 5.10.0](https://download.slicer.org/) o la [versión estable más reciente](https://download.slicer.org/). +2. Abra el **Manejador de Extensiones** y busque `TutorialMaker`. +

TutorialMakerAnnotation

+3. Haga clic en **Instalar** y reinicie Slicer cuando se le solicite. +

Restart prompt

+4. Continúe en [**Cómo Usar Tutorial Maker**](#cómo-usar-tutorial-maker). -- **Para usuarios de Windows**: - 1. Inicie 3D Slicer. - 2. Arrastre y suelte la carpeta “TutorialMaker” en la ventana de la aplicación de Slicer. - 3. Aparecerá una primera ventana emergente, “Seleccionar un lector”. Seleccione “Añadir módulos de scripting Python a la aplicación” y haga clic en OK. - 4. Aparece una segunda ventana emergente para cargar el módulo Tutorial Maker. Haga clic en “Sí”. - ![image](DOCS/Img_es/InstalarWindows.gif) +--- -- **Para usuarios de MacOs**: - 1. Inicie 3D Slicer. - 2. Seleccione “Editar” en el menú principal. - 3. Seleccione “Parámetros de la aplicación”. - 4. Aparecerá una ventana de “Parámetro”': seleccione “Módulos” en el panel izquierdo. - 5. Seleccione el archivo 'TutoriaMaker.py'. - 6. Arrastre y suelte el archivo TutorialMaker.py situado en el subdirectorio TutorialMaker-main/TutorialMaker/'en el campo “Rutas de módulos adicionales” y haga clic en OK para reiniciar Slicer. - ![add](https://github.com/user-attachments/assets/521e3d1e-ac14-4f63-9947-2e2c69cdc879) +## Instalación: Manual / Desarrollador +Siga estos pasos para usar la versión de desarrollo más reciente antes de que aparezca en el build del Manejador de Extensiones (publicado cada mañana alrededor de las 9 AM EST). -## Cómo utilizar Tutorial Maker +> [!WARNING] +> Recomendamos encarecidamente mantener el **Modo Desarrollador desactivado** a menos que esté desarrollando activamente la extensión. El Modo Desarrollador expone funciones experimentales que pueden causar inestabilidad. -- Seleccione el módulo “Tutorial Maker” en la categoría “Utilidades” de la lista de módulos de Slicer. -Captura de pantalla 2026-02-02 a la(s) 12 02 04 +1. Instale el [3D Slicer Stable Release](https://download.slicer.org/) o el [Preview Release](https://download.slicer.org/). +2. Abra el [repositorio TutorialMaker en GitHub](https://github.com/SlicerLatinAmerica/TutorialMaker). +3. Haga clic en el botón verde **Code** y seleccione **Download ZIP** para descargar `TutorialMaker.zip`. +4. Extraiga el archivo para obtener el directorio `TutorialMaker-main`. -> [!ADVERTENCIA] -> Antes de empezar este tutorial, cambie Slicer al modo de pantalla completa y ajuste el tamaño de la fuente a 14pt para asegurarse de que las capturas de pantalla son fáciles de leer. +**Windows** -- Seleccione `fourMin_tutorial` -Captura de pantalla 2026-02-02 a la(s) 12 04 07 +1. Inicie 3D Slicer. +2. Arrastre y suelte la carpeta `TutorialMaker` en la ventana de la aplicación Slicer. +3. En el diálogo **Select a reader**, elija **Add Python scripted modules to the application** y haga clic en **OK**. +4. Cuando se le pregunte si desea cargar el módulo Tutorial Maker, haga clic en **Yes**. -- Dé click en `Capture Screenshots` y siga las instrucciones para cerrar la escena y cerrar la consola de Python -Captura de pantalla 2026-02-02 a la(s) 12 04 27 -Captura de pantalla 2026-02-02 a la(s) 12 05 11 +

TutorialMakerInstall

-- Después de capturar el tutorial, haz clic en `Edit annotations`. -Captura de pantalla 2026-02-02 a la(s) 12 08 45 +**macOS / Linux** -### Herramienta de anotaciones +1. Inicie 3D Slicer. +2. Vaya a **Edit → Application Settings → Modules**. +3. En el campo **Additional module paths**, arrastre y suelte el archivo `TutorialMaker.py` ubicado dentro del directorio `TutorialMaker-main/TutorialMaker/`. +4. Haga clic en **OK** y reinicie Slicer. -- Las capturas de pantalla aparecerán a la izquierda. -Captura de pantalla 2026-02-02 a la(s) 12 11 16 +

TutorialMakerInstallMac

-- Cada captura de pantalla tiene un título (flecha verde) y un comentario (flecha roja). -Copia de Captura de pantalla 2026-02-02 a la(s) 12 11 16 +--- -- Seleccione una de las cuatro herramientas de anotación. -Copia de Captura de pantalla 2026-02-02 a la(s) 12 11 16 2 +## Cómo Usar Tutorial Maker -- Después de seleccionar una herramienta, especifique el estilo. -Copia de Captura de pantalla 2026-02-02 a la(s) 12 11 16 3 +### 1. Seleccionar un Tutorial -- A continuación, haga clic en el elemento que recibirá la anotación y empieza a escribir. -Captura de pantalla 2026-02-02 a la(s) 12 12 17 +Abra el módulo **Tutorial Maker** desde la categoría **Utilities** en el selector de módulos de Slicer. -- Después de crear todas las anotaciones, haz clic en `Save File`. -Copia de Captura de pantalla 2026-02-02 a la(s) 12 12 17 +

Module selector

-Las capturas de pantalla con anotaciones ahora se guardan en la carpeta Módulo en Salidas, dentro de la carpeta de instalación de la extensión. +> [!IMPORTANT] +> Antes de capturar pantallas, cambie Slicer al modo **Pantalla Completa** y ajuste el tamaño de fuente de la aplicación a **14 pt** para que las capturas sean fáciles de leer. -- Presiona en `Generate Tutorial` para generar los archivos MD y HTML. -Captura de pantalla 2026-02-02 a la(s) 12 22 53 +Seleccione el tutorial deseado de la lista, por ejemplo `FourMinuteTutorial`. -- Recibiras un mensaje que te avisa que los archivos se han generado. -Captura de pantalla 2026-02-02 a la(s) 12 24 49 +

Tutorial list

-- La extensión abrirá la carpeta que contiene las capturas de pantalla anotadas, y también el HTML y MD. -Captura de pantalla 2026-02-02 a la(s) 12 26 06 -Captura de pantalla 2026-02-02 a la(s) 12 30 07 +--- -- También puedes cambiar el diseño desde el anotador, arrastrando los menús. -![Grabación de pantalla 2026-02-02 a la(s) 12 30 55](https://github.com/user-attachments/assets/e1876f90-ce1d-4aec-8d9c-d6c8b66ab70e) +### 2. Capturar Pantallas -- Es posible cambiar el título y las descripciones de las diapositivas. -![Grabación de pantalla 2026-02-02 a la(s) 12 45 31](https://github.com/user-attachments/assets/14d62dc8-6875-41e8-a2ce-5850762872aa) +Haga clic en **Capture Screenshots**. Aparecerá un diálogo de preparación antes de que comience la captura. -## Modo de Desarrollador -- Si ha habilitado el modo de desarrollador (Editar > Configuración de la aplicación > Desarrollador > Habilitar modo de desarrollador) en Slicer, es posible que observe opciones adicionales dentro de la extensión. Estas representan funciones experimentales y procesos inestables que se encuentran actualmente en fase de prueba. -Captura de pantalla 2026-02-02 a la(s) 12 52 39 +

Capture Screenshots: preparation dialog

-- La función "Obtener de GitHub" permite a los usuarios descargar tutoriales directamente desde una lista seleccionada de repositorios externos. Actualmente, esta función está deshabilitada para evitar problemas relacionados con los límites de velocidad de la API de GitHub. +El diálogo **Screenshot Capture Environment Setup** ofrece tres opciones: -- Herramientas de creación de tutoriales: Estas funciones facilitan el desarrollo de nuevos tutoriales, ya que permiten registrar automáticamente los nombres y las rutas de los widgets. +| Opción | Valor por defecto | Descripción | +|--------|-------------------|-------------| +| Save current scene data | Desactivado | Abre el diálogo Guardar Datos para que pueda conservar su trabajo antes de que se limpie la escena. | +| Maximize 3D Slicer window for screen capture | Activado | Garantiza dimensiones de captura consistentes en todas las diapositivas. | +| Close Python console and Error Log window | Activado | Oculta paneles de desarrollador para capturas más limpias. | -### Escribir tutoriales -- Para obtener orientación sobre el desarrollo de sus propios tutoriales, siga la plantilla y los ejemplos alojados en SlicerTestRepository (https://github.com/SoniaPujolLab/SlicerTestTutorial) +> [!WARNING] +> La escena actual siempre se limpiará antes de que comience la captura, independientemente de las opciones elegidas. + +Haga clic en **OK** para continuar. Un diálogo de progreso seguirá cada paso de la captura y mostrará un mensaje pidiéndole que no interactúe con Slicer hasta que finalice. + +

Screenshot capture progress dialog

+ +Cuando la captura finalice, Slicer regresa al módulo Tutorial Maker y muestra una confirmación: + +> **Screenshot Capture Completed:** *Captured Tutorial: ``* + +--- + +### 3. Anotar el Tutorial + +Después de capturar las pantallas, el panel muestra dos botones uno junto al otro: + +| Botón | Comportamiento | +|-------|----------------| +| **Edit Annotations** | Abre el Anotador sin anotaciones cargadas. Use este botón para empezar a anotar desde cero o para descartar completamente el trabajo anterior. | +| **Resume Annotations** | Abre el Anotador **y recarga automáticamente** el archivo `annotations.json` guardado más recientemente para el tutorial seleccionado. Use este botón para continuar el trabajo iniciado en una sesión anterior. | + +

Edit Annotations and Resume Annotations buttons

+ +

Resume Annotations: annotator opening with saved annotations

+ +> [!NOTE] +> **Edit Annotations** se habilita en cuanto se selecciona un tutorial. **Resume Annotations** solo se habilita cuando ya existe un archivo `annotations.json` para el tutorial seleccionado (es decir, ha guardado al menos una vez). Una vez habilitado, restaura todas las anotaciones (etiquetas, posiciones, estilos, títulos y descripciones de diapositivas) exactamente como las dejó. + +--- + +### 4. Generar el Tutorial + +Después de guardar sus anotaciones, haga clic en **Generate Tutorial** para producir los archivos HTML y Markdown finales. + +

Generate Tutorial button

+ +Si no se encuentra ningún archivo de anotaciones, verá una advertencia: + +> **No Annotations Found:** *You don't have any annotations to export. Please annotate your screenshots first using "Edit Annotations".* + +Una vez que la generación sea exitosa, Slicer abre la carpeta de salida automáticamente y muestra una confirmación: + +> **Tutorial Generated:** *Generated Tutorial: ``* + +

Output folder opened in File Explorer

+ +

Generated HTML output in browser

+ +--- + +## Herramienta de Anotación + +La ventana del Anotador se abre como una ventana modal separada. + +La tira de miniaturas a la izquierda muestra todas las diapositivas capturadas. Haga clic en cualquier miniatura para seleccionarla. + +

Annotator window: full layout overview

+ +**Editar el contenido de las diapositivas** + +En las diapositivas de captura de pantalla normales, puede editar los campos **Title** y **Description** en la parte superior del panel en cualquier momento durante la sesión de anotación. + +

Slide title and description fields

+ +Las diapositivas especiales (como la **Cover Slide**) no tienen campos de Título y Descripción. En cambio, contienen anotaciones predefinidas (autor, fecha, descripción, etc.) que puede seleccionar y editar directamente en el lienzo de la diapositiva. + +

Editing cover slide premade annotations

+ +**Agregar anotaciones** + +1. Seleccione una herramienta de anotación en la barra de herramientas (Rectángulo, Flecha, Texto, etc.). +

Annotation toolbar

+2. Elija el estilo de la anotación (color, tamaño de fuente, grosor de línea). +

Annotation style options

+3. Haga clic en el área de la diapositiva donde desea colocar la anotación y escriba la etiqueta. +

Placing a rectangle annotation

+ +**Guardar** + +Haga clic en el botón **Save** en la barra de herramientas para guardar las anotaciones en `Outputs/Annotations//annotations.json` dentro de la carpeta de instalación de la extensión. + +

Save button in toolbar

+ +> [!NOTE] +> Al cerrar el Anotador, un diálogo le preguntará si desea **Guardar**, **Descartar** o **Cancelar** los cambios no guardados. + +**Personalización del diseño** + +Puede redimensionar o reorganizar los paneles arrastrando los divisores. + +

Dragging panel dividers to rearrange layout

+ +--- + +### Atajos de Teclado + +Los siguientes atajos de teclado están disponibles mientras la ventana del Anotador está enfocada: + +| Tecla | Acción | +|-------|--------| +| `Del` | Elimina la anotación seleccionada. | +| `Esc` | Deselecciona la anotación actual sin eliminarla. | +| `Shift` + clic | Coloca una anotación y **mantiene la misma herramienta activa**, permitiendo agregar múltiples anotaciones en rápida sucesión sin tener que volver a seleccionar la herramienta. | + +

Shift+click to place multiple annotations in succession

+ +--- + +## Modo Desarrollador + +Si el **Modo Desarrollador** está habilitado en Slicer (**Edit → Application Settings → Developer → Enable developer mode**), aparecerán opciones adicionales en el panel de Tutorial Maker. + +

Developer Mode extra options

+ +- **Fetch From GitHub:** Descarga scripts de tutoriales directamente desde una lista curada de repositorios externos. Actualmente desactivado por defecto para evitar problemas con los límites de la API de GitHub. +- **Tutorial Creation Tools:** Ayuda en el desarrollo de nuevos tutoriales registrando automáticamente nombres y rutas de widgets. + +> [!WARNING] +> Las funciones del Modo Desarrollador son experimentales y pueden causar inestabilidad. Recomendamos encarecidamente mantener el Modo Desarrollador desactivado para la creación rutinaria de tutoriales. + +--- + +## Escribir Tutoriales + +Para orientación sobre cómo crear sus propios scripts de tutorial, siga las plantillas y ejemplos disponibles en la [SlicerTutorialMakerCollection](https://github.com/SoniaPujolLab/SlicerTutorialMakerCollection). + +--- + +## Desinstalación + +### Mediante el Manejador de Extensiones (recomendado) + +1. En 3D Slicer, abra **View → Extension Manager** (o el botón **Extensions Manager** en la barra de herramientas). +2. Cambie a la pestaña **Installed Extensions**. +3. Localice **TutorialMaker** en la lista. +4. Haga clic en el botón **Uninstall** (papelera / eliminar) junto a la extensión. +5. Reinicie 3D Slicer cuando se le solicite para completar la eliminación. + +

Uninstalling via Extension Manager

+ +### Eliminación manual (instalación por desarrollador / código fuente) + +Si instaló la extensión agregándola a los **Additional module paths**, siga estos pasos: + +1. Abra **Edit → Application Settings → Modules**. +2. En la lista **Additional module paths**, seleccione la entrada que apunta a la carpeta `TutorialMaker` (o `TutorialMaker.py`). +3. Haga clic en el botón **Remove** (menos) para eliminar la entrada de la ruta. +4. Haga clic en **OK** y reinicie 3D Slicer. +5. Después de reiniciar, puede eliminar con seguridad el directorio `TutorialMaker-main` de su sistema de archivos. + +> [!NOTE] +> Eliminar la ruta del módulo solo cancela el registro de la extensión en Slicer. Debe eliminar manualmente la carpeta fuente del disco para remover todos los archivos. + +**Eliminar archivos de salida generados** + +Los archivos de salida de los tutoriales (capturas de pantalla, anotaciones, HTML y Markdown) se almacenan dentro de la carpeta de instalación de la extensión en `TutorialMaker/Outputs/`. Estos archivos no se eliminan automáticamente. Elimine el directorio `Outputs/` manualmente si ya no los necesita. diff --git a/README_pt-br.md b/README_pt-br.md index 2608b117..17f022b6 100644 --- a/README_pt-br.md +++ b/README_pt-br.md @@ -1,105 +1,257 @@ -# Slicer Tutorial Maker +# Slicer Tutorial Maker -O Slicer Tutorial Maker é uma extensão para o 3D Slicer para agilizar a criação de tutoriais do 3D Slicer em vários idiomas. As seções abaixo fornecem um guia do usuário para a ferramenta. +O Slicer Tutorial Maker é uma extensão para o 3D Slicer que facilita a criação de tutoriais ilustrados em múltiplos idiomas. Ele automatiza a captura de capturas de tela, oferece um editor visual de anotações e exporta os tutoriais finalizados nos formatos HTML e Markdown. [English Documentation](https://github.com/SoniaPujolLab/SlicerTutorialMaker/blob/main/README.md) [Documentación en español](https://github.com/SoniaPujolLab/SlicerTutorialMaker/blob/main/README_esp.md) -## Instalação (Usando o Gerenciador de Extensões) -- Instale a versão [3D Slicer 5.10.0](https://download.slicer.org/) ou a [versão estável mais recente disponível](https://download.slicer.org/) -- Vá para o "Extension Manager" (Gerenciador de Extensões) e procure por "TutorialMaker". -![TutorialMakenAnnotation](https://github.com/user-attachments/assets/a6060e33-34bd-444c-a230-293c580962ca) -- Clique para reiniciar e carregar a extensão -![image](https://github.com/user-attachments/assets/5b035504-fcc3-42e5-9ae3-2d45615daea7) -- Prossiga para [**Como usar o Tutorial Maker**](#como-usar-o-tutorial-maker) - -## Instalação (Manualmente) -Siga estas etapas se quiser obter a versão mais recente da extensão antes da compilação de pré-visualização (que ocorre pela manhã ~9 EST). -### Recomendamos fortemente desabilitar o Modo Desenvolvedor, pois ele usa recursos que estão atualmente em desenvolvimento e podem quebrar durante o uso da extensão. - -- Instale a versão estável mais recente do [3D Slicer Stable Release](https://download.slicer.org/) ou a versão de pré-visualização [3D Slicer Preview Release](https://download.slicer.org/) -- Abra o [repositório do Tutorial Maker no GitHub](https://github.com/SlicerLatinAmerica/TutorialMaker) -- Clique no botão verde 'Code' e selecione a opção 'Download ZIP' conforme exibido na imagem abaixo para baixar o arquivo 'TutorialMaker.zip' no seu computador -- Descompacte o arquivo 'TutorialMaker.zip' para acessar o diretório 'TutorialMaker-main' -- **Usuários Windows** : - 1. Inicie o 3D Slicer - 2. Arraste e solte a pasta `TutorialMaker` para a janela do aplicativo Slicer - 3. Uma primeira janela pop-up, 'Select a reader' (Selecionar um leitor), aparece. Selecione 'Add Python scripted modules to the application' (Adicionar módulos de script Python ao aplicativo) e clique em OK. - 4. Uma segunda janela pop-up aparece para carregar o módulo Tutorial Maker. Clique em 'Yes' (Sim). -![TutorialMakerInstall](https://github.com/SlicerLatinAmerica/TutorialMaker/assets/28208639/17ffda20-ee58-4e52-91c8-755655725d83) - -- **Usuários MacOs**: - 1. Inicie o 3D Slicer - 2. Selecione 'Edit' (Editar) no menu principal - 3. Selecione 'Application settings' (Configurações do aplicativo). - 4. Uma janela 'Parameters' (Parâmetros) aparece: selecione 'Modules' (Módulos) no painel esquerdo - 5. Selecione o arquivo 'TutoriaMaker.py.' - 6. Arraste e solte o arquivo `TutorialMaker.py` localizado no subdiretório 'TutorialMaker-main/TutorialMaker/' no campo 'Additional module paths' (Caminhos adicionais de módulos) e clique em OK para reiniciar o Slicer -![TutorialMakerInstallMac](https://github.com/SlicerLatinAmerica/TutorialMaker/assets/28208639/1aad7764-0eb6-4f2e-8a5e-ba46c3cf373d) - - -## Como usar o Tutorial Maker - -- Selecione o módulo 'Tutorial Maker' da categoria 'Utilities' (Utilitários) na lista de módulos no Slicer -![image](https://github.com/user-attachments/assets/61f70e02-fd7c-4f0b-b2ec-b190021eaf5d) +--- + +## Sumário + +1. [Instalação: Gerenciador de Extensões](#instalação-gerenciador-de-extensões) +2. [Instalação: Manual / Desenvolvedor](#instalação-manual--desenvolvedor) +3. [Como Usar o Tutorial Maker](#como-usar-o-tutorial-maker) + - [1. Selecionar um Tutorial](#1-selecionar-um-tutorial) + - [2. Capturar Capturas de Tela](#2-capturar-capturas-de-tela) + - [3. Anotar o Tutorial](#3-anotar-o-tutorial) + - [4. Gerar o Tutorial](#4-gerar-o-tutorial) +4. [Ferramenta de Anotação](#ferramenta-de-anotação) + - [Atalhos de Teclado](#atalhos-de-teclado) +5. [Modo Desenvolvedor](#modo-desenvolvedor) +6. [Escrevendo Tutoriais](#escrevendo-tutoriais) +7. [Desinstalação](#desinstalação) + +--- + +## Instalação: Gerenciador de Extensões + +1. Instale o [3D Slicer 5.10.0](https://download.slicer.org/) ou a [versão estável mais recente](https://download.slicer.org/). +2. Abra o **Gerenciador de Extensões** e pesquise por `TutorialMaker`. +

TutorialMakerAnnotation

+3. Clique em **Instalar** e reinicie o Slicer quando solicitado. +

Restart prompt

+4. Prossiga para [**Como Usar o Tutorial Maker**](#como-usar-o-tutorial-maker). + +--- + +## Instalação: Manual / Desenvolvedor + +Siga estas etapas para usar a versão de desenvolvimento mais recente antes que ela apareça no build do Gerenciador de Extensões (publicado todas as manhãs por volta das 9h EST). + +> [!WARNING] +> Recomendamos fortemente manter o **Modo Desenvolvedor desativado**, a menos que você esteja desenvolvendo ativamente a extensão. O Modo Desenvolvedor expõe funcionalidades experimentais que podem causar instabilidade. + +1. Instale o [3D Slicer Stable Release](https://download.slicer.org/) ou o [Preview Release](https://download.slicer.org/). +2. Abra o [repositório TutorialMaker no GitHub](https://github.com/SlicerLatinAmerica/TutorialMaker). +3. Clique no botão verde **Code** e selecione **Download ZIP** para baixar o arquivo `TutorialMaker.zip`. +4. Extraia o arquivo para obter o diretório `TutorialMaker-main`. + +**Windows** + +1. Inicie o 3D Slicer. +2. Arraste e solte a pasta `TutorialMaker` na janela do aplicativo Slicer. +3. Na janela **Select a reader**, escolha **Add Python scripted modules to the application** e clique em **OK**. +4. Quando perguntado sobre carregar o módulo Tutorial Maker, clique em **Yes**. + +

TutorialMakerInstall

+ +**macOS / Linux** + +1. Inicie o 3D Slicer. +2. Acesse **Edit → Application Settings → Modules**. +3. No campo **Additional module paths**, arraste e solte o arquivo `TutorialMaker.py` localizado dentro do diretório `TutorialMaker-main/TutorialMaker/`. +4. Clique em **OK** e reinicie o Slicer. + +

TutorialMakerInstallMac

+ +--- + +## Como Usar o Tutorial Maker + +### 1. Selecionar um Tutorial + +Abra o módulo **Tutorial Maker** na categoria **Utilities** no seletor de módulos do Slicer. + +

Module selector

> [!IMPORTANT] -> Antes de iniciar este tutorial, alterne o Slicer para o modo Tela Cheia e defina o tamanho da fonte para 14pt para garantir que as capturas de tela sejam fáceis de ler. +> Antes de capturar as capturas de tela, alterne o Slicer para o modo **Tela Cheia** e defina o tamanho da fonte do aplicativo para **14 pt** para garantir que as capturas de tela sejam fáceis de ler. + +Selecione o tutorial desejado na lista, por exemplo `FourMinuteTutorial`. + +

Tutorial list

+ +--- + +### 2. Capturar Capturas de Tela + +Clique em **Capture Screenshots**. Um diálogo de preparação será exibido antes do início da captura. + +

Capture Screenshots: preparation dialog

+ +O diálogo **Screenshot Capture Environment Setup** oferece três opções: + +| Opção | Padrão | Descrição | +|-------|--------|-----------| +| Save current scene data | Desativado | Abre o diálogo Salvar Dados para que você possa preservar seu trabalho antes de a cena ser limpa. | +| Maximize 3D Slicer window for screen capture | Ativado | Garante dimensões de captura de tela consistentes em todos os slides. | +| Close Python console and Error Log window | Ativado | Oculta painéis de desenvolvedor para capturas de tela mais limpas. | + +> [!WARNING] +> A cena atual sempre será limpa antes do início da captura, independentemente das opções escolhidas. + +Clique em **OK** para prosseguir. Um diálogo de progresso acompanhará cada etapa da captura e exibirá uma mensagem pedindo para não interagir com o Slicer até que a captura seja concluída. + +

Screenshot capture progress dialog

+ +Quando a captura for concluída, o Slicer retorna ao módulo Tutorial Maker e exibe uma confirmação: + +> **Screenshot Capture Completed:** *Captured Tutorial: ``* + +--- + +### 3. Anotar o Tutorial + +Após capturar as capturas de tela, o painel exibe dois botões lado a lado: + +| Botão | Comportamento | +|-------|---------------| +| **Edit Annotations** | Abre o Anotador sem anotações carregadas. Use este botão para começar a anotar do zero ou para descartar completamente o trabalho anterior. | +| **Resume Annotations** | Abre o Anotador **e recarrega automaticamente** o arquivo `annotations.json` salvo mais recentemente para o tutorial selecionado. Use este botão para continuar o trabalho iniciado em uma sessão anterior. | -- Selecione `FourMinuteTutorial` -![image](https://github.com/user-attachments/assets/33bb0de0-24e6-4edc-b807-69f593443dce) +

Edit Annotations and Resume Annotations buttons

-- Clique em `Capture screenshots` (Capturar capturas de tela) e siga as instruções para fechar a cena e fechar o console Python -![image](https://github.com/user-attachments/assets/1eac96d9-150f-416c-ba40-18730ef02ccd) +

Resume Annotations: annotator opening with saved annotations

-- Após capturar o tutorial, clique em `Edit annotations` (Editar anotações). -![image](https://github.com/user-attachments/assets/e2d1f02c-e8d6-4620-ade8-cc8dd2d30e30) +> [!NOTE] +> **Edit Annotations** é habilitado assim que um tutorial é selecionado. **Resume Annotations** só é habilitado quando já existe um arquivo `annotations.json` para o tutorial selecionado (ou seja, você salvou ao menos uma vez). Quando habilitado, ele restaura todas as anotações (rótulos, posições, estilos, títulos e descrições dos slides) exatamente como você deixou. + +--- + +### 4. Gerar o Tutorial + +Após salvar suas anotações, clique em **Generate Tutorial** para produzir os arquivos HTML e Markdown finais. + +

Generate Tutorial button

+ +Se nenhum arquivo de anotações for encontrado, você verá um aviso: + +> **No Annotations Found:** *You don't have any annotations to export. Please annotate your screenshots first using "Edit Annotations".* + +Quando a geração for concluída com sucesso, o Slicer abre a pasta de saída automaticamente e exibe uma confirmação: + +> **Tutorial Generated:** *Generated Tutorial: ``* + +

Output folder opened in File Explorer

+ +

Generated HTML output in browser

+ +--- ## Ferramenta de Anotação -- As capturas de tela aparecerão à esquerda -![image](https://github.com/user-attachments/assets/dcabfa14-8454-4458-a32a-a2040d03ef10) +A janela do Anotador é aberta como uma janela modal separada. + +A faixa de miniaturas à esquerda exibe todos os slides capturados. Clique em qualquer miniatura para selecioná-la. + +

Annotator window: full layout overview

+ +**Editando o conteúdo dos slides** + +Nos slides de captura de tela normais, você pode editar os campos **Title** e **Description** no topo do painel a qualquer momento durante a sessão de anotação. + +

Slide title and description fields

+ +Slides especiais (como o **Cover Slide**) não possuem campos de Título e Descrição. Em vez disso, eles contêm anotações pré-definidas (autor, data, descrição, etc.) que você pode selecionar e editar diretamente no canvas do slide. + +

Editing cover slide premade annotations

+ +**Adicionando anotações** -- Cada captura de tela inclui uma seção de título (seta verde) e uma seção de Comentários (seta vermelha) -![image](https://github.com/user-attachments/assets/de1a97a9-a5e4-4cbd-8c8b-208a9b9e0ebe) +1. Selecione uma ferramenta de anotação na barra de ferramentas (Retângulo, Seta, Texto, etc.). +

Annotation toolbar

+2. Escolha o estilo da anotação (cor, tamanho da fonte, espessura da linha). +

Annotation style options

+3. Clique na área do slide onde deseja colocar a anotação e digite o rótulo. +

Placing a rectangle annotation

-- Selecione uma das quatro ferramentas de anotação -![image](https://github.com/user-attachments/assets/3b345eb6-5ac3-46c8-a87f-b2bd935173a9) +**Salvando** -- Após selecionar uma ferramenta, especifique o estilo -![image](https://github.com/user-attachments/assets/62acbbba-c118-40f9-9a34-97674c64d121) +Clique no botão **Save** na barra de ferramentas para salvar as anotações em `Outputs/Annotations//annotations.json` dentro da pasta de instalação da extensão. -- Em seguida, clique no elemento que receberá a anotação e comece a digitar -![image](https://github.com/user-attachments/assets/32a7de11-6dc8-4bcc-a78c-5aacc1e83087) +

Save button in toolbar

-- Após criar todas as anotações, clique em Save file (Salvar arquivo) -![image](https://github.com/user-attachments/assets/983da69f-78ae-4812-afa2-7d30eeec687f) +> [!NOTE] +> Ao fechar o Anotador, um diálogo perguntará se você deseja **Salvar**, **Descartar** ou **Cancelar** as alterações não salvas. -As Capturas de Tela com Anotações são salvas agora na pasta do Módulo em Outputs, dentro da pasta de instalação da extensão. +**Personalização do layout** -- Clique em `Generate output` (Gerar saída) para gerar os arquivos MD e HTML. -![image](https://github.com/user-attachments/assets/6422a4fa-bcac-4634-8c1c-c03b20d55aee) +Você pode redimensionar ou reorganizar os painéis arrastando os divisores. -- Você receberá uma mensagem avisando sobre a geração -![image](https://github.com/user-attachments/assets/4f0dd1cc-6d5f-44c6-8d9b-5579145aaa04) +

Dragging panel dividers to rearrange layout

-- A extensão abrirá a pasta contendo as capturas de tela anotadas, e também o HTML e MD -![image](https://github.com/user-attachments/assets/3e1b91bd-0d9f-42f6-8e47-e27ceeba72d4) +--- -![image](https://github.com/user-attachments/assets/a7201cae-30b6-4ddd-8e4f-cd60079ba9a7) +### Atalhos de Teclado -Você também pode alterar o layout do anotador, arrastando os menus. -![dg](https://github.com/user-attachments/assets/b4269d5d-7c37-43f1-9e2e-f90d8aacb730) +Os seguintes atalhos de teclado estão disponíveis enquanto a janela do Anotador estiver em foco: -É possível alterar o título e as descrições do slide -![dg2](https://github.com/user-attachments/assets/a0264344-6c3d-403d-ae49-db8b30507623) +| Tecla | Ação | +|-------|------| +| `Del` | Exclui a anotação selecionada. | +| `Esc` | Deseleciona a anotação atual sem excluí-la. | +| `Shift` + clique | Coloca uma anotação e **mantém a mesma ferramenta ativa**, permitindo adicionar múltiplas anotações em rápida sucessão sem precisar selecionar a ferramenta novamente. | + +

Shift+click to place multiple annotations in succession

+ +--- ## Modo Desenvolvedor -- Se você habilitou o modo desenvolvedor (Edit > Application Settings > Developer > Enable developer mode) no Slicer, você pode notar opções adicionais dentro da extensão. Estas representam recursos experimentais e processos instáveis atualmente em teste -![image](https://github.com/user-attachments/assets/ce9478fa-e195-4cc8-b2ef-f90b3d4c9ed1) -- O recurso Fetch From GitHub permite que os usuários baixem tutoriais diretamente de uma lista curada de repositórios externos. Atualmente, este recurso está desabilitado para evitar problemas relacionados aos limites de taxa da API do GitHub. -- .Tutorial Creation Tools: Esses recursos auxiliam no desenvolvimento de novos tutoriais, permitindo gravar nomes e caminhos de widgets automaticamente. +Se o **Modo Desenvolvedor** estiver habilitado no Slicer (**Edit → Application Settings → Developer → Enable developer mode**), opções adicionais aparecerão no painel do Tutorial Maker. + +

Developer Mode extra options

+ +- **Fetch From GitHub:** Baixa scripts de tutoriais diretamente de uma lista curada de repositórios externos. Atualmente desativado por padrão para evitar problemas com os limites de taxa da API do GitHub. +- **Tutorial Creation Tools:** Auxilia no desenvolvimento de novos tutoriais registrando nomes e caminhos de widgets automaticamente. + +> [!WARNING] +> Os recursos do Modo Desenvolvedor são experimentais e podem causar instabilidade. Recomendamos fortemente manter o Modo Desenvolvedor desativado para a criação rotineira de tutoriais. + +--- + +## Escrevendo Tutoriais + +Para orientações sobre como criar seus próprios scripts de tutorial, siga os modelos e exemplos disponíveis na [SlicerTutorialMakerCollection](https://github.com/SoniaPujolLab/SlicerTutorialMakerCollection). + +--- + +## Desinstalação + +### Pelo Gerenciador de Extensões (recomendado) + +1. No 3D Slicer, abra **View → Extension Manager** (ou o botão **Extensions Manager** na barra de ferramentas). +2. Acesse a aba **Installed Extensions**. +3. Localize **TutorialMaker** na lista. +4. Clique no botão **Uninstall** (lixeira / remover) ao lado da extensão. +5. Reinicie o 3D Slicer quando solicitado para concluir a remoção. + +

Uninstalling via Extension Manager

+ +### Remoção manual (instalação por desenvolvedor / código-fonte) + +Se você instalou a extensão adicionando-a aos **Additional module paths**, siga estas etapas: + +1. Acesse **Edit → Application Settings → Modules**. +2. Na lista **Additional module paths**, selecione a entrada que aponta para a pasta `TutorialMaker` (ou `TutorialMaker.py`). +3. Clique no botão **Remove** (menos) para excluir a entrada do caminho. +4. Clique em **OK** e reinicie o 3D Slicer. +5. Após reiniciar, você pode excluir com segurança o diretório `TutorialMaker-main` do seu sistema de arquivos. + +> [!NOTE] +> Remover o caminho do módulo apenas cancela o registro da extensão no Slicer. Você deve excluir manualmente a pasta de origem do disco para remover todos os arquivos. + +**Removendo arquivos de saída gerados** -## Escrevendo tutoriais -- Para orientações sobre o desenvolvimento de seus próprios tutoriais, siga o modelo e exemplos hospedados no SlicerTestRepository (https://github.com/SoniaPujolLab/SlicerTestTutorial). +Os arquivos de saída dos tutoriais (capturas de tela, anotações, HTML e Markdown) são armazenados dentro da pasta de instalação da extensão em `TutorialMaker/Outputs/`. Esses arquivos não são removidos automaticamente. Exclua o diretório `Outputs/` manualmente caso não precise mais deles. diff --git a/TutorialMaker/Lib/TutorialExporter.py b/TutorialMaker/Lib/TutorialExporter.py index 247ea12e..de585f91 100644 --- a/TutorialMaker/Lib/TutorialExporter.py +++ b/TutorialMaker/Lib/TutorialExporter.py @@ -534,11 +534,26 @@ class Theme(Enum): overflow: hidden; page-break-after: always; page-break-inside: avoid; - min-height: 600px; + height: 600px; + display: flex; + flex-direction: column; + }} + + /* Stacked content */ + .slideContent, .textContent, .blankContent {{ + flex: 1 1 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 40px; }} - /* Content Wrappers */ - .slideContent, .coverContent, .backCoverContent, .sectionContent, .textContent, .blankContent {{ + /* Centered content */ + .coverContent, .backCoverContent, .sectionContent {{ + flex: 0 1 auto; + min-height: 0; + overflow: hidden; padding: 40px; }} @@ -546,7 +561,6 @@ class Theme(Enum): .cover {{ background: linear-gradient(135deg, {primary} 0%, {secondary} 100%); color: white; - display: flex; align-items: center; justify-content: center; }} @@ -592,22 +606,29 @@ class Theme(Enum): font-size: 3.5rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 3px solid {primary}; }} .containerImage {{ - text-align: center; - margin: 30px 0; + flex: 1 1 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; background: #fafafa; - padding: 20px; + padding: 10px; border-radius: 4px; }} .slideImage {{ - max-width: 90%; + max-width: 100%; + max-height: 100%; + width: auto; height: auto; + object-fit: contain; border-radius: 4px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }} @@ -617,17 +638,15 @@ class Theme(Enum): line-height: 1.8; color: #444; text-align: justify; - margin-top: 25px; + margin-top: 10px; }} /* Back Cover */ .backCover {{ background: linear-gradient(135deg, {secondary} 0%, {primary} 100%); color: white; - min-height: 600px; - display: flex; - flex-direction: column; align-items: center; + justify-content: center; }} .backCoverContent {{ @@ -677,8 +696,6 @@ class Theme(Enum): .sectionSlide {{ background: linear-gradient(135deg, {primary} 0%, {secondary} 100%); color: white; - min-height: 600px; - display: flex; align-items: center; justify-content: center; }} @@ -700,7 +717,7 @@ class Theme(Enum): font-size: 3.5rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 3px solid {primary}; }} @@ -735,22 +752,33 @@ class Theme(Enum): /* Print Styles */ @media print {{ + * {{ + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + }} + body {{ background: white; padding: 0; }} .slide, .cover, .backCover, .sectionSlide, .textSlide, .blankSlide {{ + max-width: none; + width: 297mm; + height: 148.5mm; margin: 0; box-shadow: none; border-radius: 0; - min-height: 100vh; - height: auto; + overflow: hidden; + }} + + .slideContent, .textContent, .blankContent {{ + overflow: hidden; }} }} @page {{ - size: A4 landscape; + size: 297mm 148.5mm; margin: 0; }} """, @@ -777,16 +805,29 @@ class Theme(Enum): overflow: hidden; page-break-after: always; page-break-inside: avoid; - min-height: 600px; + height: 600px; + display: flex; + flex-direction: column; }} - .slideContent, .coverContent, .backCoverContent, .sectionContent, .textContent, .blankContent {{ + .slideContent, .textContent, .blankContent {{ + flex: 1 1 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 50px; + }} + + .coverContent, .backCoverContent, .sectionContent {{ + flex: 0 1 auto; + min-height: 0; + overflow: hidden; padding: 50px; }} .cover {{ background: white; - display: flex; align-items: center; justify-content: center; }} @@ -831,7 +872,7 @@ class Theme(Enum): font-size: 4rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid {primary}; text-align: center; @@ -839,15 +880,22 @@ class Theme(Enum): }} .containerImage {{ - text-align: center; - margin: 30px 0; - padding: 20px; + flex: 1 1 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + padding: 10px; border: 1px solid #ddd; }} .slideImage {{ - max-width: 85%; + max-width: 100%; + max-height: 100%; + width: auto; height: auto; + object-fit: contain; border: 1px solid {primary}; }} @@ -856,14 +904,13 @@ class Theme(Enum): line-height: 1.9; color: {text}; text-align: justify; - margin-top: 25px; + margin-top: 10px; }} .backCover {{ background: white; - display: flex; - flex-direction: column; align-items: center; + justify-content: center; }} .backCover .coverTitle {{ @@ -905,8 +952,6 @@ class Theme(Enum): /* Section Slide */ .sectionSlide {{ background: #fefefe; - min-height: 600px; - display: flex; align-items: center; justify-content: center; }} @@ -934,7 +979,7 @@ class Theme(Enum): font-size: 4rem; font-weight: 600; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid {primary}; text-align: center; @@ -972,21 +1017,32 @@ class Theme(Enum): }} @media print {{ + * {{ + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + }} + body {{ background: white; padding: 0; }} .slide, .cover, .backCover, .sectionSlide, .textSlide, .blankSlide {{ + max-width: none; + width: 297mm; + height: 148.5mm; margin: 0; border: none; - min-height: 100vh; - height: auto; + overflow: hidden; + }} + + .slideContent, .textContent, .blankContent {{ + overflow: hidden; }} }} @page {{ - size: A4 landscape; + size: 297mm 148.5mm; margin: 0; }} """, @@ -1012,15 +1068,28 @@ class Theme(Enum): overflow: hidden; page-break-after: always; page-break-inside: avoid; - min-height: 600px; + height: 600px; + display: flex; + flex-direction: column; }} - .slideContent, .coverContent, .backCoverContent, .sectionContent, .textContent, .blankContent {{ + .slideContent, .textContent, .blankContent {{ + flex: 1 1 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 60px; + }} + + .coverContent, .backCoverContent, .sectionContent {{ + flex: 0 1 auto; + min-height: 0; + overflow: hidden; padding: 60px; }} .cover {{ - display: flex; align-items: center; justify-content: center; border-left: 8px solid {primary}; @@ -1059,32 +1128,39 @@ class Theme(Enum): font-size: 3.3rem; font-weight: 400; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid {primary}; }} .containerImage {{ - text-align: center; - margin: 30px 0; + flex: 1 1 0; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + padding: 10px; }} .slideImage {{ max-width: 100%; + max-height: 100%; + width: auto; height: auto; + object-fit: contain; }} .slideDescription {{ font-size: 1.9rem; line-height: 1.8; color: {text}; - margin-top: 25px; + margin-top: 10px; }} .backCover {{ - display: flex; - flex-direction: column; align-items: center; + justify-content: center; border-left: 8px solid {primary}; }} @@ -1127,8 +1203,6 @@ class Theme(Enum): .sectionSlide {{ background: white; border-left: 8px solid {primary}; - display: flex; - min-height: 600px; align-items: center; justify-content: center; }} @@ -1151,7 +1225,7 @@ class Theme(Enum): font-size: 3.3rem; font-weight: 400; color: {primary}; - margin-bottom: 30px; + margin-bottom: 20px; padding-bottom: 10px; border-bottom: 1px solid {primary}; }} @@ -1182,21 +1256,36 @@ class Theme(Enum): color: {text}; }} + .slideContent p, .textContent p, .blankContent p {{ + margin: 0 0 0.4em; + }} + @media print {{ + * {{ + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + }} + body {{ background: white; padding: 0; }} .slide, .cover, .backCover, .sectionSlide, .textSlide, .blankSlide {{ + max-width: none; + width: 297mm; + height: 148.5mm; margin: 0; - min-height: 100vh; - height: auto; + overflow: hidden; + }} + + .slideContent, .textContent, .blankContent {{ + overflow: hidden; }} }} @page {{ - size: A4 landscape; + size: 297mm 148.5mm; margin: 0; }} """ @@ -1212,7 +1301,7 @@ def __init__(self, title: str, author: str, date: str, description: str): self.Description = description pass - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = HTML_TEMPLATES[theme]['cover'] colors = PALETTE_COLORS[palette] return template.format( @@ -1223,7 +1312,7 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): **colors ) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = MARKDOWN_TEMPLATES[theme]['cover'] colors = PALETTE_COLORS[palette] return template.format( @@ -1239,7 +1328,7 @@ def __init__(self, title: str, Acknowledgments: str): self.Title = title self.Acknowledgments = Acknowledgments - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): if isinstance(self.Acknowledgments, dict): items = "".join( f"
  • {k}

    {v}

  • " @@ -1257,7 +1346,7 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): **colors ) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): colors = PALETTE_COLORS[palette] if isinstance(self.Acknowledgments, dict): @@ -1289,13 +1378,18 @@ def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODER ) class SimpleSlide(): - def __init__(self, Title: str, Description: str, ImagePath: str): + def __init__(self, Title: str, Description: str, ImagePath: str, base_dir: str = None): self.Title = Title self.Description = Description self.ImagePath = ImagePath + self.BaseDir = base_dir - def _get_image_data_url(self, image_path): - if not image_path or not os.path.exists(image_path): + def _get_image_data_url(self, image_path, base_dir: str = None): + if not image_path: + return image_path + if base_dir and not os.path.isabs(image_path): + image_path = os.path.join(base_dir, image_path) + if not os.path.exists(image_path): return image_path try: @@ -1319,11 +1413,14 @@ def _get_image_data_url(self, image_path): print(f"Warning: Could not convert image to base64 ({image_path}): {e}") return image_path - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = HTML_TEMPLATES[theme]['slide'] colors = PALETTE_COLORS[palette] - - image_src = self._get_image_data_url(self.ImagePath) + base_dir = self.BaseDir + if embed: + image_src = self._get_image_data_url(self.ImagePath, base_dir=base_dir) + else: + image_src = self.ImagePath or "" return template.format( title=self.Title, @@ -1333,11 +1430,14 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): **colors ) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = MARKDOWN_TEMPLATES[theme]['slide'] colors = PALETTE_COLORS[palette] - - image_src = self._get_image_data_url(self.ImagePath) + base_dir = self.BaseDir + if embed: + image_src = self._get_image_data_url(self.ImagePath, base_dir=base_dir) + else: + image_src = self.ImagePath or "" return template.format( title=self.Title, @@ -1351,7 +1451,7 @@ class SimpleSection(): def __init__(self, Title: str): self.Title = Title - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = HTML_TEMPLATES[theme]['section'] colors = PALETTE_COLORS[palette] return template.format( @@ -1359,7 +1459,7 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): **colors ) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = MARKDOWN_TEMPLATES[theme]['section'] colors = PALETTE_COLORS[palette] return template.format( @@ -1372,7 +1472,7 @@ def __init__(self, Title: str, Body: str): self.Title = Title self.Body = Body - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = HTML_TEMPLATES[theme]['text'] colors = PALETTE_COLORS[palette] return template.format( @@ -1381,7 +1481,7 @@ def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): **colors ) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = MARKDOWN_TEMPLATES[theme]['text'] colors = PALETTE_COLORS[palette] return template.format( @@ -1394,12 +1494,12 @@ class BlankSlide(): def __init__(self): pass - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = HTML_TEMPLATES[theme]['blank'] colors = PALETTE_COLORS[palette] return template.format(**colors) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): template = MARKDOWN_TEMPLATES[theme]['blank'] colors = PALETTE_COLORS[palette] return template.format(**colors) @@ -1419,9 +1519,10 @@ def __init__(self, Model:SlideModel = SlideModel.SimpleSlide): self.Model = Model # Model will be used later to create more than one type of slide class TutorialExporter(): - def __init__(self, Slides: list[SlidePage], Title: str): + def __init__(self, Slides: list[SlidePage], Title: str, html_dir: str = None): self.Slides = Slides self.Title = Title + self.HtmlDir = html_dir self.Html = """ @@ -1435,18 +1536,103 @@ def __init__(self, Slides: list[SlidePage], Title: str): + """ self.Markdown = "" - def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): - body = "".join([slide.Model.ToHtml(palette=palette, theme=theme) for slide in self.Slides]) + def ToHtml(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): + body = "".join([slide.Model.ToHtml(palette=palette, theme=theme, embed=embed) for slide in self.Slides]) colors = PALETTE_COLORS[palette] css = CSS_TEMPLATES[theme].format(**colors) return self.Html.format(self.Title, body, css) - def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): - md = "".join([slide.Model.ToMarkdown(palette=palette, theme=theme) for slide in self.Slides]) + def ToMarkdown(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN, embed: bool = False): + md = "".join([slide.Model.ToMarkdown(palette=palette, theme=theme, embed=embed) for slide in self.Slides]) self.Markdown = md return md @@ -1462,7 +1648,7 @@ def ToPdf(self, palette: Palette = Palette.BLUE, theme: Theme = Theme.MODERN): printer.setOrientation(qt.QPrinter.Landscape) doc = qt.QTextDocument() - doc.setHtml(self.ToHtml(palette=palette, theme=theme)) + doc.setHtml(self.ToHtml(palette=palette, theme=theme, embed=True)) doc.setPageSize(qt.QSizeF(printer.pageRect().size())) doc.print_(printer) diff --git a/TutorialMaker/Lib/TutorialPainter.py b/TutorialMaker/Lib/TutorialPainter.py index c0b37141..f759b95e 100644 --- a/TutorialMaker/Lib/TutorialPainter.py +++ b/TutorialMaker/Lib/TutorialPainter.py @@ -842,11 +842,11 @@ def GenerateHTMLfromAnnotatedTutorial(self, path): ) elif slide.SlideLayout == AnnotatorSlideLayoutType.Screenshot: - full_image_path = os.path.join(localizedScreenshotsPath, slide.imagePath) page = Exporter.SimpleSlide( slide.SlideTitle, self.SimpleParser(slide.SlideBody), - full_image_path + slide.imagePath, + base_dir=localizedScreenshotsPath ) elif slide.SlideLayout == AnnotatorSlideLayoutType.Blank: @@ -860,7 +860,7 @@ def GenerateHTMLfromAnnotatedTutorial(self, path): tutorialPath = localizedScreenshotsPath + f"/{clean_title}" - export = Exporter.TutorialExporter(pages, self.TutorialInfo["title"]) + export = Exporter.TutorialExporter(pages, self.TutorialInfo["title"], html_dir=localizedScreenshotsPath) html = export.ToHtml() markdown = export.ToMarkdown() # pdf = export.ToPdf()