After running a basic JSDoc compile/render from Node.js:
jsdoc file1.js file2.js
I get a well-formatted document using the default template inside a directory "out". Almost all is as expected!
But when opening the document, it always says "Home" on the index.html page, has no content on that initial page, and has "Home" in the sidebar navigation.
How and where do I notate the name of the project so that it replaces "Home"? I would also like to see a project description, as well as author and copyright information.
It seems like the most basic of things to do in a JSDoc, but I can't find the information! I have tried the following, based on some random article I found on the internet:
/**
* This JavaScript file contains foo bar baz...
*
* #projectname Project Name
* #version 0.1
* #author Greg Pettit
* #copyright 2015
*
*/
But I get no love.
[edited to add:]
Discovered the #file / #fileOverview / #overview (all synonyms) directive, which is somewhat helpful as I can now describe and set copyright/author information for each file:
/**
* #file Project description which renders below the individual filename and therefore isn't a real overview blurb.
*
* #version 0.1
* #author Greg Pettit
* #copyright 2015
*
*/
That leaves 2 "problems" to solve still:
An overview description; I think #file takes care of most of my needs, but since it's per-file, I would still like an "introduction" type paragraph or overview paragraph that appears before the descriptions of included files.
Replacing that "Home" text with custom text
Generate Home page
Create markdown file README.md
Generating jsdoc:
$ jsdoc path/to/js path/to/readme/README.md
To read more about this visit official documentation
Change 'Home' text
I don't think this is a proper way to do it but this works.
If you have jsdoc installed in your project find template file in your working directory, mine was:
./node_modules/jsdoc/templates/default/publish.js
Then search for 'Home' with search command and replace with your text, next step is to specify template when generating jsdoc:
$ jsdoc ./src/scripts/ ./README.md -t node_modules/jsdoc/templates/default/
I can't comment so I'll add a note here to clarify how to do all of the things in the original question without altering the default template, based on the directions in a file found in the "\npm\node_modules\jsdoc\templates" folder, which explains how to create your own templates. The steps to change the "Home" headings in the generated js documentation to project specific headings (e.g., "MyDescription") and include the overview blurb at the top of main page are outlined below.
Steps
First, to get the general overview onto the top of the main page of the js documentation, you would make the simple text file named README.md written in Markdown as per the answer and link above. The entire text appears at the top of the page if the path to that file is included in the command line as shown above or a reference is added in a file named conf.json, in which case you can use jsdoc -c pathTo\conf.json for the command line (see example in item 4 below). (As the link explains, you could make a file with any name or extension as long as it is in Markdown and you tell jsdoc where to find it).
Copy the folder and contents for the default template (\npm\node_modules\jsdoc\templates\default) to a new directory, renaming the new folder to something like myTemplate.
Using the advice from above for Change 'Home' text, search the file named publish.js inside the new myTemplate folder and replace "Home" with "MyDescription". Two points to note here: the file name has to remain publish.js, and "Home" appeared in two places in my original "publish.js", in the line var nav = '<h2>Home</h2>'; and the line starting generate('Home',....
Tell the jsdoc generator where to find your custom template (myTemplate folder) and your overview file ("README.md"). You can add -t pathTo\myTemplate to the command line, or you can use a very short command line, jsdoc -c pathTo\conf.json if you create a file named conf.json in a text editor, something like the file below, which specifies the source, destination, etc. for the documentation. That file puts the overview into the main page by telling the doc generator to use README.md in the "source" section, and changes the headings from "Home" to the new heading, "MyDescription", using the new myTemplate folder in the "opts" section.
{
"tags": {
"allowUnknownTags": true,
"dictionaries": ["jsdoc","closure"]
},
"opts": {
"template": "pathTo/myTemplate",
"destination": "pathTo/myJScriptDocs",
"recurse": true
},
"source": {
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_",
"include": ["pathTo/myJSSources", "pathTo/README.md"]
},
"plugins": [],
"templates": {
"cleverLinks": false,
"monospaceLinks": false
}
}
You can also add an #file (or #fileOverview) to one or more of your source files.
All of the files' overview sections will be included on the JSDoc home page. If you also feed your README to JSDoc, the file overviews will be placed after the Readme content.
Example:
/**
* #file index.js is the root file for the example.
* It kicks things off.
* #author Your name goes here
* #see DocuSign Developer Center
*/
'Home' is harcoded (passed as title when generating the index) in the default template so there is no variable or config that you could set to modify this title.
If multiple people are generating/editing the docs, editing the node_modules is an obvious no-go.
It's enough to create a layout.tmpl (or a full custom template, if you're using one), point JSDoc to it (CLI option or config file) and replace <?js= title ?> with <?js= title==='Home' ? 'Your Title' : title ?>.
I had a similar but different problem with the Home Page. The small in-house JavaScript library that I wanted to generate JSDOC pages for was just a collection of global functions, and I didn't want to display the home page at all. I only want to display the global.html page.
Since we use NPM to install JSDOC, I didn't want to duplicate the entire module just to customize the global page. Instead, I copied just the layout page to a separate directory and specified that in my jsdoc.json config file:
"templates" : {
"default": {
"layoutFile": "config/layout.tmpl"
}
}
and then I edited layout.tmpl to add a <style> tag, with a style rule that does not display the link to the home.html page:
nav > h2 {
display: none;
}
Related
I have the following function where I am trying to search the 'title' and 'summary' for something entered in the search bar. However, this throws an error that 'const' is not allowed here.
import { frontMatter as blogs1 } from './blog/*.mdx';
const filteredBlogPosts = blogs1
.sort(
(a, b) =>
Number(new Date(b.publishedAt)) - Number(new Date(a.publishedAt))
)
.filter((frontMatter) =>
const concat = frontMatter.summary + frontMatter.title, #Error. How to search for both title and summary for entered search value?
concat.toLowerCase().includes(searchValue.toLowerCase()),
);
The blogs1 that gets imported has content like this - how do I make the content part of the MDX file searchable as well? At least with title and summary, I have a key-value pair. But how to make text in content of this MDX file (anything after 'Table of Contents' in example below) searchable too?
---
title: 'abc def ghi'
publishedAt: '2020-09-06'
summary: "xyz mnk."
image: '/static/images/chapter18/1.png'
---
## Table of Contents
1. [Introduction](#introduction)
2. [Alphabet and xyz](#comparing-alphabet-and-xyz)
3. [ABC](#abc)
# Introduction
This is an attempt at something.<br/>
![Test](/static/images/chapter18/2.png)<br/>
It's very hard to answer your question exactly because you're stuck in a path where you need to step backwards and consider the whole "architecture" side.
For search, I'd recommend to use fuse.js, see this tutorial.
I do have a search feature on my website and it is searching the MDX sources: articles and npm package readme's.
Conceptually, you have to make a script which fs.readFileSync-reads all MDX, extracts the JSON-like "list" (from fuse.js terminology) and writes it into a file (I make it .ts). Then, React app imports it and runs the fuse client-side.
In npm scripts, in package.json, we end up with two scripts, instead of "build": "next build", you prepend the search index generation script, something like: "build": "node './ops/generate.mjs' && next build".
I even published my "list" fuse string generation function as an npm package, see extract-search-index. It takes a string, article's source, which you get by fs.fileReadSync and then slice from the second instance of ---, that's just under the front-matter.
I estimate the total "weight" of the search feature ends up around 200KB, but it's loaded in async then cached; Remix manages it well.
I have a hybrid AngularJS/Angular application that will take some time to complete migration to fully be an Angular app. While this process occurs, I'd like to move away from the previous build system to using the CLI and webpack to manage all of the old AngularJS scripts as well. This is possible as I've done it before by adding all of my scripts to the scripts section in angular.json like the following:
"scripts": [
"src/app/angularjs/app.js",
"src/app/angularjs/controllers/main.js",
"src/app/angularjs/services/someService.js",
"src/app/angularjs/controllers/someController.js"
],
This works well and the CLI builds via ng serve and ng build continue to work for the hybrid bootstrapped app as needed. The problem I'm running into now is manually listing each file for the current application I'm migrating is not ideal. I have hundreds of scripts that need to be added, and what I need is to be able to use a globbing pattern like the following:
"scripts": [
"src/app/angularjs/**/*.js"
],
The problem is this syntax from what I can tell is not supported. The glob pattern is supported in the assets section of angular.json as stated here but not in the scripts section: https://angular.io/guide/workspace-config#assets-configuration
In the scripts section I can't find a similar solution. It does have an expanded object API, but nothing that solves the problem I can tell to select all .js files from a particular directory as listed here: https://angular.io/guide/workspace-config#styles-and-scripts-configuration
Is it possible by some means to use a glob pattern or similar approach to select all files of a directory for the scripts section in angular.json so I don't have to manually list out hundreds of individual .js files?
The Bad News
The scripts section does not support the same glob patterns that the assets section does.
The Good News(?)
Since you're transitioning away from AngularJS, you hopefully won't have any new files to import in the future, so you could just generate the list of all the files you need to import.
Make your way to the src/app/angular directory and run the following:
find . -iregex '.*\.\(js\)' -printf '"%p",\n'
That will give you your list, already quoted for your convenience. You may need to do a quick search/replace (changing "." to "src/app/angularjs"), and don't forget to remove the last comma, but once you've done that once you should be all set.
The Extra News
You can further filter out unwanted files with -not, so (per your comment) you might do:
find . -iregex '^.*\.js$' -not -iregex '^.*_test\.js$' -printf '"%p",\n'
And that should give you all your .js files without your _test.js files.
KISS
Of course, this isn't a complex pattern, so as #atconway points out below, this will work just as well:
find . -iname "*.js" -not -iname "*_test.js" -printf '"%p",\n'
I'll keep the above, though, for use in situations where the full power of regex might come in handy.
I wanted to extend an anser of #JasonVerber and here is a Node.JS code and therefore (I believe) cross-platform.
Firstly install find package and then save contents from the snippet in some file.js.
Afterwards, specify paths so that they resolve to where you wan't to get your files from and where to put the resulting file to.
After that node file-name.js and this will save all found file paths to the resultPath in result.txt ready to Ctrl+A, Ctrl+C, Ctrl+V.
const find = require('find');
const path = require('path');
const fs = require('fs');
// BEFORE USAGE INSTALL `find` package
// Path to the folder where to look for files
const sourcePath = path.resolve(path.join(__dirname, 'cordova-app', 'src'));
// Path that will be removed from absolute path to files
const pathToRemove = path.resolve(path.join(__dirname, 'cordova-app'));
// Path where to put result.txt
const resultPath = path.resolve(path.join(__dirname, './result.txt'));
// Collects the file paths
const res = [];
// Path with replaced \ onto /
const pathToRemovehReplaced = pathToRemove.replace(/\\/g, '/');
// Get all fils that match a regex
find.eachfile(/\.js$/, sourcePath, file => {
// First remove all \ with / and then remove the path from root to source so that only relative path is left
const fileReplaced = file.replace(/\\/g, '/').replace(`${pathToRemovehReplaced}/`, '');
// Surround with quoutes
res.push(`"${fileReplaced}"`);
}).end(() => {
// Write file and concatenate results with newline and commas
fs.writeFileSync(resultPath, res.join(',\r\n'), 'utf8');
console.log('DONE!');
});
The result I got while testing (/\.ts$/ for regex)
"src/app/app.component.spec.ts",
"src/app/app.component.ts",
"src/app/app.module.ts",
"src/environments/environment.prod.ts",
"src/environments/environment.ts",
"src/main.ts",
"src/polyfills.ts",
"src/test.ts"
With Sublime Text, is it possible to use different syntax for a same file extension depending on the currently opened project ?
Example :
Project A : file.js contains classic Javascript
Project B : file.js contains JSX
How can I obtain JavaScript syntax for project A and Babel syntax for Project B?
Just for background (which you likely already know), Sublime Text applies a syntax via the extension of the file, and overriding that requires you to use View > Syntax > Open all with current extension as... from the menu. This creates a syntax specific override which appears in a specific file name and is thus not directly overrideable on a per project basis.
That said, it is possible to swap the syntax on your own (e.g. via the command palette) which opens the possibility of a plugin being able to do this for you. There may be an existing plugin that does this in PackageControl, but for reference purposes, here is an example based on something I'm using for a similar purpose.
The following assumes that you're using the Babel plugin to get your syntax highlighting, since you mention Babel. This would need to be modified if this is not the package you're using. This could also be modified to similarly do a swap for a different type of file if desired.
To use this, select Tools > Developer > New Plugin from the menu and replace the entire contents of the sample file with the code below, and then save it as a python file in the directory that Sublime suggests (which should be in Packages\User). I named mine js_syntax_swap.py, but the name doesn't matter as long as the extension is .py:
import sublime, sublime_plugin
# Standard Sublime JavaScript syntax file is:
# 'Packages/JavaScript/JavaScript.sublime-syntax'
#
# The Babel package syntax is:
# 'Packages/Babel/JavaScript (Babel).sublime-syntax'
class JavaScriptSyntaxSwap (sublime_plugin.EventListener):
def modify_syntax (self, view):
if view.window () == None:
return
swapSyntax = view.settings ().get ('using_babel_js', False)
curSyntax = view.settings ().get ('syntax')
variables = view.window ().extract_variables ()
extension = variables['file_extension']
if swapSyntax is True and extension == 'js' and "Babel" not in curSyntax:
view.set_syntax_file ('Packages/Babel/JavaScript (Babel).sublime-syntax')
def on_load (self, view):
self.modify_syntax (view)
def on_post_save (self, view):
self.modify_syntax (view)
With this in place, if you choose Project > Edit Project from the menu, you can include a using_babel_js setting to enable the plugin for JavaScript files in that project. An example might be:
{
"folders":
[
{
"path": "."
}
],
"settings":
{
"using_babel_js": true
}
}
What this is doing is checking every time you load or save a file to see if it should swap the syntax from the default to the Babel JSX syntax, which it does only for files with the extension .js that are not already using Babel as the syntax.
Im working with suitescript 2.0 (netsuite) and Im wondering how would I go about including a custom class (object) using it's new API. For example I'm trying to include a controller class but getting a "module not found" warning. See snippet below
/**
*#NApiVersion 2.x
*#NScriptType Restlet
*/
define(['N/record', 'N/error', "src/My_Controller"],
function (record, error, My_Controller) {
var controller = new My_Controller();
...
The error message is: Module does not exist: src/My_Controller.js when in fact it is there. Is this the correct way to do it?
The NetSuite help center has nothing about inclusion of custom/ancillary javascript
You reference custom modules by their path in the File Cabinet. This can be either relative to the current file or relative to the root of the File Cabinet. So it will look something like:
define(['N/record', 'N/error', '/SuiteScripts/my-project/src/My_Controller'], ...)
or:
define(['N/record', 'N/error', './src/My_Controller'], ...)
Assuming that src is in the same directory as this file.
I'm using requireJS to load scripts. It has this detail in the docs:
The path that is used for a module name should not include the .js
extension, since the path mapping could be for a directory.
In my app, I map all of my script files in a config path, because they're dynamically generated at runtime (my scripts start life as things like order.js but become things like order.min.b25a571965d02d9c54871b7636ca1c5e.js (this is a hash of the file contents, for cachebusting purposes).
In some cases, require will add a second .js extension to the end of these paths. Although I generate the dynamic paths on the server side and then populate the config path, I have to then write some extra javascript code to remove the .js extension from the problematic files.
Reading the requireJS docs, I really don't understand why you'd ever want the path mapping to be used for a directory. Does this mean it's possible to somehow load an entire directory's worth of files in one call? I don't get it.
Does anybody know if it's possible to just force require to stop adding .js to file paths so I don't have to hack around it?
thanks.
UPDATE: added some code samples as requested.
This is inside my HTML file (it's a Scala project so we can't write these variables directly into a .js file):
foo.js.modules = {
order : '#Static("javascripts/order.min.js")',
reqwest : 'http://5.foo.appspot.com/js/libs/reqwest',
bean : 'http://4.foo.appspot.com/js/libs/bean.min',
detect : 'order!http://4.foo.appspot.com/js/detect/detect.js',
images : 'order!http://4.foo.appspot.com/js/detect/images.js',
basicTemplate : '#Static("javascripts/libs/basicTemplate.min.js")',
trailExpander : '#Static("javascripts/libs/trailExpander.min.js")',
fetchDiscussion : '#Static("javascripts/libs/fetchDiscussion.min.js")'
mostPopular : '#Static("javascripts/libs/mostPopular.min.js")'
};
Then inside my main.js:
requirejs.config({
paths: foo.js.modules
});
require([foo.js.modules.detect, foo.js.modules.images, "bean"],
function(detect, images, bean) {
// do stuff
});
In the example above, I have to use the string "bean" (which refers to the require path) rather than my direct object (like the others use foo.js.modules.bar) otherwise I get the extra .js appended.
Hope this makes sense.
If you don't feel like adding a dependency on noext, you can also just append a dummy query string to the path to prevent the .js extension from being appended, as in:
require.config({
paths: {
'signalr-hubs': '/signalr/hubs?noext'
}
});
This is what the noext plugin does.
requirejs' noext plugin:
Load scripts without appending ".js" extension, useful for dynamic scripts...
Documentation
check the examples folder. All the info you probably need will be inside comments or on the example code itself.
Basic usage
Put the plugins inside the baseUrl folder (usually same folder as the main.js file) or create an alias to the plugin location:
require.config({
paths : {
//create alias to plugins (not needed if plugins are on the baseUrl)
async: 'lib/require/async',
font: 'lib/require/font',
goog: 'lib/require/goog',
image: 'lib/require/image',
json: 'lib/require/json',
noext: 'lib/require/noext',
mdown: 'lib/require/mdown',
propertyParser : 'lib/require/propertyParser',
markdownConverter : 'lib/Markdown.Converter'
}
});
//use plugins as if they were at baseUrl
define([
'image!awsum.jpg',
'json!data/foo.json',
'noext!js/bar.php',
'mdown!data/lorem_ipsum.md',
'async!http://maps.google.com/maps/api/js?sensor=false',
'goog!visualization,1,packages:[corechart,geochart]',
'goog!search,1',
'font!google,families:[Tangerine,Cantarell]'
], function(awsum, foo, bar, loremIpsum){
//all dependencies are loaded (including gmaps and other google apis)
}
);
I am using requirejs server side with node.js. The noext plugin does not work for me. I suspect this is because it tries to add ?noext to a url and we have filenames instead of urls serverside.
I need to name my files .njs or .model to separate them from static .js files. Hopefully the author will update requirejs to not force automatic .js file extension conventions on the users.
Meanwhile here is a quick patch to disable this behavior.
To apply this patch (against version 2.1.15 of node_modules/requirejs/bin/r.js) :
Save in a file called disableAutoExt.diff or whatever and open a terminal
cd path/to/node_modules/
patch -p1 < path/to/disableAutoExt.diff
add disableAutoExt: true, to your requirejs.config: requirejs.config({disableAutoExt: true,});
Now we can do require(["test/index.njs", ...] ... and get back to work.
Save this patch in disableAutoExt.diff :
--- mod/node_modules/requirejs/bin/r.js 2014-09-07 20:54:07.000000000 -0400
+++ node_modules/requirejs/bin/r.js 2014-12-11 09:33:21.000000000 -0500
## -1884,6 +1884,10 ##
//Delegates to req.load. Broken out as a separate function to
//allow overriding in the optimizer.
load: function (id, url) {
+ if (config.disableAutoExt && url.match(/\..*\.js$/)) {
+ url = url.replace(/\.js$/, '');
+ }
+
req.load(context, id, url);
},
The patch simply adds the following around line 1887 to node_modules/requirejs/bin/r.js:
if (config.disableAutoExt && url.match(/\..*\.js$/)) {
url = url.replace(/\.js$/, '');
}
UPDATE: Improved patch by moving url change deeper in the code so it no longer causes a hang after calling undef on a module. Needed undef because:
To disable caching of modules when developing with node.js add this to your main app file:
requirejs.onResourceLoad = function(context, map)
{
requirejs.undef(map.name);
};