Uno de mis objetivos en torno al desarrollo web en general, es respetar lo más estrictamente posible los estándares W3C.
La documentación generada por phpDocumentor lamentablemente no es completamente limpia en ese sentido. Y como phpDocumentor es Software Libre, decidí meterle mano.
phpDocumentor tiene unas clases «Converter», dedicadas a transformar la información analisada del código fuente en el formato de salida. Los 2 converters afectados son HTMLframesConverter.inc y HTMLSmartyConverter.inc.
frames hace la documentación en páginas HTML en marcos, y Smarty en una página completa por cada elemento documentado. Ambos usan smarty como motor de plantillas.
Fijándome en los errores descubiertos por Html Validator for Firefox y ZendStudio, logré identificar los archivos fuente afectados. En su mayoría eran errores tontos en las plantillas, como el uso de mayúsculas en las etiquetas y nombres de atributos, falta de atributos obligatorios y esas cosas. Pero hay unos detalles que no depende de los templates, sino de las clases Converter. Por ejemplo, me topé con que el árbol de clases queda con etiquetas de cierre </ul> y </li> sueltas. Tampoco se escapan los caracteres «&» de los parámetros pasados por referencia. Muchos otros lugares de las plantillas tienen problemas con etiquetas con contenido vacío (por ejemplo, me vi obligado a rellenar el tag @copyright en todos los archivos fuente y así evitar un <ul></ul>).
Ojeando el código, encontré que el método getRootTree() consiste en un algoritmo iterativo que recorre el arreglo de nodos de información de las clases. El problema es que los método iterativos que trabajan con arreglos o árboles, suelen requerir muchas más variables auxiliares, por lo cual confunde mucho. Además recuerdo haber trabajado en una clase que desplegaba listas HTML con <ul> y <li>, pero usando un método recursivo.
Para quien le interese el concepto, hay un patrón de diseño llamado «Composite», que ocupa el mismo principio de recursividad, pero en el recorrido se hace entre objetos (cada nodo es propiedad de otro objeto de igual clase).
Como me fue imposible comprender el error, decidí derechamente reescribir el método del HTMLframesConverter.inc y HTMLSmartyConverter.inc (era idéntico). Además, tuve que quitar unas etiquetas de apertura<ul> y cierre </ul> en los métodos generateFormattedClassTrees() y generateFormattedInterfacesTrees() que invocaban a getRootTree().
Acá está uno de los archivos fuente modificados por mí, por si alguien le interesa: http://pastebin.com/f3c61b7c5
Por supuesto, mandé este tema al bug tracker y a la lista de correos de phpdocumentor. Espero que ojala se resuelvan los detalles pendientes. Por lo que he visto, últimamente están más concentrados en lo que será el soporte de PHP6.
Excelente aporte, ese es el espíritu del software libre.
Saludos !!!!
Bien gon