mirror of
https://github.com/10h30/wordpress-export-to-markdown.git
synced 2026-07-16 21:23:46 +09:00
Convert to ES modules and related changes
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import * as luxon from 'luxon';
|
||||
|
||||
import * as settings from './settings.js';
|
||||
|
||||
// get author, without decoding
|
||||
// WordPress doesn't allow funky characters in usernames anyway
|
||||
export function getAuthor(post) {
|
||||
return post.data.creator[0];
|
||||
}
|
||||
|
||||
// get array of decoded category names, filtered as specified in settings
|
||||
export function getCategories(post) {
|
||||
if (!post.data.category) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const categories = post.data.category
|
||||
.filter(category => category.$.domain === 'category')
|
||||
.map(({ $: attributes }) => decodeURIComponent(attributes.nicename));
|
||||
|
||||
return categories.filter(category => !settings.filter_categories.includes(category));
|
||||
}
|
||||
|
||||
// get cover image filename, previously decoded and set on post.meta
|
||||
// this one is unique as it relies on special logic executed by the parser
|
||||
export function getCoverImage(post) {
|
||||
return post.meta.coverImage;
|
||||
}
|
||||
|
||||
// get post date, optionally formatted as specified in settings
|
||||
// this value is also used for year/month folders, date prefixes, etc. as needed
|
||||
export function getDate(post) {
|
||||
const dateTime = luxon.DateTime.fromRFC2822(post.data.pubDate[0], { zone: settings.custom_date_timezone });
|
||||
|
||||
if (settings.custom_date_formatting) {
|
||||
return dateTime.toFormat(settings.custom_date_formatting);
|
||||
} else if (settings.include_time_with_date) {
|
||||
return dateTime.toISO();
|
||||
} else {
|
||||
return dateTime.toISODate();
|
||||
}
|
||||
}
|
||||
|
||||
// get excerpt, not decoded, newlines collapsed
|
||||
export function getExcerpt(post) {
|
||||
return post.data.encoded[1].replace(/[\r\n]+/gm, ' ');
|
||||
}
|
||||
|
||||
// get ID
|
||||
export function getId(post) {
|
||||
return post.data.post_id[0];
|
||||
}
|
||||
|
||||
// get slug, previously decoded and set on post.meta
|
||||
export function getSlug(post) {
|
||||
return post.meta.slug;
|
||||
}
|
||||
|
||||
// get array of decoded tag names
|
||||
export function getTags(post) {
|
||||
if (!post.data.category) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const categories = post.data.category
|
||||
.filter(category => category.$.domain === 'post_tag')
|
||||
.map(({ $: attributes }) => decodeURIComponent(attributes.nicename));
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
// get simple post title, but not decoded like other frontmatter string fields
|
||||
export function getTitle(post) {
|
||||
return post.data.title[0];
|
||||
}
|
||||
|
||||
// get type, often this will always be "post"
|
||||
// but can also be "page" or other custom types
|
||||
export function getType(post) {
|
||||
return post.data.post_type[0];
|
||||
}
|
||||
+10
-15
@@ -1,15 +1,12 @@
|
||||
const fs = require('fs');
|
||||
const requireDirectory = require('require-directory');
|
||||
const xml2js = require('xml2js');
|
||||
import fs from 'fs';
|
||||
import xml2js from 'xml2js';
|
||||
|
||||
const shared = require('./shared');
|
||||
const settings = require('./settings');
|
||||
const translator = require('./translator');
|
||||
import * as shared from './shared.js';
|
||||
import * as settings from './settings.js';
|
||||
import * as translator from './translator.js';
|
||||
import * as frontmatter from './frontmatter.js';
|
||||
|
||||
// dynamically requires all frontmatter getters
|
||||
const frontmatterGetters = requireDirectory(module, './frontmatter', { recurse: false });
|
||||
|
||||
async function parseFilePromise(config) {
|
||||
export async function parseFilePromise(config) {
|
||||
console.log('\nParsing...');
|
||||
const content = await fs.promises.readFile(config.input, 'utf8');
|
||||
const allData = await xml2js.parseStringPromise(content, {
|
||||
@@ -174,19 +171,17 @@ function mergeImagesIntoPosts(images, posts) {
|
||||
|
||||
function populateFrontmatter(posts) {
|
||||
posts.forEach(post => {
|
||||
const frontmatter = {};
|
||||
post.frontmatter = {};
|
||||
settings.frontmatter_fields.forEach(field => {
|
||||
const [key, alias] = field.split(':');
|
||||
|
||||
let frontmatterGetter = frontmatterGetters[key];
|
||||
let frontmatterGetter = frontmatter['get' + key.replace(/^./, (match) => match.toUpperCase())];
|
||||
if (!frontmatterGetter) {
|
||||
throw `Could not find a frontmatter getter named "${key}".`;
|
||||
}
|
||||
|
||||
frontmatter[alias || key] = frontmatterGetter(post);
|
||||
post.frontmatter[alias || key] = frontmatterGetter(post);
|
||||
});
|
||||
post.frontmatter = frontmatter;
|
||||
});
|
||||
}
|
||||
|
||||
exports.parseFilePromise = parseFilePromise;
|
||||
|
||||
+8
-8
@@ -2,7 +2,7 @@
|
||||
// Order is preserved. If a field has an empty value, it will not be included. You can rename a
|
||||
// field by providing an alias after a ':'. For example, 'date:created' will include 'date' in
|
||||
// frontmatter, but renamed to 'created'.
|
||||
exports.frontmatter_fields = [
|
||||
export const frontmatter_fields = [
|
||||
'title',
|
||||
'date',
|
||||
'categories',
|
||||
@@ -12,29 +12,29 @@ exports.frontmatter_fields = [
|
||||
|
||||
// Time in ms to wait between requesting image files. Increase this if you see timeouts or
|
||||
// server errors.
|
||||
exports.image_file_request_delay = 500;
|
||||
export const image_file_request_delay = 500;
|
||||
|
||||
// Time in ms to wait between saving Markdown files. Increase this if your file system becomes
|
||||
// overloaded.
|
||||
exports.markdown_file_write_delay = 25;
|
||||
export const markdown_file_write_delay = 25;
|
||||
|
||||
// Enable this to include time with post dates. For example, "2020-12-25" would become
|
||||
// "2020-12-25T11:20:35.000Z".
|
||||
exports.include_time_with_date = false;
|
||||
export const include_time_with_date = false;
|
||||
|
||||
// Override post date formatting with a custom formatting string (for example: 'yyyy LLL dd').
|
||||
// Tokens are documented here: https://moment.github.io/luxon/#/parsing?id=table-of-tokens. If
|
||||
// set, this takes precedence over include_time_with_date.
|
||||
exports.custom_date_formatting = '';
|
||||
export const custom_date_formatting = '';
|
||||
|
||||
// Specify the timezone used for post dates. See available zone values and examples here:
|
||||
// https://moment.github.io/luxon/#/zones?id=specifying-a-zone.
|
||||
exports.custom_date_timezone = 'utc';
|
||||
export const custom_date_timezone = 'utc';
|
||||
|
||||
// Categories to be excluded from post frontmatter. This does not filter out posts themselves,
|
||||
// just the categories listed in their frontmatter.
|
||||
exports.filter_categories = ['uncategorized'];
|
||||
export const filter_categories = ['uncategorized'];
|
||||
|
||||
// Strict SSL is enabled as the safe default when downloading images, but will not work with
|
||||
// self-signed servers. You can disable it if you're getting a "self-signed certificate" error.
|
||||
exports.strict_ssl = true;
|
||||
export const strict_ssl = true;
|
||||
|
||||
+1
-3
@@ -1,4 +1,4 @@
|
||||
function getFilenameFromUrl(url) {
|
||||
export function getFilenameFromUrl(url) {
|
||||
let filename = url.split('/').slice(-1)[0];
|
||||
try {
|
||||
filename = decodeURIComponent(filename)
|
||||
@@ -8,5 +8,3 @@ function getFilenameFromUrl(url) {
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
exports.getFilenameFromUrl = getFilenameFromUrl;
|
||||
|
||||
+5
-8
@@ -1,7 +1,7 @@
|
||||
const turndown = require('turndown');
|
||||
const turndownPluginGfm = require('turndown-plugin-gfm');
|
||||
import turndown from 'turndown';
|
||||
import turndownPluginGfm from 'turndown-plugin-gfm';
|
||||
|
||||
function initTurndownService() {
|
||||
export function initTurndownService() {
|
||||
const turndownService = new turndown({
|
||||
headingStyle: 'atx',
|
||||
bulletListMarker: '-',
|
||||
@@ -73,7 +73,7 @@ function initTurndownService() {
|
||||
// preserve <figcaption>
|
||||
turndownService.addRule('figcaption', {
|
||||
filter: 'figcaption',
|
||||
replacement: (content, node) => {
|
||||
replacement: (content) => {
|
||||
// extra newlines are necessary for markdown and HTML to render correctly together
|
||||
return '\n\n<figcaption>\n\n' + content + '\n\n</figcaption>\n\n';
|
||||
}
|
||||
@@ -94,7 +94,7 @@ function initTurndownService() {
|
||||
return turndownService;
|
||||
}
|
||||
|
||||
function getPostContent(postData, turndownService, config) {
|
||||
export function getPostContent(postData, turndownService, config) {
|
||||
let content = postData.encoded[0];
|
||||
|
||||
// insert an empty div element between double line breaks
|
||||
@@ -124,6 +124,3 @@ function getPostContent(postData, turndownService, config) {
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
exports.initTurndownService = initTurndownService;
|
||||
exports.getPostContent = getPostContent;
|
||||
|
||||
+7
-12
@@ -1,10 +1,8 @@
|
||||
const camelcase = require('camelcase');
|
||||
const commander = require('commander');
|
||||
const fs = require('fs');
|
||||
const inquirer = require('inquirer');
|
||||
const path = require('path');
|
||||
|
||||
const package = require('../package.json');
|
||||
import camelcase from 'camelcase';
|
||||
import * as commander from 'commander';
|
||||
import fs from 'fs';
|
||||
import inquirer from 'inquirer';
|
||||
import path from 'path';
|
||||
|
||||
// all user options for command line and wizard are declared here
|
||||
const options = [
|
||||
@@ -77,7 +75,7 @@ const options = [
|
||||
}
|
||||
];
|
||||
|
||||
async function getConfig(argv) {
|
||||
export async function getConfig(argv) {
|
||||
extendOptionsData();
|
||||
const unaliasedArgv = replaceAliases(argv);
|
||||
const opts = parseCommandLine(unaliasedArgv);
|
||||
@@ -160,7 +158,6 @@ function parseCommandLine(argv) {
|
||||
// setup for help output
|
||||
commander.program
|
||||
.name('node index.js')
|
||||
.version('v' + package.version, '-v, --version', 'Display version number')
|
||||
.helpOption('-h, --help', 'See the thing you\'re looking at right now')
|
||||
.addHelpText('after', '\nMore documentation is at https://github.com/lonekorean/wordpress-export-to-markdown');
|
||||
|
||||
@@ -180,7 +177,7 @@ function parseCommandLine(argv) {
|
||||
}
|
||||
|
||||
function coerceBoolean(value) {
|
||||
return !['false', 'no', '0'].includes(value.toLowerCase());
|
||||
return !['false', 'no', '0'].includes(value.toString().toLowerCase());
|
||||
}
|
||||
|
||||
function coercePath(value) {
|
||||
@@ -197,5 +194,3 @@ function validateFile(value) {
|
||||
|
||||
return isValid ? true : 'Unable to find file: ' + path.resolve(value);
|
||||
}
|
||||
|
||||
exports.getConfig = getConfig;
|
||||
|
||||
+10
-12
@@ -1,15 +1,15 @@
|
||||
const axios = require('axios');
|
||||
const chalk = require('chalk');
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
const https = require('https');
|
||||
const luxon = require('luxon');
|
||||
const path = require('path');
|
||||
import axios from 'axios';
|
||||
import chalk from 'chalk';
|
||||
import fs from 'fs';
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
import * as luxon from 'luxon';
|
||||
import path from 'path';
|
||||
|
||||
const shared = require('./shared');
|
||||
const settings = require('./settings');
|
||||
import * as shared from './shared.js';
|
||||
import * as settings from './settings.js';
|
||||
|
||||
async function writeFilesPromise(posts, config) {
|
||||
export async function writeFilesPromise(posts, config) {
|
||||
await writeMarkdownFilesPromise(posts, config);
|
||||
await writeImageFilesPromise(posts, config);
|
||||
}
|
||||
@@ -215,5 +215,3 @@ function getPostPath(post, config) {
|
||||
function checkFile(path) {
|
||||
return fs.existsSync(path);
|
||||
}
|
||||
|
||||
exports.writeFilesPromise = writeFilesPromise;
|
||||
|
||||
Reference in New Issue
Block a user