Запретить узлу » fs «вставлять» r » в разрывы строк

#javascript #node.js

Вопрос:

Я не очень хорошо разбираюсь в NodeJS, но мне удалось собрать базовый серверный скрипт, чтобы получить файлы уценки из папки и написать файл JSON со всем содержимым frontmatter. Проблема в том, что в результирующем JSON есть r или rnr для некоторых разрывов строк, а не для других, что вызывает проблемы в моем материале.

Например:

 {
"section": "Medicalr",
}
 

отличается от :

 {
"section": "Medical",
}
 

в результате в моей документации создаются дубликаты «Глав».

Я пытался:

  • проверка наличия лишних пробелов
  • вручную удалив все r в JSON, что временно устраняет проблему

Я использую :

  • Узел v14.15.2
  • macOS 1.2.3
  • VSCode 1.55.2
  • CRA 4
  • nodemon 2.0.6 для запуска сервера и отслеживания изменений

Это сервер узла:

 const path = require('path');
const fs = require('fs');

const dirPath = path.join(__dirname, '../library/');
let postList = [];

const getPosts = () => {
  fs.readdir(dirPath, (err, files) => {
    if (err) {
      return console.log('Failed to list contents of directory: '   err);
    }
    let fileList = [];
    files.forEach((file, i) => {
      let obj = {};
      let post;
      fs.readFile(`${dirPath}/${file}`, 'utf8', (err, contents) => {
        const getMetadataIndices = (acc, elem, i) => {
          if (/^---/.test(elem)) {
            acc.push(i);
          }
          return acc;
        };
        const parseMetadata = ({ lines, metadataIndices }) => {
          if (metadataIndices.length > 0) {
            let metadata = lines.slice(
              metadataIndices[0]   1,
              metadataIndices[1]
            );
            metadata.forEach((line) => {
              obj[line.split(': ')[0]] = line.split(': ')[1];
            });
            return obj;
          }
        };

        const parseContent = ({ lines, metadataIndices }) => {
          if (metadataIndices.length > 0) {
            lines = lines.slice(metadataIndices[1]   1, lines.length);
          }
          return lines.join('n');
        };
        const lines = contents.split('n');
        const metadataIndices = lines.reduce(getMetadataIndices, []);
        const metadata = parseMetadata({ lines, metadataIndices });

        const content = parseContent({ lines, metadataIndices });

        // H2 headings
        const h2 = /^## (.*$)/gim;
        const headings = content.matchAll(h2);
        var headingsArrays = [...headings].map((m) => m.slice(1));
        var mergedHeadings = [].concat.apply([], headingsArrays);

        post = {
          name: metadata.title ? metadata.title : 'No title given',
          updated: metadata.updated ? metadata.updated : 'No update given',
          content: content ? content : 'No content given',
          path: metadata.path ? metadata.path : '404',
          section: metadata.section ? metadata.section : 'Misc',
          headings: mergedHeadings ? mergedHeadings : []
        };
        postList.push(post);
        fileList.push(i);
        if (fileList.length === files.length) {
          const sortedList = postList.sort((a, b) => {
            return a.id < b.id ? 1 : -1;
          });
          let data = JSON.stringify(sortedList);
          fs.writeFileSync('src/posts.json', data);
        }
      });
    });
  });
  return;
};

getPosts();

 

Я ценю любые советы, чтобы остановить r запись в JSON. Спасибо.

Комментарии:

1. Сработает ли что-то подобное lines.map(line => line.replace(/r$/, '') ? Это замена возвращаемого конца строки пустой строкой

2. Спасибо, @evolutionxbox, это сработало. Я надеялся предотвратить r , а не удалить их после того, как они были добавлены, но это работает нормально. Можете ли вы дать на это ответ?

3. Я бы предположил, что это не узел, добавляющий возвраты, вместо этого они существуют в самом файле?

4. @evolutionxbox вот чего я не понимаю — я вырезал все пробелы из переднего плана, скопировал и вставил также передний план, чтобы убедиться, что он точно такой же, перезапустил сервер, и все равно у одного объекта JSON был r , а у другого нет.

5. Скорее всего, это проблема с окончанием строки. Что вы увидите, если включите «невидимые персонажи»?

Ответ №1:

Это предложение от @evolutionxbox выше работает:

 const path = require('path');
const fs = require('fs');

const dirPath = path.join(__dirname, '../library/');
let postList = [];

const getPosts = () => {
  fs.readdir(dirPath, (err, files) => {
    if (err) {
      return console.log('Failed to list contents of directory: '   err);
    }
    let fileList = [];
    files.forEach((file, i) => {
      let obj = {};
      let post;
      fs.readFile(`${dirPath}/${file}`, 'utf8', (err, contents) => {
        const getMetadataIndices = (acc, elem, i) => {
          if (/^---/.test(elem)) {
            acc.push(i);
          }
          return acc;
        };
        const parseMetadata = ({ lines, metadataIndices }) => {
          if (metadataIndices.length > 0) {
            let metadata = lines
              .slice(metadataIndices[0]   1, metadataIndices[1])
              .map((line) => line.replace(/r$/, ''));
            metadata.forEach((line) => {
              obj[line.split(': ')[0]] = line.split(': ')[1];
            });
            return obj;
          }
        };

        const parseContent = ({ lines, metadataIndices }) => {
          if (metadataIndices.length > 0) {
            lines = lines.slice(metadataIndices[1]   1, lines.length);
          }
          return lines.join('n');
        };
        const lines = contents
          .split('n')
          .map((line) => line.replace(/r$/, ''));
        const metadataIndices = lines.reduce(getMetadataIndices, []);
        const metadata = parseMetadata({ lines, metadataIndices });

        const content = parseContent({ lines, metadataIndices });

        // H2 headings
        const h2 = /^## (.*$)/gim;
        const headings = content.matchAll(h2);
        var headingsArrays = [...headings].map((m) => m.slice(1));
        var mergedHeadings = [].concat.apply([], headingsArrays);

        post = {
          name: metadata.title ? metadata.title : 'No title given',
          updated: metadata.updated ? metadata.updated : 'No update given',
          content: content ? content : 'No content given',
          path: metadata.path ? metadata.path : '404',
          section: metadata.section ? metadata.section : 'Misc',
          headings: mergedHeadings ? mergedHeadings : []
        };
        postList.push(post);
        fileList.push(i);
        if (fileList.length === files.length) {
          const sortedList = postList.sort((a, b) => {
            return a.id < b.id ? 1 : -1;
          });
          let data = JSON.stringify(sortedList);
          fs.writeFileSync('src/posts.json', data);
        }
      });
    });
  });
  return;
};

getPosts();