@@ -9,6 +9,8 @@ var Filter = require('./filter');
99var Parser = require ( './parser' ) ;
1010var Worker = require ( './worker' ) ;
1111
12+ var PluginLoader = require ( './plugin_loader' ) ;
13+
1214var FileError = require ( './errors/file_error' ) ;
1315var ParserError = require ( './errors/parser_error' ) ;
1416var WorkerError = require ( './errors/worker_error' ) ;
@@ -90,7 +92,10 @@ var app = {
9092 apisuccessstructure : './workers/api_success_structure.js' ,
9193 apisuccesstitle : './workers/api_success_title.js' ,
9294 apiuse : './workers/api_use.js'
93- }
95+ } ,
96+ hooks : { } ,
97+ addHook : addHook ,
98+ hook : applyHook
9499} ;
95100
96101var defaultGenerator = {
@@ -159,6 +164,7 @@ function parse(options) {
159164 app . languages = _ . defaults ( { } , options . languages , app . languages ) ;
160165 app . parsers = _ . defaults ( { } , options . parsers , app . parsers ) ;
161166 app . workers = _ . defaults ( { } , options . workers , app . workers ) ;
167+ app . hooks = _ . defaults ( { } , options . hooks , app . hooks ) ;
162168
163169 // options
164170 app . options = options ;
@@ -181,10 +187,17 @@ function parse(options) {
181187 app . log . verbose ( 'apidoc-core version: ' + packageJson . version ) ;
182188 app . log . verbose ( 'apidoc-spec version: ' + getSpecificationVersion ( ) ) ;
183189
190+ new PluginLoader ( app ) ;
191+
184192 var parser = new Parser ( app ) ;
185193 var worker = new Worker ( app ) ;
186194 var filter = new Filter ( app ) ;
187195
196+ // Make them available for plugins
197+ app . parser = parser ;
198+ app . worker = worker ;
199+ app . filter = filter ;
200+
188201 // if input option for source is an array of folders,
189202 // parse each folder in the order provided.
190203 app . log . verbose ( 'run parser' ) ;
@@ -345,6 +358,55 @@ function setPackageInfos(packageInfos) {
345358 app . packageInfos = packageInfos ;
346359}
347360
361+ /**
362+ * Register a hook function.
363+ *
364+ * @param {String } name Name of the hook. Hook overview: https://github.com/apidoc/apidoc-core/hooks.md
365+ * @param {Function } func Callback function.
366+ * @param {Integer } [priority=100] Hook priority. Lower value will be executed first.
367+ * Same value overwrite a previously defined hook.
368+ */
369+ function addHook ( name , func , priority ) {
370+ priority = priority || 100 ;
371+
372+ if ( ! app . hooks [ name ] )
373+ app . hooks [ name ] = [ ] ;
374+
375+ app . log . debug ( 'add hook: ' + name + ' [' + priority + ']' ) ;
376+
377+ // Find position and overwrite same priority
378+ var replace = 0 ;
379+ var pos = 0 ;
380+ app . hooks [ name ] . forEach ( function ( entry , index ) {
381+ if ( priority === entry . priority ) {
382+ pos = index ;
383+ replace = 1 ;
384+ } else if ( priority > entry . priority ) {
385+ pos = index + 1 ;
386+ }
387+ } ) ;
388+
389+ app . hooks [ name ] . splice ( pos , replace , {
390+ func : func ,
391+ priority : priority
392+ } ) ;
393+ }
394+
395+ /**
396+ * Execute a hook.
397+ */
398+ function applyHook ( name /* , ...args */ ) {
399+ if ( ! app . hooks [ name ] )
400+ return Array . prototype . slice . call ( arguments , 1 , 2 ) [ 0 ] ;
401+
402+ var args = Array . prototype . slice . call ( arguments , 1 ) ;
403+ app . hooks [ name ] . forEach ( function ( hook ) {
404+ hook [ 'func' ] . apply ( this , args ) ;
405+ } ) ;
406+ return args [ 0 ] ;
407+ }
408+
409+
348410module . exports = {
349411 getSpecificationVersion : getSpecificationVersion ,
350412 parse : parse ,
0 commit comments