closes #1852 Add configurable link disambuators Add a service to disambiguate docs by module Add a service to disambiguate docs that are deprecated
		
			
				
	
	
		
			84 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var path = require('canonical-path');
 | |
| 
 | |
| /**
 | |
|  * @dgService getLinkInfo
 | |
|  * @description
 | |
|  * Get link information to a document that matches the given url
 | |
|  * @kind function
 | |
|  * @param  {String} url   The url to match
 | |
|  * @param  {String} title An optional title to return in the link information
 | |
|  * @return {Object}       The link information
 | |
|  *
 | |
|  * @property {boolean} relativeLinks Whether we expect the links to be relative to the originating doc
 | |
|  * @property {array<function(url, title, currentDoc, ambiguousDocs) : array} disambiguators a collection of functions
 | |
|  *           that attempt to resolve ambiguous links. Each disambiguator returns a new collection of docs with
 | |
|  *           unwanted ambiguous docs removed (see moduleScopeLinkDisambiguator service for an example).
 | |
|  */
 | |
| module.exports = function getLinkInfo(getDocFromAlias, encodeCodeBlock, log) {
 | |
| 
 | |
|   getLinkInfoImpl.disambiguators = [];
 | |
| 
 | |
|   return getLinkInfoImpl;
 | |
| 
 | |
|   function getLinkInfoImpl(url, title, currentDoc) {
 | |
|     var linkInfo = {
 | |
|       url: url,
 | |
|       type: 'url',
 | |
|       valid: true,
 | |
|       title: title || url
 | |
|     };
 | |
| 
 | |
|     if ( !url ) {
 | |
|       throw new Error('Invalid url');
 | |
|     }
 | |
| 
 | |
|     var docs = getDocFromAlias(url, currentDoc);
 | |
| 
 | |
|     // Give each disambiguator a chance to reduce the number of ambiguous docs
 | |
|     docs = getLinkInfoImpl.disambiguators.reduce(function(docs, disambiguator) {
 | |
|       return disambiguator(url, title, currentDoc, docs);
 | |
|     }, docs);
 | |
| 
 | |
|     if ( !getLinkInfoImpl.useFirstAmbiguousLink && docs.length > 1 ) {
 | |
| 
 | |
|       linkInfo.valid = false;
 | |
|       linkInfo.errorType = 'ambiguous';
 | |
|       linkInfo.error = 'Ambiguous link: "' + url + '".\n' +
 | |
|         docs.reduce(function(msg, doc) { return msg + '\n  "' + doc.id + '" ('+ doc.docType + ') : (' + doc.path + ' / ' + doc.fileInfo.relativePath + ')'; }, 'Matching docs: ');
 | |
| 
 | |
|     } else if ( docs.length >= 1 ) {
 | |
| 
 | |
|       linkInfo.url = docs[0].path;
 | |
|       linkInfo.title = title || encodeCodeBlock(docs[0].name, true);
 | |
|       linkInfo.type = 'doc';
 | |
| 
 | |
|       if ( getLinkInfoImpl.relativeLinks && currentDoc && currentDoc.path ) {
 | |
|         var currentFolder = path.dirname(currentDoc.path);
 | |
|         var docFolder = path.dirname(linkInfo.url);
 | |
|         var relativeFolder = path.relative(path.join('/', currentFolder), path.join('/', docFolder));
 | |
|         linkInfo.url = path.join(relativeFolder, path.basename(linkInfo.url));
 | |
|         log.debug(currentDoc.path, docs[0].path, linkInfo.url);
 | |
|       }
 | |
| 
 | |
|     } else if ( url.indexOf('#') > 0 ) {
 | |
|       var pathAndHash = url.split('#');
 | |
|       linkInfo = getLinkInfoImpl(pathAndHash[0], title, currentDoc);
 | |
|       linkInfo.url = linkInfo.url + '#' + pathAndHash[1];
 | |
|       return linkInfo;
 | |
| 
 | |
|     } else if ( url.indexOf('/') === -1 && url.indexOf('#') !== 0 ) {
 | |
| 
 | |
|       linkInfo.valid = false;
 | |
|       linkInfo.errorType = 'missing';
 | |
|       linkInfo.error = 'Invalid link (does not match any doc): "' + url + '"';
 | |
| 
 | |
|     } else {
 | |
| 
 | |
|       linkInfo.title = title || (( url.indexOf('#') === 0 ) ? url.substring(1) : path.basename(url, '.html'));
 | |
| 
 | |
|     }
 | |
| 
 | |
|     return linkInfo;
 | |
|   };
 | |
| 
 | |
| }; |