@menome/document-to-graph
Version:
Menome Technologies Inc: takes incoming text and turns it into a structure suitable for a graph
208 lines (171 loc) • 9.5 kB
JavaScript
const ht = require('./headerTypeEnum.js');
const hr = require("./headerRegexEnum");
const ct = require("./connectionTypeEnum");
/* ---------------------------------------------------------------------------------------------
// Object.defineProperty
// Hashing function for generating hash value from string
// REQUIREMENTS:
// By: Menome
// Date: 201106
// HACK:: TODO : - this function is duplicated from sentencestograph -
*/
Object.defineProperty(String.prototype, 'hashCode2', {
value: function () {
var hash = 0, i, chr;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
});
/* ---------------------------------------------------------------------------------------------
// DocumentToGraph -
// Identifies headings and text segments
// REQUIREMENTS:
// - list must be sorted
// - items must have a Header pattern
// By: Menome
// Date: 201106
// iterate through the segemented text.
// Identify headers and demarkate them from text
6 Stakeholder Engagement
6.1 General
The pipeline operator shall maintain a process and a plan for communication and engagement with internal and
external stakeholders regarding risk identification and management, safety performance, and as appropriate, other
PSMS elements. The plan shall identify the organization’s stakeholders, both internal and external, and the
communication responsibilities of pipeline operator personnel.
Stakeholder engagement plans shall identify specific objectives and the personnel responsible for sharing and
receiving information. The operator shall identify the types of information to be shared and how it is valuable in
improving pipeline safety.
6.2 Internal
The pipeline operator shall establish processes to communicate the importance of meeting requirements of the
PSMS to appropriate functions within the organization. Employees and contractors shall understand the policies,
goals, objectives, and procedures pertinent to their work that are driven by the PSMS.
The pipeline operator shall maintain a process for employees and contractor personnel to raise concerns to
management and make recommendations for improvements in risk identification, prevention, and mitigation.
Management shall promote an environment encouraging two-way communication. Management shall also implement
a process for communicating and applying lessons learned.
10 API RECOMMENDED PRACTICE 1173
6.3 External
Javascript object pattern
{indexNumber:i,textSegment:'text',connectionNodeType:'RequirementStatement',depth:1,type:HEADING1,indexName:'Name'};
-----------------------------------------------------------------------------------------------*/
function DocumentToGraph(segments, rootNode) {
let segmentDefinition;
const segmentDefinitions = [];
let rootSegment= rootNode;
// first - clear out any blank or 0 length text lines
var textSegmentArray=filter_array(segments);
// Loop through groupedSegments generate segment definitions
for (let i = 0; i < textSegmentArray.length; i++) {
// create object for segmentDefinition
segmentDefinition = {
indexNumber: i,
textSegment: textSegmentArray[i],
connectionNodeType: ct.connectionType.TopicHeading,
type:ht.HeaderType.TEXT,
code:'',
parentCode:''
};
if(i===0) priorSegment=rootSegment;
let THREE_SPACES = " ";
if (segmentDefinition.textSegment.match(hr.HeaderRegex.Heading1)) {
// Base headings map to Root connection type Parent
segmentDefinition.connectionNodeType = rootNode.connectionNodeType;
segmentDefinition.type = ht.HeaderType.HEADING1
segmentDefinition.indexName = segmentDefinition.textSegment.match(hr.HeaderRegex.Heading1)[0]
segmentDefinition.code = segmentDefinition.textSegment.split(" ")[0]
segmentDefinition.parentCode = rootSegment.code;
priorSegment = segmentDefinition;
}
else if (segmentDefinition.textSegment.match(hr.HeaderRegex.Heading2)) {
segmentDefinition.type = ht.HeaderType.HEADING2
segmentDefinition.connectionNodeType = ct.connectionType.TopicHeading
segmentDefinition.indexName = segmentDefinition.textSegment.match(hr.HeaderRegex.Heading2)[0]
segmentDefinition.code = segmentDefinition.textSegment.split(" ")[0]
// parent code will be parent code from heading1
//var parent=segmentDefinitions.filter(segement => segement.type === ht.HeaderType.HEADING1 );
//segmentDefinition.parentCode = parent[parent.length - 1].code;
var parentCode=segmentDefinition.code.split('.');
parentCode=parentCode.slice(0,parentCode.length-1);
segmentDefinition.parentCode=parentCode.join('.');
priorSegment = segmentDefinition;
}
else if (segmentDefinition.textSegment.match(hr.HeaderRegex.Heading3)) {
segmentDefinition.type = ht.HeaderType.HEADING3
segmentDefinition.connectionNodeType = ct.connectionType.TopicHeading
segmentDefinition.indexName = segmentDefinition.textSegment.match(hr.HeaderRegex.Heading3)[0]
segmentDefinition.code = segmentDefinition.textSegment.split(" ")[0]
// parent code will be parent code from header2
//var parent=segmentDefinitions.filter(segement => segement.type === ht.HeaderType.HEADING2 );
//segmentDefinition.parentCode = parent[0].code;
var parentCode=segmentDefinition.code.split('.');
parentCode=parentCode.slice(0,parentCode.length-1);
segmentDefinition.parentCode=parentCode.join('.');
priorSegment = segmentDefinition;
}
else if (segmentDefinition.textSegment.match(hr.HeaderRegex.PageHeadingPageNumberLeft)) {
segmentDefinition.type = ht.HeaderType.PAGE_HEADING;
// root level nodes will connect to the parent requirement collection
segmentDefinition.connectionNodeType = ct.connectionType.RequirementCollection;
segmentDefinition.textSegment =segmentDefinition.textSegment.trim();
const splitLocation = segmentDefinition.textSegment.indexOf(THREE_SPACES);
segmentDefinition.indexName = segmentDefinition.textSegment.substring(splitLocation).trim();
// use a string hash to generate a code for the text
var hashIndex = segmentDefinition.textSegment.hashCode2();
if (hashIndex < 0) hashIndex = hashIndex * -1;
segmentDefinition.parentCode = priorSegment.code;
segmentDefinition.code=hashIndex + '.' + segmentDefinition.parentCode;
}
else if (segmentDefinition.textSegment.match(hr.HeaderRegex.PageHeadingPageNumberRight)) {
segmentDefinition.type = ht.HeaderType.PAGE_HEADING
segmentDefinition.connectionNodeType = ct.connectionType.PageHeading
segmentDefinition.textSegment =segmentDefinition.textSegment.trim()
const splitLocation = segmentDefinition.textSegment.lastIndexOf(THREE_SPACES)
segmentDefinition.indexName = segmentDefinition.textSegment.substring(0, splitLocation).trim()
// use a string hash to generate a code for the text
var hashIndex = segmentDefinition.textSegment.hashCode2();
if (hashIndex < 0) hashIndex = hashIndex * -1;
segmentDefinition.parentCode = priorSegment.code;
segmentDefinition.code=hashIndex + '.' + segmentDefinition.parentCode;
}
else // its text
{
segmentDefinition.type = ht.HeaderType.TEXT;
segmentDefinition.connectionNodeType = ct.connectionType.RequirementStatement;
segmentDefinition.indexName = segmentDefinition.textSegment.substring(0,25);
var hashIndex = segmentDefinition.textSegment.hashCode2();
if (hashIndex < 0) hashIndex = hashIndex * -1;
// text - means prior segment's code is the text segment parent
segmentDefinition.parentCode = priorSegment.code;
segmentDefinition.code= segmentDefinition.parentCode + '.'+ hashIndex;
}
segmentDefinitions.push(segmentDefinition);
}
return segmentDefinitions;
}
/* ---------------------------------------------------------------------------------------------
// filter_array -
// removes nulls, '' and 0 length strings.
// REQUIREMENTS:
// - list must be sorted
// - items must have a Header pattern
// By: Menome
// Date: 201106
*/
function filter_array(test_array) {
var index = -1,
arr_length = test_array ? test_array.length : 0,
resIndex = -1,
result = [];
while (++index < arr_length) {
var value = test_array[index];
if (value) {
result[++resIndex] = value;
}
}
return result;
}
module.exports = {DocumentToGraph: DocumentToGraph};