Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,22 @@ <h1>Export reddit post to markdown format</h1>
/>
</div>

<label>Acquisition option :</label>
<div class="form-check form-check-inine">
<input type="checkbox" class="form-check-input" id="postLoadComments" />
<label class="form-check-label" for="postLoadComments">
Load additional comments in seperate request if comment depth greather than 10
</label>
</div>

<label>Export style :</label>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="exportOption" id="treeOption" checked/>
<label class="form-check-label" for="treeOption">Tree style</label>
<input class="form-check-input" type="radio" name="exportOption" id="listOption"/>
<label class="form-check-label" for="listOption">List style</label>
<input class="form-check-input" type="radio" name="exportOption" id="blockOption" />
<label class="form-check-label" for="blockOption">Blockquote style</label>
</div>

<label>Export option :</label>
Expand Down
97 changes: 75 additions & 22 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ let output = '';
let style = 0;
let escapeNewLine = false;
let spaceComment = false;
let postLoadAdditionalComments = false
var selectedProxy = 'auto';

// CORS Proxy configurations
Expand Down Expand Up @@ -36,7 +37,7 @@ const onDocumentReady = () => {
};

const getQueryParamUrl = () => new URLSearchParams(window.location.search).get(
'url') ?? null;
'url') ?? null;
const getFieldUrl = () => document.getElementById('url-field').value;

function formatRedditJsonUrl(url) {
Expand Down Expand Up @@ -188,7 +189,7 @@ async function fetchData(url) {
const comments = data[1].data.children;
displayTitle(post);
output += '\n\n## Comments\n\n';
comments.forEach(displayComment);
comments.forEach((comment) => displayComment(comment, null));

console.log('Done');
let output_display = document.getElementById('output-display');
Expand Down Expand Up @@ -216,11 +217,27 @@ async function fetchData(url) {
}
}

function loadMoreComments(url, parentid, depthInd) {
const h2 = new XMLHttpRequest()
//to allow the newly loaded comments to appear in the correct place, this call has to be synchronous
h2.open('GET', `${url}/${parentid}.json`, false);
//setting a desired response type is not supported for non-async calls
//h2.responseType = 'json';
h2.send();

//as a response type cannot be set, the result needs to be parsed to JSON manually.
const d2 = JSON.parse(h2.responseText)
const comments = d2[1].data.children[0].data.replies.data.children;
comments.forEach((comment) => displayComment(comment, depthInd));
}

function setStyle() {
if (document.getElementById('treeOption').checked) {
style = 0;
} else {
} else if (document.getElementById('listOption').checked) {
style = 1;
} else {
style = 2
}

if (document.getElementById('escapeNewLine').checked) {
Expand All @@ -235,6 +252,12 @@ function setStyle() {
spaceComment = false;
}

if (document.getElementById('postLoadComments').checked) {
postLoadAdditionalComments = true;
} else {
postLoadAdditionalComments = false;
}

selectedProxy = document.getElementById('proxySelection').value;
}

Expand Down Expand Up @@ -266,7 +289,7 @@ function download(text, name, type) {
document.getElementById('copyButton').removeAttribute('disabled');
let download_button = document.getElementById('downloadButton');
download_button.removeAttribute('disabled');
let file = new Blob([text], {type: type});
let file = new Blob([text], { type: type });
download_button.href = URL.createObjectURL(file);
download_button.download = name;
}
Expand All @@ -288,39 +311,69 @@ function formatComment(text) {
}
}

function displayComment(comment, index) {
function displayComment(comment, preexistingDepth = null) {
let currentDepth = preexistingDepth != null ? preexistingDepth : comment.data.depth;
let depthTag
if (style == 0) {
depthTag = '─'.repeat(comment.data.depth);
if (depthTag != '') {
output += `├${depthTag} `;
if (currentDepth > 0) {
depthTag = `├${'─'.repeat(currentDepth)} `;
} else {
output += `##### `;
depthTag = `##### `;
}
} else {
depthTag = '\t'.repeat(comment.data.depth);
if (depthTag != '') {
output += `${depthTag}- `;
} else if (style == 1) {
if (currentDepth > 0) {
depthTag = `${'\t'.repeat(currentDepth)}- `;
} else {
output += `- `;
depthTag = `- `;
}
}
else {
depthTag = '>'.repeat(currentDepth + 1);
}

if (comment.data.body) {
console.log(formatComment(comment.data.body));
output += `${formatComment(
comment.data.body)} ⏤ by *${comment.data.author}* (↑ ${
comment.data.ups
}/ ↓ ${comment.data.downs})\n`;
if (style < 2) {
output += `${depthTag}${formatComment(
comment.data.body)} ⏤ by *${comment.data.author}* (↑ ${comment.data.ups
}/ ↓ ${comment.data.downs})\n`;
}
else {
if (currentDepth == 0) {
/*to make it unambiguous if two block quotes should be seperate or one and the same
they need to be seperated by at least one character not part of either (I chose NBSP)*/
output += '&amp;nbsp;\n\n'
}
output += `${depthTag}\n${depthTag}#### [**${comment.data.author}** ${comment.data.author_flair_text ? `'***${comment.data.author_flair_text}***' ` : ''}(↑ ${comment.data.ups}/ ↓ ${comment.data.downs}) @${new Date(comment.data.created_utc * 1000).toISOString()}${comment.data.edited ? ` (edited @${new Date(comment.data.edited * 1000).toISOString()})` : ''}](${getFieldUrl()}/${comment.data.id})\n${depthTag}\n${depthTag}${formatComment(comment.data.body).trimEnd().replace(/!&lt;/g, '!&amp;lt;').replace(/&gt;!/g, '&amp;gt;!').replace(/\n/g, `\n${depthTag}`)}\n`;
//the !&lt;/&gt;! replacement is to force retain the escaping of </> in spoiler tags to avoid confusion between blockquotes and spoilers
}
} else if (comment.kind === "more") {
let parentID = comment.data.parent_id.substring(3);
if (postLoadAdditionalComments) {
loadMoreComments(getFieldUrl(), parentID, currentDepth); ""
}
else {
output += `${depthTag}${style == 2 ? `\n${depthTag}#### ` : ''}comment depth-limit (${currentDepth}) reached. [view on reddit](${getFieldUrl()}/${parentID})\n`;
}
} else {
output += 'deleted \n';
output += `${depthTag}${style == 2 ? `\n${depthTag}#### ` : ''}deleted\n`;
}

if (comment.data.replies) {
const subComment = comment.data.replies.data.children;
subComment.forEach(displayComment);
const subComments = comment.data.replies.data.children;
subComments.forEach((subComment) => displayComment(subComment, preexistingDepth != null ? preexistingDepth + 1 : null));
}
if (style == 2) {
/*do note, this is NOT depthTag, it has one fewer symbol
this is required forcibly split the block-quotes for two comments on the same level.
It technically generates more markers than strictly necessary,
but those extra ones are not harmful, and depending on your interpretation,
can even more sematically correct than if they were absent*/
output += '>'.repeat(currentDepth);
output += '\n'
}

if (comment.data.depth == 0 && comment.data.replies) {
if (currentDepth == 0 && comment.data.replies) {
if (style == 0) {
output += '└────\n\n';
}
Expand Down