ReVo Blog

PHPMarkdoc

« Older   Newer »
  Share  
.ReVo.
view post Posted on 25/7/2014, 13:50




In questi ultimi giorni mi sono dedicato ad un piccolo progetto "casalingo"... PHPMarkdoc.

PHPMarkdoc



Lo scopo è quello di generare documentazione PHP nel formato Markdown in modo da poterlo usare per inserire la documentazione di una classe in un Wiki di Bitbucket o Github.
L'idea mi è venuta quando dovevo scrivere la documentazione online di alcune classi che avevo creato per un progetto e vedendo che tutti i generatori automatici erano tutti per HTML ho pensato di crearne una mia versione che scrivesse tutto in Markdown.

Il progetto utilizza Java, mentre per legge i file da analizzare viene usato il PHP (php-cgi -f <file_name>). Il file source.php utilizza le API Reflection del PHP per leggere i dati delle classi dell'utente e le memorizza in una struttura Json che sarà letta e convertita in un oggetto FileDoc da Java.

Il codice dell'utente viene iniettato da Java utilizzato un file di "passaggio" che ho chiamato source_injector.php infatti, questo file viene creato da Java ogni volta che è necessario analizzare un file e contiene una singola linea:

CODICE
require_once("URL_DEL_FILE_PHP");


In questo modo, all'interno di source.php è presente il codice PHP della classe (p.s al momento non è presente nessun algoritmo che "blocca" output diversi dal Json di source.php).

Le funzioni get_declared_classes, get_declared_interfaces, get_defined_functions e get_declared_traits si occuperanno di leggere i nomi delle classi dell'utente.

Va notato che, prima di require_once("source_injector.php"); troviamo:

CODICE
$default_classes = get_declared_classes();
$default_interfaces = get_declared_interfaces();
$default_traits = get_declared_traits();


Con questo "trucco", possiamo fare in modo di isolare le classi di PHP da quelle dell'utente utilizzando array_diff.

Non c'è nulla del genere per le funzioni perchè il PHP già fa la divisione con un array interno con [internal] e [user] per differenziare i due tipi, eseguire un array_filter su questo array è obbligatorio per rimuovere da questo elenco le funzioni del parser (infatti, anche se get_defined_functions() viene eseguito prima che il source.php definisca una funzione, il PHP fa una prima lettura del sorgente per leggere tutte le funzioni (e tanto altro)) ed è per questo che hanno tutte un prefix parse_. Purtroppo questo sistema ha i suoi limiti, se l'utente dichiara una funzione con il prefisso parse_ questa sarà "silenziosamente" ignorata. Per questo sto pensando di utilizzare un array interno per definire le funzioni di sistema, ma il problema rimane lo stesso se l'utente utilizza funzioni con gli stessi nomi (parse_ è molto comune, per questo dovrà essere modificato in phpmarkdoc_parser_*).

Dopo tutto questo lavoro, come ho detto prima, il PHP ritorna a Java il Json con tutte le informazioni necessarie sul file:

  • Il numero di classi/traits/funzioni e interfacce trovate

  • Tutte le classi trovate

  • Tutte le interfacce trovate

  • Tutti i traits trovati

  • Tutte le funzioni trovate


Questi ultimi 4 non contengono solamente i nomi ma tutte le informazioni necessarie trovate. (Tranne per quanto riguarda informazioni come super classi o interfacce implementate, dato che potrebbe capitare che la definizione si trovi da qualche altra parte.. Anche se non sono soddisfatto di questo sistema, dato che a causa dell'eccessiva "flessibilità" del PHP potrebbe essere difficile capire quale sia la vera super classe/interfaccia)

Da come si può intuire, FileDoc è il padre di tutto. Contiene tutti i dati Json portati in forma di classi Java.

Non c'è molto da scrivere a riguardo, sono solo una lista di campi che riportano i dati trovati.

Il sistema di scrittura



Il mio scopo era renderlo il più flessibile possibile!

Più flessibile è, meno codice è necessario cambiare per modificare il tipo di output. L'interfaccia Writer si occupa di rappresentare una classe il cui compito è quello di scrivere su un file senza sapere nulla sul formato o altro.

Nome metodoDescrizione
start(String fileName, Path outputDirectory)Richiamato quando il Parser vuole scrivere qualcosa su un determinato file (fileName) e dove (outputDirectory).
writeClassInfo(LClass lClass)Chiamato quando si vuole scrivere informazioni riguardo una determinata classe (lClass)
writeTraitInfo(Trait trait)Chiamato quando si vuole scrivere informazioni riguardo un determinato Trait (trait)
writeInterfaceInfo(Interface mInterface)Chiamato quando si vuole scrivere informazioni riguardo una determinata interfaccia (mInterface)
writeFunction(Function function)Chiamato quando si vuole scrivere informazioni riguardo una determinata funzione (function)
close()Chiamato quando il parser ha finito di scrivere (in genere, chiude il writer)


La prima (e attualmente, l'unica) implementazione è MarkdownWriter

L'intero progetto è disponibile qui.

Edited by .ReVo. - 25/7/2014, 17:40

Tags:
java,
php,
phpmarkdoc
 
Top
0 replies since 25/7/2014, 13:50   7 views
  Share