| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- // Licensed to Cloudera, Inc. under one
- // or more contributor license agreements. See the NOTICE file
- // distributed with this work for additional information
- // regarding copyright ownership. Cloudera, Inc. licenses this file
- // to you under the Apache License, Version 2.0 (the
- // "License"); you may not use this file except in compliance
- // with the License. You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- const fs = require('fs');
- const LOG_NAME = 'extractorUtils.js';
- /**
- * Utility function to read a text file using UTF-8 encoding
- *
- * @param {string} path
- * @return {Promise} - A promise, fulfilled with the file contents or rejected
- */
- const readFile = path =>
- new Promise((resolve, reject) => {
- fs.readFile(path, 'utf8', (err, contents) => {
- if (err) {
- console.log("%s: Could not read file '%s'", LOG_NAME, path);
- console.log(err);
- reject(err);
- } else {
- resolve(contents);
- }
- });
- });
- /**
- * Returns the parent folder of a file path
- *
- * @param {string} path
- * @return {string}
- */
- const getParentFolder = path => path.substring(0, path.lastIndexOf('/') + 1);
- /**
- * Checks arguments given on the command line, breaks the program if required ones are missing.
- *
- * @param {Object} program - See command lib
- */
- const checkArguments = program => {
- if (!program.folder) {
- console.log('\n No folder supplied!');
- program.help();
- }
- if (!program.ditamap) {
- console.log('\n No ditamap file supplied!');
- program.help();
- }
- if (!program.output) {
- console.log('\n No output path supplied!');
- program.help();
- }
- };
- /**
- * Helper method to check if a node has attributes that aren't empty
- *
- * @param node
- * @param {string|string[]} attributes
- * @return {boolean}
- */
- const hasAttributes = (node, attributes) => {
- if (typeof attributes === 'string') {
- attributes = [attributes];
- }
- return attributes.every(
- attribute =>
- node.attr(attribute) &&
- node
- .attr(attribute)
- .value()
- .trim()
- );
- };
- /**
- * Helper method to remove all attributes of a noce
- *
- * @param node
- */
- const removeAllAttributes = node => {
- node.attrs().forEach(attr => {
- attr.remove();
- });
- };
- /**
- * Helper method to find a fragment with specified anchorId within a topic. If the anchor ID isn't found it will return
- * the closes possible parent.
- *
- * @param topic
- * @param anchorId
- * @return {[DocFragment]}
- */
- const findFragmentInTopic = (topic, anchorId) => {
- if (!anchorId) {
- return topic.fragment;
- }
- const splitIds = anchorId.split('/');
- const findDeep = (fragments, id) => {
- let foundFragment = undefined;
- fragments.some(fragment => {
- if (fragment.id === id) {
- foundFragment = fragment;
- return true;
- }
- foundFragment = findDeep(fragment.children, id);
- return foundFragment;
- });
- return foundFragment;
- };
- let fragmentsToSearch = [topic.fragment];
- let result = undefined;
- while (splitIds.length) {
- result = findDeep(fragmentsToSearch, splitIds.shift());
- if (!result) {
- break;
- }
- fragmentsToSearch = result.children;
- }
- if (!result) {
- console.log("%s: Could not find id '%s' in ref '%s'", LOG_NAME, anchorId, topic.ref);
- return topic.fragment;
- }
- return result;
- };
- /**
- * @typedef {Object} FragmentSearchResult
- * @property {boolean} partOfTree - Whether or not the found fragment is part of the main tree
- * @property {DocFragment} [fragment]
- */
- /**
- *
- * @param {DitamapParseResult[]} parseResults
- * @param {string} ref
- * @param {string} [anchorId]
- * @return {FragmentSearchResult}
- */
- const findFragment = (parseResults, ref, anchorId) => {
- const result = { partOfTree: true, fragment: undefined };
- parseResults.some(parseResult => {
- const topic = parseResult.topicIndex[ref];
- if (topic) {
- result.fragment = findFragmentInTopic(topic, anchorId);
- } else {
- result.partOfTree = false;
- }
- return result.fragment;
- });
- return result;
- };
- module.exports = {
- readFile: readFile,
- getParentFolder: getParentFolder,
- checkArguments: checkArguments,
- hasAttributes: hasAttributes,
- removeAllAttributes: removeAllAttributes,
- findFragment: findFragment
- };
|