splitFileBySections : function()

in packages/Ludown/lib/helpers.js [100:253]


    splitFileBySections : function(fileContent, log) {
        fileContent = helpers.sanitizeNewLines(fileContent);
        let linesInFile = fileContent.split(NEWLINE);
        let currentSection = '';
        let middleOfSection = false;
        let sectionsInFile = [];
        let currentSectionType = null; //PARSERCONSTS
        let inQnAAnswer = false;
        let lineIndex = 0;
        for(lineIndex in linesInFile) {
            let currentLine = linesInFile[lineIndex].trim();
            // QnA answer can be multi-line markdown. So (re)set the in answer flag
            if(currentLine.indexOf(PARSERCONSTS.ANSWER) === 0) {
                inQnAAnswer = !inQnAAnswer;
            }
            // if in QnA answer, just add the new line.
            if(inQnAAnswer) {
                currentSection += currentLine + NEWLINE;
                continue;
            }
            // skip line if it is just a comment
            if(currentLine.indexOf(PARSERCONSTS.COMMENT) === 0) {
                // Add support to parse application metadata if found
                let info = currentLine.split(/>[ ]*!#/g);
                if (info === undefined || info.length === 1) continue;
                if (currentSection !== null) {
                    let previousSection = currentSection.substring(0, currentSection.lastIndexOf(NEWLINE));
                    try {
                        sectionsInFile = validateAndPushCurrentBuffer(previousSection, sectionsInFile, currentSectionType, lineIndex, log);
                    } catch (err) {
                        throw (err);
                    }
                }
                currentSection = PARSERCONSTS.MODELINFO + info[1].trim() + NEWLINE;
                currentSectionType = PARSERCONSTS.MODELINFO;
                continue;
            }

            // skip line if it is blank
            if(currentLine === '') continue;

            // is this a FILEREF or URLREF section? 
            if((currentLine.indexOf(PARSERCONSTS.FILEREF) === 0) ||
            (currentLine.indexOf(PARSERCONSTS.URLREF) === 0)  ||
            (currentLine.indexOf(PARSERCONSTS.URLORFILEREF) === 0)) {
                // handle anything in currentSection buffer
                if(currentSection !== null) {
                    var previousSection = currentSection.substring(0, currentSection.lastIndexOf(NEWLINE));
                    try {
                        sectionsInFile = validateAndPushCurrentBuffer(previousSection, sectionsInFile, currentSectionType, lineIndex, log);
                    } catch (err) {
                        throw(err);
                    }
                }
                currentSection = null;
                sectionsInFile.push(currentLine);
                middleOfSection = false;
            } else if((currentLine.indexOf(PARSERCONSTS.INTENT) === 0)) {
                if(currentLine.indexOf(' ') === -1) {
                    ++lineIndex;
                    throw(new exception(retCode.errorCode.INVALID_INTENT, 'Error: Line #' + lineIndex + '. "' + currentLine + '" does not have valid intent definition'));
                }
                // handle anything in currentSection buffer
                if(currentSection !== null) {
                    let previousSection = currentSection.substring(0, currentSection.lastIndexOf(NEWLINE));
                    try {
                        sectionsInFile = validateAndPushCurrentBuffer(previousSection, sectionsInFile, currentSectionType, lineIndex, log);
                    } catch (err) {
                        throw(err);
                    }
                }
                middleOfSection = true;
                currentSectionType = PARSERCONSTS.INTENT;
                currentSection = currentLine + NEWLINE;
            } else if((currentLine.indexOf(PARSERCONSTS.ENTITY) === 0)) {
                // handle anything in currentSection buffer
                if(currentSection !== null) {
                    let previousSection = currentSection.substring(0, currentSection.lastIndexOf(NEWLINE));
                    try {
                        sectionsInFile = validateAndPushCurrentBuffer(previousSection, sectionsInFile, currentSectionType, lineIndex, log);
                    } catch (err) {
                        throw(err);
                    }
                } 
                // is this a valid entity definition? 
                // Entities must have $<entityName>:<entityType> format
                // List entities have $<entityName>:<normalizedvalue>= format
                // Phrase list entities have $<entityName>:phraseList format
                // only list entity and phrase list entity types can have multi-line definition
                if(currentLine.toLowerCase().includes(':')) {
                    // get entity name and type
                    // Fix for #1137. 
                    // Current code did not account for ':' in normalized values of list entities
                    let entityDef = currentLine.replace(PARSERCONSTS.ENTITY, '');
                    let entityType = entityDef.slice(entityDef.indexOf(':') + 1).trim();
                    // is entityType a phraseList? 
                    if(entityType.trim().toLowerCase().includes('phraselist') || entityType.trim().toLowerCase().includes('qna-alterations')) {
                        middleOfSection = true;
                        currentSectionType = PARSERCONSTS.ENTITY;
                        currentSection = currentLine + NEWLINE;
                    } else if(LUISBuiltInTypes.includes(entityType.trim()) || entityType.trim().toLowerCase() === 'simple') {
                        // this is a built in type definition. Just add it.
                        sectionsInFile.push(currentLine);
                        middleOfSection = false;
                        currentSection = null;
                    } else if((currentLine.indexOf('=') >= 0)) {
                        let getRolesAndType = this.getRolesAndType(entityType);
                        // this is a list entity type
                        if(getRolesAndType.entityType.trim().endsWith('=')){
                            middleOfSection = true;
                            currentSectionType = PARSERCONSTS.ENTITY;
                            currentSection = currentLine + NEWLINE;
                        } else {
                            // this has inline role definition
                            sectionsInFile.push(currentLine);
                            middleOfSection = false;
                            currentSection = null;
                        }
                    } else if (entityType.startsWith('/') && entityType.endsWith('/')) {
                        // this is a regex entity.
                        sectionsInFile.push(currentLine);
                        middleOfSection = false;
                        currentSection = null;
                    } else if (entityType.startsWith('[') && entityType.endsWith(']')) {
                        // this is a composite entity.
                        sectionsInFile.push(currentLine);
                        middleOfSection = false;
                        currentSection = null;
                    } else {
                        throw (new exception(retCode.errorCode.INVALID_INPUT, '[ERROR] Invalid entity definition for ' + currentLine));
                    }
                } else {
                    throw (new exception(retCode.errorCode.INVALID_INPUT, '[ERROR] Invalid entity definition for ' + currentLine));
                }
            } else {
                if(middleOfSection) {
                    currentSection += currentLine + NEWLINE;
                } else {
                    ++lineIndex;
                    throw(new exception(retCode.errorCode.INVALID_LINE,'Error: Line #' + lineIndex + ' is not part of a Intent/ Entity/ QnA'));
                }
            }
        }
        // handle anything in currentSection buffer
        if(currentSection !== null) {
            let previousSection = currentSection.substring(0, currentSection.lastIndexOf(NEWLINE));
            try {
                sectionsInFile = validateAndPushCurrentBuffer(previousSection, sectionsInFile, currentSectionType, lineIndex, log);
            } catch (err) {
                throw (err);
            }
        }
        return sectionsInFile;
    },