2. Los ejemplos de este documento
Me gustaría escribir un artículo breve. Las interacciones entre una IA y un usuario se presentan en el artículo [Generar un script de Python con herramientas de IA], al que a partir de ahora me referiré como [ref1]. Las interacciones con Gemini y ChatGPT solo se presentarán de forma marginal. De todos modos, era imposible presentar todas las iteraciones.
Ahora voy a presentar ejemplos de las particularidades de mis documentos ODT / DOCX que el conversor Gemini / ChatGPT gestiona correctamente. Es este mismo documento el que propondremos para la conversión a HTML mediante el script de Gemini / ChatGPT. Veremos qué hace con él.
2.1. Las listas
El conversor Gemini / ChatGPT sabe gestionar las listas con viñetas y las listas numeradas, incluso si están anidadas:
2.1.1. Listas con viñetas s
- Elemento 1;
- Elemento 2:
- Elemento 3;
- Elemento 3.1;
- Elemento 3.1.1
- Elemento 3.1.2
- Elemento 3.1.2.1
- Elemento 3.1.2.2
- Elemento 3.2;
- Elemento 3.1;
- Elemento 4;
2.1.2. Listas numeradas
- Elemento 1;
- Elemento 2;
- Elemento 2.1
- Elemento 2.1.1
- Elemento 2.1.1.1
- Elemento 2.1.1.2
- Elemento 2.1.2
- Elemento 2.1.1
- Elemento 2.2
- Elemento 2.1
- Elemento 3;
2.1.3. Listas mixtas 1
- Elemento 1;
- Elemento 2:
- Elemento 3;
- Elemento 3.1;
- Elemento 3.1.1
- Elemento 3.1.2
- Elemento 3.1.2.1
- Elemento 3.1.2.2
- Elemento 3.2;
- Elemento 3.1;
- Elemento 4;
2.1.4. Listas mixtas 2
- Elemento 1;
- Elemento 2;
- Elemento 2.1
- Elemento 2.1.1
- Elemento 2.1.1.1
- Elemento 2.1.1.2
- Elemento 2.1.2
- Elemento 2.1.1
- Elemento 2.2
- Elemento 2.1
- Elemento 3;
2.1.5. Listas numeradas manualmente
Por numeración manual se entiende aquí que es el usuario quien establece el número de un párrafo numerado: [clic con el botón derecho del ratón sobre el párrafo numerado / párrafo / párrafo / reiniciar la numeración / comenzar con].
Empiezo una lista con un número distinto de 1.
- Elemento 6
- Elemento 7
Aquí interrumpo la lista para decir algo, pero luego quiero continuar con la numeración.
- Elemento 8
- elemento 9
A continuación, empiezo una nueva lista numerada:
- elemento 11
- elemento 12
2.2. Los bloques de código
Mis cursos contienen muchos bloques de código. A menudo se trata de códigos formateados (negrita, colores en las palabras clave) por los IDE (Eclipse, PyCharm, WebStorm, Netbeans). El conversor reproduce estos códigos formateados tal cual.
Cuando el código no está formateado (código procedente del Bloc de notas o Notepad o…), el conversor Gemini / ChatGPT lo reconoce (Java, C#, XML, HTML, …) mediante palabras clave del lenguaje incluidas en un archivo de configuración. Cuando reconoce un lenguaje, inserta un marcador (fence) para MkDocs, de modo que este adapte el resaltado sintáctico del código al lenguaje utilizado en el bloque de código.
2.2.1. Bloques de código enriquecido (Eclipse, Visual Studio, etc.)
A continuación se muestran bloques de código enriquecidos por diferentes IDE:
Java
package istia.st.spring.core;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
clase pública Demo01 {
@SuppressWarnings({ "unchecked", "resource" })
public static void main(String[] args) {
// recuperación del contexto Spring
ApplicationContext ctx = new ClassPathXmlApplicationContext("config-01.xml");
// recuperamos los beans
Persona p01 = ctx.getBean("persona_01", Persona.class);
Persona p02 = ctx.getBean("persona_02", Persona.class);
List<Persona> club = ctx.getBean("club", new ArrayList<Persona>().getClass());
Piso piso01 = ctx.getBean(Piso.class);
...
C#
using System;
namespace Chap1 {
class Impuestos {
static void Main(string[] args) {
// matrices de datos necesarias para el cálculo del impuesto
decimal[] límites = { 4962M, 8382M, 14753M, 23888M, 38868M, 47932M, 0M };
decimal[] coeffR = { 0M, 0.068M, 0.191M, 0.283M, 0.374M, 0.426M, 0.481M };
decimal[] coeffN = { 0M, 291,09M, 1322,92M, 2668,39M, 4846,98M, 6883,66M, 9505,54M };
// recuperamos el estado civil
bool OK = false;
string respuesta = null;
while (!OK) {
Console.Write("¿Está casado/a (S/N)? ");
respuesta = Console.ReadLine().Trim().ToLower();
if (respuesta != "s" && respuesta != "n")
Console.Error.WriteLine("Respuesta incorrecta. Vuelva a intentarlo");
else OK = true;
}//while
bool marie = respuesta == "o";
...
Python
# ----------------------------------
def mostrar(cadena):
# muestra cadena
print("cadena=%s" % cadena)
# ----------------------------------
def mostrar_tipo(variable):
# muestra el tipo de variable
print("tipo[%s]=%s" % (variable, tipo(variable)))
# ----------------------------------
def f1(param):
# suma 10 a param
return param + 10
# ----------------------------------
def f2():
# devuelve una tupla de 3 valores
return "uno", 0, 100
# -------------------------------- programa principal ------------------------------------
...
PHP
<?php
// tipos estrictos para los parámetros de las funciones
declare(strict_types=1);
// constantes globales
define("LÍMITE_QF_MEDIA_PARTE", 1551);
define("LÍMITE_INGRESOS_SOLTERO_PARA_REDUCCIÓN", 21037);
define("LÍMITE_INGRESOS_PAREJA_PARA_REDUCCIÓN", 42074);
define("VALOR_REDUCCIÓN_MEDIA_PARTE", 3797);
define("LÍMITE_MÁXIMO_DE_DESCUENTO_SOLTERO", 1196);
define("LÍMITE_MÁXIMO_DE_DESCUENTO_PARA_PAREJAS", 1970);
define("LÍMITE_IMPUESTO_PAREJA_PARA_DESCUENTO", 2627);
define("LÍMITE_MÁXIMO_IMPUESTO_SOLTERO_PARA_DESCUENTO", 1595);
define("DESCUENTO_MÁXIMO_DEL_10_POR_CIENTO", 12502);
define("DESCUENTO_DIEZ_POR_CIENTO_MÍNIMO", 437);
// definición de las constantes locales
$DATA = "taxpayersdata.txt";
$RESULTADOS = "resultados.txt";
$límites = array(9964, 27519, 73779, 156244, 0);
$coeffR = array(0, 0.14, 0.3, 0.41, 0.45);
$coeffN = array(0, 1394.96, 5798, 13913.69, 20163.45);
// lectura de los datos
$data = fopen($DATA, "r");
if (!$data) {
print "No se puede abrir el archivo de datos [$DATA] para lectura\n";
exit;
}
...
ECMAScript
'use strict';
// esto es un comentario
// constante
const nombre = "dupont";
// una salida a pantalla
console.log("nombre: ", nombre);
// una matriz con elementos de diferentes tipos
const matriz = ["uno", "dos", 3, 4];
// su número de elementos
let n = array.length;
// un bucle
for (let i = 0; i < n; i++) {
console.log("matriz[", i, "] = ", matriz[i]);
}
// inicialización de 2 variables con el contenido de un array
let [cadena1, cadena2] = ["cadena1", "cadena2"];
// concatenación de las 2 cadenas
const cadena3 = cadena1 + cadena2;
// visualización del resultado
console.log([cadena1, cadena2, cadena3]);
...
VBScript
' cálculo del impuesto de un contribuyente
' el programa debe ejecutarse con tres parámetros: casado, hijos, salario
' casado: carácter O si está casado, N si no lo está
' hijos: número de hijos
' salario: salario anual sin céntimos
' declaración obligatoria de las variables
Option Explicit
Dim error
' recuperamos los argumentos comprobando su validez
Dim marie, enfants, salario
error = getArguments(marie, enfants, salaire)
' ¿Error?
If error(0)<>0 Then wscript.echo error(1) : wscript.quit error(0)
' se recuperan los datos necesarios para el cálculo del impuesto
Dim límites, coeffR, coeffN
error = getData(límites, coeffR, coeffN)
' ¿Hay error?
Si error(0) ≠ 0 Entonces wscript.echo error(1) : wscript.quit 5
' se muestra el resultado
wscript.echo "impuesto=" & calcularImpuesto(esposa,hijos,salario,límites,coefR,coefN)
' salimos sin error
wscript.quit 0
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuración>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="config://spring/objects" />
</context>
<objects xmlns="http://www.springframework.net">
<object name="dao" type="Dao.DataBaseImpot, ImpotsV7-dao">
<constructor-arg index="0" value="MySql.Data.MySqlClient"/>
<constructor-arg index="1" value="Server=localhost;Database=bdimpots;Uid=admimpots;Pwd=mdpimpots;"/>
<constructor-arg index="2" value="select limite, coeffr, coeffn from tranches"/>
</object>
<object name="metier" type="Metier.ImpotMetier, ImpotsV7-metier">
<constructor-arg index="0" ref="dao"/>
</object>
</objects>
</spring>
</configuración>
2.2.2. Bloques de código sin formato (texto sin formato)
Estos son algunos ejemplos de código sin formato:
Resultados de la ejecución
Cabe señalar que el código no comienza en la línea n.º 1.
Este caso requirió decenas de iteraciones. El conversor nunca encontraba el número de la primera línea de código. Finalmente, le pregunté a Gemini cómo formatear el bloque de código para que lo reconociera. Esto es lo que me respondió:

Seguí este procedimiento y funcionó. Yo utilizaba el método a través del icono de lista (Personalizar). Por lo tanto, es posible que haya que modificar ciertos elementos del documento ODT/DOCX para obtener lo que se desea.
El conversor sabe gestionar bloques de código sin numerar.
Estos son los mismos ejemplos que en el apartado2.2.1 , pero sin enriquecer. En este caso, serán las palabras clave del archivo de configuración las que guiarán al convertidor hacia el lenguaje adecuado.
Java
C#
Python
PHP
ECMAScript
VBScript
XML
HTML
2.3. Los enlaces
El conversor Gemini / ChatGPT conserva los enlaces externos del documento ODT / DOCX. Por ejemplo, Gemini 3 o [Generar un script de Python con herramientas de IA].
Sabe gestionar un enlace a un capítulo Enlace a un capítulo
Una referencia a un capítulo:2.1.1 .
Una referencia a una marca de texto anterior: Gemini 3
Una referencia a un marcador de texto posterior: GitHub
2.4. El enriquecimiento del texto
El conversor sabe gestionar la negrita, la cursiva, el subrayado y el resaltado. Respeta el color del resaltado.
Un texto con palabras en negrita, cursiva, subrayadas o resaltadas o resaltadas o resaltadas.
Lo mismo ocurre con los enlaces: [Generar un script de Python con herramientas de IA].
El conversor también gestiona el color de los caracteres.
También gestiona los bordes superior e inferior de los párrafos.
También gestiona los bordes superior e inferior de los párrafos.- También gestiona los bordes superior e inferior de los párrafos.
- También gestiona los bordes superior e inferior de los párrafos.
También gestiona los bordes superior e inferior de los párrafos.- También gestiona los bordes superior e inferior de los párrafos.
- También gestiona los bordes superior e inferior de los párrafos.
- Un texto con palabras en negrita, cursiva, subrayadas o resaltadas.
- Lo mismo ocurre con los enlaces: [Generar un script de Python con herramientas de IA].
- El conversor también gestiona el color de los caracteres.
- Un texto con palabras en negrita, cursiva, subrayadas o resaltadas.
- Lo mismo ocurre con los enlaces: [Generar un script de Python con herramientas de IA].
- El conversor también gestiona el color de los caracteres.
- También gestiona el fondo del párrafo
- También gestiona el fondo del párrafo
2.5. Un título también se puede enriquecer.
2.6. Las imágenes
El conversor Gemini / ChatGPT sabe gestionar imágenes y tablas de imágenes:
![]() | ![]() |

En los documentos ODT es frecuente encontrar dibujos. A pesar de decenas de intentos, Gemini no ha logrado generar un script que genere la imagen (como una captura de pantalla) del dibujo. Así, arriba, la imagen 5 es la captura de pantalla de un dibujo de un documento ODT.
Todas las imágenes son clicables para ampliarlas. Si arriba hacemos clic en la imagen [1-3], obtenemos la siguiente ampliación:
![]() |
2.7. Los caracteres que hay que proteger
Un sitio web de MkDocs1 tiene páginas cuyo contenido no es HTML, sino Markdown. Si el documento ODT/DOCX contiene caracteres que existen en Markdown, es posible que MkDocs los interprete y, por lo tanto, no se muestren como se esperaba. He aquí dos ejemplos:
El asterisco * tiene un significado en MarkDown. Por lo tanto, la siguiente línea puede interpretarse incorrectamente:
El impuesto I es entonces igual a 0,15*R – 2072,5*nbParts.
Otro ejemplo es cuando quieres insertar un bloque de código Markdown en tu documento como este:
2.8. Las tablas
Una tabla puede contener diferentes contenidos:
1 | 2 | ![]() | |
3 | 4 | ![]() | |
Una tabla que contiene enlaces:
El conversor Gemini / ChatGPT sabe conservar los enlaces externos del documento ODT / DOCX. Por ejemplo Gemini 3 o Sabe gestionar un enlace a un capítulo Enlace a un capítulo | Una referencia a un capítulo:2.1.1 . Una referencia a un marcador de texto anterior: Gemini 3 Una referencia a un marcador de texto posterior: GitHub |
Una tabla cuyas celdas contienen otra tabla:
sirve tanto para generar la etiqueta HTML <form> como para proporcionar información al controlador que tendrá que procesar este formulario:
Cabe señalar que no se especifica el método de envío de los parámetros del formulario (GET/POST) al controlador. Se podría hacer con el atributo method. En ausencia de este, se utiliza el método POST por defecto. | |||||||
sirve para generar la etiqueta <input type="text" value="...">:
|
También gestiona el fondo del párrafo en una tabla
|
2.9. Las notas al pie
El convertidor Gemini2 / ChatGPT gestiona las notas al pie de página. Aquí hay otra nota al pie de página3 .
-
La nota al pie ↩




