@@ -5,7 +5,6 @@ const path = require('path');
5
5
const fse = require ( 'fs-extra' ) ;
6
6
const Glob = require ( 'glob' ) . Glob ;
7
7
const Handlebars = require ( 'handlebars' ) ;
8
-
9
8
const classConfigs = require ( './three-class-config' ) ;
10
9
const Types = require ( './prop-types.js' ) ;
11
10
@@ -14,6 +13,7 @@ const baseDir = path.resolve(scriptDir, '..');
14
13
15
14
const jsSrcDir = path . resolve ( baseDir , 'src/' ) ;
16
15
const pySrcDir = path . resolve ( baseDir , '..' , 'pythreejs' ) ;
16
+ const docSrcDir = path . resolve ( baseDir , '..' , 'docs' , 'source' , 'api' ) ;
17
17
const templateDir = path . resolve ( scriptDir , 'templates' ) ;
18
18
19
19
const threeSrcDir = path . resolve ( baseDir , 'node_modules' , 'three' , 'src' ) ;
@@ -99,9 +99,27 @@ const jsWrapperTemplate = compileTemplate('js_wrapper');
99
99
const jsIndexTemplate = compileTemplate ( 'js_index' ) ;
100
100
const pyWrapperTemplate = compileTemplate ( 'py_wrapper' ) ;
101
101
const pyTopLevelInitTemplate = compileTemplate ( 'py_top_level_init' ) ;
102
+ const docTemplate = compileTemplate ( 'autodoc' ) ;
103
+ const docIndexTemplate = compileTemplate ( 'autodoc_index' ) ;
102
104
103
105
const pathSep = / \\ | \/ / ;
104
106
107
+ Handlebars . registerHelper ( 'indent' , function ( data , indent ) {
108
+ const out = data . replace ( / \n / g, '\n' + indent ) ;
109
+ return new Handlebars . SafeString ( out ) ;
110
+ } ) ;
111
+
112
+ Handlebars . registerHelper ( 'rst' , function ( data , indent ) {
113
+ let out = data
114
+ . replace ( / \* / g, '\\*' )
115
+ . replace ( / \[ / g, '\\[' )
116
+ . replace ( / \] / g, '\\]' ) ;
117
+ if ( indent ) {
118
+ out = out . replace ( / \n / g, '\n' + indent ) ;
119
+ }
120
+ return new Handlebars . SafeString ( out ) ;
121
+ } ) ;
122
+
105
123
//
106
124
// Helper Functions
107
125
//
@@ -856,6 +874,14 @@ class PythonWrapper {
856
874
return this . pyAutoDestPath ;
857
875
}
858
876
877
+ getDocFilename ( ) {
878
+ return path . resolve ( docSrcDir , this . dirRelativePath , `${ this . className } _autogen.rst` ) ;
879
+ }
880
+
881
+ getDocOutput ( ) {
882
+ return docTemplate ( this . context ) ;
883
+ }
884
+
859
885
}
860
886
861
887
function createPythonWrapper ( modulePath , className ) {
@@ -871,14 +897,89 @@ function createPythonWrapper(modulePath, className) {
871
897
let fname = wrapper . getOutputFilename ( ) ;
872
898
let pyPromise = fse . outputFile ( fname , wrapper . output ) ;
873
899
874
- return pyPromise ;
900
+ // Also output documentation for the Python API
901
+ let docfname = wrapper . getDocFilename ( ) ;
902
+ //console.log(docfname);
903
+ //let docPromise = Promise.resolve();
904
+ let docPromise = fse . outputFile ( docfname , wrapper . getDocOutput ( ) ) ;
905
+
906
+ return Promise . all ( [ pyPromise , docPromise ] ) ;
875
907
}
876
908
877
909
function createPythonModuleInitFile ( modulePath ) {
878
910
879
911
const dirname = path . dirname ( modulePath ) ;
880
912
const pyInitFilePath = path . resolve ( pySrcDir , dirname , '__init__.py' ) ;
881
913
return fse . ensureFile ( pyInitFilePath ) ;
914
+ }
915
+
916
+
917
+
918
+
919
+ function writeDocModuleFiles ( ) {
920
+
921
+ console . log ( 'Writing document indices...' ) ;
922
+
923
+ const RE_AUTOGEN = / i n d e x .r s t / g;
924
+
925
+ function writeIndexForDir ( dirPath , isTopLevel ) {
926
+
927
+ const dirAbsPath = path . resolve ( docSrcDir , dirPath ) ;
928
+ let moduleName ;
929
+ if ( dirPath === '.' ) {
930
+ moduleName = 'pythreejs' ;
931
+ } else {
932
+ moduleName = path . basename ( dirPath ) ;
933
+ }
934
+
935
+ // Generate list of files in dir to include in module as toc entries
936
+ return fse . readdir ( dirAbsPath ) . then ( function ( dirFiles ) {
937
+
938
+ // sort directories first:
939
+ dirFiles = _ . sortBy ( dirFiles , filePath => {
940
+ return fse . statSync ( path . join ( dirAbsPath , filePath ) ) . isDirectory ( ) ? 0 : 1 ;
941
+ } ) ;
942
+
943
+ dirFiles = dirFiles . filter ( filePath => {
944
+ return ! filePath . match ( RE_AUTOGEN ) ;
945
+ } ) ;
946
+
947
+ // convert file paths to paths relative to dirPath
948
+ dirFiles = dirFiles . map ( filePath => {
949
+ if ( fse . statSync ( path . join ( dirAbsPath , filePath ) ) . isDirectory ( ) ) {
950
+ return `./${ filePath } /index` ;
951
+ }
952
+ // Need to use forward slash for RST:
953
+ return `./${ path . basename ( filePath ) } ` ;
954
+ } ) ;
955
+
956
+ // render template
957
+ const context = {
958
+ now : new Date ( ) ,
959
+ generatorScriptName : path . basename ( __filename ) ,
960
+ moduleName : moduleName ,
961
+ submodules : dirFiles ,
962
+ top_level : isTopLevel ,
963
+ } ;
964
+ const output = docIndexTemplate ( context ) ;
965
+ const outputPath = path . resolve ( docSrcDir , dirPath , 'index.rst' ) ;
966
+
967
+ return fse . outputFile ( outputPath , output ) ;
968
+
969
+ } ) ;
970
+ }
971
+
972
+ // map over all directories in js src dir
973
+ return mapPromiseFnOverGlob (
974
+ `**/` , // trailing slash globs for dirs only
975
+ function ( dirPath ) {
976
+ return writeIndexForDir ( dirPath , false ) ;
977
+ } ,
978
+ { cwd : docSrcDir , }
979
+ ) . then ( function ( ) {
980
+ // write top-level index (not included in above glob)
981
+ return writeIndexForDir ( '.' , true ) ;
982
+ } ) ;
882
983
883
984
}
884
985
@@ -890,6 +991,14 @@ function createTopLevelPythonModuleFile() {
890
991
'sage.py'
891
992
] ;
892
993
994
+ const ignoreDocFiles = [
995
+ 'enums' ,
996
+ 'pythreejs' ,
997
+ 'traits' ,
998
+ '_package' ,
999
+ '_version' ,
1000
+ ] ;
1001
+
893
1002
const modules = [ ] ;
894
1003
895
1004
return mapPromiseFnOverGlob ( '**/*.py' , function ( filePath ) {
@@ -917,8 +1026,16 @@ function createTopLevelPythonModuleFile() {
917
1026
importPath = '.' + moduleName ;
918
1027
}
919
1028
1029
+ let docPath ;
1030
+ if ( ignoreDocFiles . indexOf ( moduleName ) === - 1 ) {
1031
+ docPath = filePath . replace ( '_autogen' , '' ) . replace ( '.py' , '' ) + '_autogen' ;
1032
+ } else {
1033
+ docPath = '' ;
1034
+ }
1035
+
920
1036
modules . push ( {
921
1037
pyRelativePath : importPath ,
1038
+ docRelativePath : docPath ,
922
1039
} ) ;
923
1040
924
1041
} , {
@@ -979,6 +1096,9 @@ function createPythonFiles() {
979
1096
// Manually ensure base init file is created
980
1097
return createPythonModuleInitFile ( '_base/__init__' ) ;
981
1098
} )
1099
+ . then ( function ( ) {
1100
+ return writeDocModuleFiles ( ) ;
1101
+ } )
982
1102
. then ( function ( ) {
983
1103
// top level __init__.py file imports *all* pythreejs modules into namespace
984
1104
return createTopLevelPythonModuleFile ( ) ;
@@ -987,6 +1107,7 @@ function createPythonFiles() {
987
1107
}
988
1108
989
1109
1110
+
990
1111
function generateFiles ( ) {
991
1112
992
1113
return Promise . all ( [
0 commit comments