-
Notifications
You must be signed in to change notification settings - Fork 4
/
ploc.js
135 lines (111 loc) · 4.8 KB
/
ploc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
'use strict';
var ploc = {};
ploc.opts = {};
ploc.opts.minItemsForToc = 3;
ploc.utils = {};
ploc.utils.reverseString = function (string) {
return string.split("").reverse().join("");
};
ploc.utils.capitalizeString = function (string) {
return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
};
ploc.utils.getAnchor = function (name) {
return name.trim().toLowerCase().replace(/[^\w\- ]+/g, '').replace(/\s/g, '-').replace(/\-+$/, '');
};
// Helper function to get the doc data as JSON object - you can use this
// function to creata your own output instead of using ploc.getDoc(code).
ploc.getDocData = function (code) {
// We need to work on a reversed string to avoid to fetch too much text, so the keywords for package, function and so on are looking ugly...
var regexItem = /\/\*{2,}\s*((?:.|\s)+?)\s*\*{2,}\/\s*((?:.|\s)*?\s*([\w$#]+|".+?")(?:\.(?:[\w$#]+|".+?")){0,1}\s+(reggirt|epyt|erudecorp|noitcnuf|egakcap))\s*(?:(?:ECALPER\s+RO\s+){0,1}ETAERC){0,1}\s*$/gim;
var regexHeaderSetext = /(^(?:\s*(?:\r\n|\n|\r))* {0,3}\S.+(?:\r\n|\n|\r) {0,3}=+ *)(?:\r\n|\n|\r)/;
var regexHeaderAtx = /(^(?:\s*(?:\r\n|\n|\r))* {0,3}# +.+)(?:\r\n|\n|\r)/;
var regexLeadingWhitespace = /^(?:\s*(?:\r\n|\n|\r))*/;
var match;
var anchors = [];
var data = {};
data.header = '';
data.toc = (ploc.opts.tocStyles ? '<ul style="' + ploc.opts.tocStyles + '">\n' : '');
data.items = [];
code = ploc.utils.reverseString(code);
// Get base attributes.
if (!regexItem.test(code)) {
console.warn('PLOC: Document contains no code to process!');
} else {
// Reset regexItem index to find all occurrences with exec.
// Also see: https://www.tutorialspoint.com/javascript/regexItem_lastindex.htm
regexItem.lastIndex = 0;
while (match = regexItem.exec(code)) {
var item = {};
item.description = ploc.utils.reverseString(match[1])
.replace(/{{@}}/g, '@') // Special SQL*Plus replacements. SQL*Plus is reacting on those special
.replace(/{{#}}/g, '#') // characters when they occur as the first character in a line of code.
.replace(/{{\/}}/g, '/'); // That can be bad when you try to write Markdown with sample code.
item.signature = ploc.utils.reverseString(match[2]);
item.name = ploc.utils.reverseString(match[3]);
item.type = ploc.utils.capitalizeString(ploc.utils.reverseString(match[4]));
data.items.push(item);
}
}
// Calculate additional attributes.
data.items.reverse().forEach(function (item, i) {
// Process global document header, if provided in first item (index = 0).
if (i === 0) {
if (match = regexHeaderSetext.exec(data.items[i].description)) {
data.header = match[1];
data.items[i].description = data.items[i].description
.replace(regexHeaderSetext, '')
.replace(regexLeadingWhitespace, '');
}
else if (match = regexHeaderAtx.exec(data.items[i].description)) {
data.header = match[1];
data.items[i].description = data.items[i].description
.replace(regexHeaderAtx, '')
.replace(regexLeadingWhitespace, '');
}
}
// Define item header and anchor for TOC.
data.items[i].header = data.items[i].type + ' ' + data.items[i].name;
data.items[i].anchor = ploc.utils.getAnchor(data.items[i].header);
// Ensure unique anchors.
if (anchors.indexOf(data.items[i].anchor) !== -1) {
var j = 0;
var anchor = data.items[i].anchor;
while (anchors.indexOf(data.items[i].anchor) !== -1 && j++ <= 100) {
data.items[i].anchor = anchor + '-' + j;
}
}
anchors.push(data.items[i].anchor);
data.toc += (
ploc.opts.tocStyles ?
'<li><a href="#' + data.items[i].anchor + '">' + data.items[i].header + '</a></li>\n' :
'- [' + data.items[i].header + '](#' + data.items[i].anchor + ')\n'
);
});
data.toc += (ploc.opts.tocStyles ? '</ul>\n' : '');
return data;
};
// The main function to create the Markdown document.
ploc.getDoc = function (code) {
var doc = '';
var docData = ploc.getDocData(code);
var provideToc = (docData.items.length >= ploc.opts.minItemsForToc);
doc += (docData.header ? docData.header + '\n\n' : '');
doc += (provideToc ? docData.toc + '\n\n' : '');
docData.items.forEach(function (item, i) {
var level = (i === 0 && !docData.header ? 1 : 2);
doc += (
ploc.opts.autoHeaderIds ?
'<h' + level + '><a id="' + item.anchor + '"></a>' + item.header + '</h' + level + '>\n' +
'<!--' + (level === 1 ? '=' : '-').repeat((15 + item.header.length + item.anchor.length)) + '-->\n\n'
:
'#'.repeat(level) + ' ' + item.header + '\n\n'
) +
item.description + '\n\n' +
'SIGNATURE\n\n' +
'```sql\n' +
item.signature + '\n' +
'```\n\n\n';
});
return doc;
}
module.exports = ploc;