From b3dc6d7d1df3d0c9072e859e1ea32143c8042ae6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 17 Mar 2019 19:33:25 +0100 Subject: [PATCH] NEW Generation of doc by modulebuilder can include README and CHANGELOG --- htdocs/core/class/utils.class.php | 39 +++--- htdocs/core/lib/files.lib.php | 46 +++---- htdocs/core/lib/parsemd.lib.php | 32 +++++ htdocs/langs/en_US/modulebuilder.lang | 4 +- htdocs/modulebuilder/index.php | 123 ++++++++++-------- htdocs/modulebuilder/template/README.md | 13 +- .../template/doc/Documentation.asciidoc | 10 +- 7 files changed, 160 insertions(+), 107 deletions(-) diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 445bc908847..1e596209cdb 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -634,6 +634,19 @@ class Utils return -1; } + // Copy some files into temp directory, so instruction include::ChangeLog.md[] will works inside the asciidoc file. + dol_copy($dirofmodule.'/README.md', $dirofmoduletmp.'/README.md', 0, 1); + dol_copy($dirofmodule.'/ChangeLog.md', $dirofmoduletmp.'/ChangeLog.md', 0, 1); + + // Replace into README.md and ChangeLog.md (in case they are included into documentation with tag __README__ or __CHANGELOG__) + $arrayreplacement=array(); + $arrayreplacement['/^#\s.*/m']=''; // Remove first level of title into .md files + $arrayreplacement['/^#/m']='##'; // Add on # to increase level + + dolReplaceInFile($dirofmoduletmp.'/README.md', $arrayreplacement, '', 0, 0, 1); + dolReplaceInFile($dirofmoduletmp.'/ChangeLog.md', $arrayreplacement, '', 0, 0, 1); + + $destfile=$dirofmoduletmp.'/'.$FILENAMEASCII; $fhandle = fopen($destfile, 'w+'); @@ -666,19 +679,13 @@ class Utils $i++; } - /*fwrite($fhandle, "\n\n\n== DATA SPECIFICATIONS...\n\n"); - - // TODO - fwrite($fhandle, "TODO..."); - - fwrite($fhandle, "\n\n\n== CHANGELOG...\n\n"); - - // TODO - fwrite($fhandle, "TODO..."); - */ - fclose($fhandle); + $contentreadme=file_get_contents($dirofmoduletmp.'/README.md'); + $contentchangelog=file_get_contents($dirofmoduletmp.'/ChangeLog.md'); + + include DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + //var_dump($phpfileval['fullname']); $arrayreplacement=array( 'mymodule'=>strtolower($modulename), @@ -695,16 +702,14 @@ class Utils '__USER_EMAIL__'=>$user->email, '__YYYY-MM-DD__'=>dol_print_date($now, 'dayrfc'), '---Put here your own copyright and developer email---'=>dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':''), - '__DATA_SPECIFICATION__'=>'Not yet available' + '__DATA_SPECIFICATION__'=>'Not yet available', + '__README__'=>dolMd2Asciidoc($contentreadme), + '__CHANGELOG__'=>dolMd2Asciidoc($contentchangelog), ); - dolReplaceInFile($spec['fullname'], $arrayreplacement); + dolReplaceInFile($destfile, $arrayreplacement); } - // Copy some files into temp directory, so instruction include::ChangeLog.md[] will works inside the asciidoc file. - dol_copy($dirofmodule.'/README.md', $dirofmoduletmp.'/README.md', 0, 1); - dol_copy($dirofmodule.'/ChangeLog.md', $dirofmoduletmp.'/ChangeLog.md', 0, 1); - // Launch doc generation $currentdir = getcwd(); chdir($dirofmodule); diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index ec7ca11ca69..b2c7edf4590 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -583,19 +583,20 @@ function dol_filemtime($pathoffile) /** * Make replacement of strings into a file. * - * @param string $srcfile Source file (can't be a directory) - * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) - * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. - * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' - * @param int $indexdatabase 1=index new file into database. - * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dol_copy() dolReplaceRegExInFile() + * @param string $srcfile Source file (can't be a directory) + * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) + * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. + * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' + * @param int $indexdatabase 1=index new file into database. + * @param int $arrayreplacementisregex 1=Array of replacement is regex + * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK + * @see dol_copy() */ -function dolReplaceInFile($srcfile, $arrayreplacement, $destfile = '', $newmask = 0, $indexdatabase = 0) +function dolReplaceInFile($srcfile, $arrayreplacement, $destfile = '', $newmask = 0, $indexdatabase = 0, $arrayreplacementisregex = 0) { global $conf; - dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase); + dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase." arrayreplacementisregex=".$arrayreplacementisregex); if (empty($srcfile)) return -1; if (empty($destfile)) $destfile=$srcfile; @@ -626,7 +627,17 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile = '', $newmask // Create $newpathoftmpdestfile from $newpathofsrcfile $content = file_get_contents($newpathofsrcfile, 'r'); - $content = make_substitutions($content, $arrayreplacement, null); + if (empty($arrayreplacementisregex)) + { + $content = make_substitutions($content, $arrayreplacement, null); + } + else + { + foreach ($arrayreplacement as $key => $value) + { + $content = preg_replace($key, $value, $content); + } + } file_put_contents($newpathoftmpdestfile, $content); @chmod($newpathoftmpdestfile, octdec($newmask)); @@ -650,21 +661,6 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile = '', $newmask return 1; } -/** - * Make replacement of strings into a file. - * - * @param string $srcfile Source file (can't be a directory) - * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) - * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. - * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' - * @param int $indexdatabase Index new file into database. - * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dol_copy() dolReplaceInFile() - */ -function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile = '', $newmask = 0, $indexdatabase = 0) -{ - // TODO -} /** * Copy a file to another file. diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 074b0dcce03..a686278d82c 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -53,3 +53,35 @@ function dolMd2Html($content, $parser = 'parsedown', $replaceimagepath = null) return $content; } + + +/** + * Function to parse MD content into ASCIIDOC + * + * @param string $content MD content + * @param string $parser 'dolibarr' + * @param string $replaceimagepath Replace path to image with another path. Exemple: ('doc/'=>'xxx/aaa/') + * @return string Parsed content + */ +function dolMd2Asciidoc($content, $parser = 'dolibarr', $replaceimagepath = null) +{ + if (is_array($replaceimagepath)) + { + foreach($replaceimagepath as $key => $val) + { + $keytoreplace = ']('.$key; + $valafter = ']('.$val; + $content = preg_replace('/'.preg_quote($keytoreplace, '/').'/m', $valafter, $content); + } + } + //if ($parser == 'dolibarr') + //{ + $content = preg_replace('//msU', '', $content); + //} + //else + //{ + // $content = $content; + //} + + return $content; +} \ No newline at end of file diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 8f9f62e1018..c10f57aec43 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -24,7 +24,7 @@ ModuleBuilderDescbuildpackage=You can generate here a "ready to distribute" pack EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: ALL files of module AND structured data and documentation will be deleted! EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All files related to object will be deleted! DangerZone=Danger zone -BuildPackage=Build package/documentation +BuildPackage=Build package BuildDocumentation=Build documentation ModuleIsNotActive=This module is not activated yet. Go to %s to make it live or click here: ModuleIsLive=This module has been activated. Any change on it may break a current active feature. @@ -45,7 +45,7 @@ SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed. FileNotYetGenerated=File not yet generated RegenerateClassAndSql=Erase and regenerate class and sql files RegenerateMissingFiles=Generate missing files -SpecificationFile=File with template documentation +SpecificationFile=File of documentation LanguageFile=File for language ConfirmDeleteProperty=Are you sure you want to delete the property %s? This will change code in PHP class but also remove column from table definition of object. NotNull=Not NULL diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 2e66cbed3d1..925990283c6 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -327,6 +327,7 @@ if ($dirins && $action == 'initdoc' && !empty($module)) if ($result > 0) { $modulename = ucfirst($module); // Force first letter in uppercase + $modulelowercase = strtolower($module); //var_dump($phpfileval['fullname']); $arrayreplacement=array( @@ -347,6 +348,17 @@ if ($dirins && $action == 'initdoc' && !empty($module)) ); dolReplaceInFile($destfile, $arrayreplacement); + + // Delete old documentation files + $FILENAMEDOC=$modulelowercase.'.html'; + $FILENAMEDOCPDF=$modulelowercase.'.pdf'; + $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC; + $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC; + $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF; + $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF; + + dol_delete_file($outputfiledoc, 0, 0, 0, null, false, 0); + dol_delete_file($outputfiledocpdf, 0, 0, 0, null, false, 0); } } @@ -557,7 +569,7 @@ if ($dirins && $action == 'initobject' && $module && $objectname) $moduledescriptorfile=$destdir.'/core/modules/mod'.$module.'.class.php'; - // TODO Allow a replace with regex using dolReplaceRegexInFile + // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1 // TODO Avoid duplicate addition dolReplaceInFile($moduledescriptorfile, array('END MODULEBUILDER LEFTMENU MYOBJECT */' => '*/'."\n".$stringtoadd."\n\t\t/* END MODULEBUILDER LEFTMENU MYOBJECT */")); @@ -985,10 +997,17 @@ if ($action == 'savefile' && empty($cancel)) if ($content) { dol_delete_file($pathoffile); - file_put_contents($pathoffile, $content); - @chmod($pathoffile, octdec($newmask)); + $result = file_put_contents($pathoffile, $content); + if ($result) + { + @chmod($pathoffile, octdec($newmask)); - setEventMessages($langs->trans("FileSaved"), null); + setEventMessages($langs->trans("FileSaved"), null); + } + else + { + setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors'); + } } else { @@ -2742,13 +2761,13 @@ elseif (! empty($module)) if ($tab == 'specifications') { + $specs=dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/')); + if ($action != 'editfile' || empty($file)) { print ''.$langs->trans("SpecDefDesc").'
'; print '
'; - $specs=dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/')); - print ''; if (is_array($specs) && ! empty($specs)) { @@ -2802,6 +2821,53 @@ elseif (! empty($module)) print ''; } + + print '


'; + + $FILENAMEDOC=$modulelowercase.'.html'; + $FILENAMEDOCPDF=$modulelowercase.'.pdf'; + $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC; + $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC; + $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF; + $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF; + + // HTML + print ' '. $langs->trans("PathToModuleDocumentation", "HTML") . ' : '; + if (! dol_is_file($outputfiledoc)) print ''.$langs->trans("FileNotYetGenerated").''; + else { + print ''; + print ''; + print $outputfiledoc; + print ''; + print ''; + print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')'; + } + print '
'; + + // PDF + print ' '. $langs->trans("PathToModuleDocumentation", "PDF") . ' : '; + if (! dol_is_file($outputfiledocpdf)) print ''.$langs->trans("FileNotYetGenerated").''; + else { + print ''; + print ''; + print $outputfiledocpdf; + print ''; + print ''; + print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')'; + } + print '
'; + + print '
'; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; } if ($tab == 'buildpackage') @@ -2846,13 +2912,6 @@ elseif (! empty($module)) { $FILENAMEZIP="module_".$modulelowercase.'-'.$arrayversion[0].'.'.$arrayversion[1].($arrayversion[2]?".".$arrayversion[2]:"").".zip"; $outputfilezip = dol_buildpath($modulelowercase, 0).'/bin/'.$FILENAMEZIP; - - $FILENAMEDOC=$modulelowercase.'.html'; - $FILENAMEDOCPDF=$modulelowercase.'.pdf'; - $outputfiledoc = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOC; - $outputfiledocurl = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOC; - $outputfiledocpdf = dol_buildpath($modulelowercase, 0).'/doc/'.$FILENAMEDOCPDF; - $outputfiledocurlpdf = dol_buildpath($modulelowercase, 1).'/doc/'.$FILENAMEDOCPDF; } print '
'; @@ -2875,44 +2934,6 @@ elseif (! empty($module)) print ''; print ''; print ''; - - print '


'; - - // HTML - print ' '. $langs->trans("PathToModuleDocumentation", "HTML") . ' : '; - if (! dol_is_file($outputfiledoc)) print ''.$langs->trans("FileNotYetGenerated").''; - else { - print ''; - print ''; - print $outputfiledoc; - print ''; - print ''; - print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledoc), 'dayhour').')'; - } - print '
'; - - // PDF - print ' '. $langs->trans("PathToModuleDocumentation", "PDF") . ' : '; - if (! dol_is_file($outputfiledocpdf)) print ''.$langs->trans("FileNotYetGenerated").''; - else { - print ''; - print ''; - print $outputfiledocpdf; - print ''; - print ''; - print ' ('.$langs->trans("GeneratedOn").' '.dol_print_date(dol_filemtime($outputfiledocpdf), 'dayhour').')'; - } - print '
'; - - print '
'; - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; } if ($tab != 'description') diff --git a/htdocs/modulebuilder/template/README.md b/htdocs/modulebuilder/template/README.md index f894c3ac6ae..0fcd76f178e 100644 --- a/htdocs/modulebuilder/template/README.md +++ b/htdocs/modulebuilder/template/README.md @@ -11,7 +11,7 @@ Other modules are available on -Licenses --------- +## Licenses -### Main code +**Main code** GPLv3 or (at your option) any later version. See file COPYING for more information. -#### Documentation +**Documentation** All texts and readmes are licensed under GFDL. diff --git a/htdocs/modulebuilder/template/doc/Documentation.asciidoc b/htdocs/modulebuilder/template/doc/Documentation.asciidoc index b9fb684e312..5a05c7011a6 100644 --- a/htdocs/modulebuilder/template/doc/Documentation.asciidoc +++ b/htdocs/modulebuilder/template/doc/Documentation.asciidoc @@ -16,7 +16,7 @@ == TOPIC OF DOCUMENT -This document is the document of module MyModule +This is the documentation of module MyModule *Log of versions of document* @@ -41,8 +41,8 @@ This document was generated using Dolibarr ERP CRM process == INTRODUCTION -include::README.md[] - +//include::README.md[] +__README__ == DATA SPECIFICATIONS @@ -51,4 +51,6 @@ __DATA_SPECIFICATION__ == CHANGELOG -include::ChangeLog.md[] +//include::ChangeLog.md[] +__CHANGELOG__ +