medium-export
Version:
a cli to convert medium stories to markdown
63 lines (62 loc) • 2.62 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import prompts from 'prompts';
import { JSDOM } from 'jsdom';
import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeRemark from 'rehype-remark';
import remarkStringify from 'remark-stringify';
export const resolveOptions = (opts) => __awaiter(void 0, void 0, void 0, function* () {
let { story, output } = opts;
if (!story) {
const { _story } = yield prompts({
type: 'text',
name: '_story',
message: 'Medium story URL',
});
story = _story;
}
if (!output) {
const { _output } = yield prompts({
type: 'text',
name: '_output',
message: 'Output path',
});
output = _output;
}
return Object.assign(Object.assign({}, opts), { story, output });
});
export const getMediumMarkdown = (opts) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const { story, author, image } = opts;
const resp = yield fetch(story);
const html = yield resp.text();
const { document } = new JSDOM(html).window;
const content = document.querySelector('article section');
// * remove author info
if (!author)
(_a = content.querySelector('h1+div')) === null || _a === void 0 ? void 0 : _a.remove();
// * remove images
if (!image)
content.querySelectorAll('figure:has(img)').forEach(figure => figure.remove());
// * wrap pre tags' content with a code tag
content.querySelectorAll('pre').forEach(pre => {
pre.innerHTML = `<code>${pre.innerHTML
.trim()
.replace(/<br>/g, '\n') // * replace <br> with line feeds
.replace(/<[^>]*>/g, '')}</code>`; // * strip html tags
});
const vfile = yield unified()
.use(rehypeParse)
.use(rehypeRemark)
.use(remarkStringify)
.process(content.outerHTML);
return [document.title, String(vfile)];
});