Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
HackettLai committed Aug 28, 2024
1 parent 64d7268 commit d3463b4
Show file tree
Hide file tree
Showing 19 changed files with 576 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# srt-to-word
Welcome to the SRT to DOCX Converter page, a user-friendly tool designed to transform your subtitle files into easily shareable Word documents. This versatile application allows you to upload SRT files, view the converted text directly within the webpage, and download a well-formatted DOCX file at your convenience.
- **Simple File Upload:** Easily upload your `.srt` subtitle files using the integrated file input option.
- **Instant Text Display:** Once converted, your subtitle text is displayed instantly on the page, formatted for easy viewing and ready for review.
- **Flexible Download Option:** Choose to download the converted document when you're ready—no need for immediate downloads after conversion.
- **Automatic Sentence Separation:** The tool intelligently processes your subtitles, breaking them down into paragraphs based on a variety of sentence-ending punctuation marks. This includes not only Western marks like ".", "!", "?", but also extends to Chinese punctuation marks such as "。", "!", and "?". Additionally, the tool now supports advanced separation techniques, such as recognizing ellipses "..." for pauses and breaks, and handling special cases like quoted speech and nested punctuation for more accurate paragraph division.
- **Readability Enhancements:** For enhanced readability, the converted text includes sensible line breaks and section spacing, making your subtitles easier to navigate.
- **Intuitive Interface:** The layout and functionality are designed to provide an effortless user experience, ensuring even those unfamiliar with DOCX conversions can navigate the process with ease.
Binary file added android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/.DS_Store
Binary file not shown.
Binary file added assets/footer-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/og-image.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions browserconfig.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#ffffff</TileColor>
</tile>
</msapplication>
</browserconfig>
24 changes: 24 additions & 0 deletions changelog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// JavaScript for modal
// Get the paragraph element
var versionParagraph = document.getElementById("version");

// Get the modal
var modal = document.getElementById("modal");

// When the user clicks on the paragraph, open the modal
versionParagraph.onclick = function() {
modal.style.display = "block";
}

// When the user clicks anywhere outside of the modal, close it
function closeModalHandler(event) {
if (event.target == modal || event.target == document.getElementById('closeModal')) {
modal.style.display = "none";
}
}

// Assign the function to window.onclick
window.onclick = closeModalHandler;

// Run the same function when clicking the element with id "closeModal"
document.getElementById('closeModal').onclick = closeModalHandler;
Binary file added favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added favicon.ico
Binary file not shown.
189 changes: 189 additions & 0 deletions function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
let docBlob; // Variable to store the docx blob
const btn_convert = document.getElementById("btn_convert");
const btn_download = document.getElementById("btn_download");
const fileInput = document.getElementById("srtFile");

// Enable the convert button once a file is selected
fileInput.addEventListener("change", function () {
if (fileInput.files.length > 0) {
btn_convert.disabled = false;
const resultDiv = document.getElementById("result_div");
resultDiv.innerHTML = ""; // Clear any previous content
} else {
btn_convert.disabled = true;
}
});

// Start conversion process when the button is clicked
btn_convert.addEventListener("click", convertSrtToDocx);

// Converts an uploaded SRT file to DOCX format
function convertSrtToDocx() {
const file = fileInput.files[0];
if (!file) {
alert("Please upload a .srt file first.");
return;
}

const reader = new FileReader();
reader.onload = function (event) {
const srtText = event.target.result;
const sentences = parseSrt(srtText);
displayResult(sentences);
};
reader.readAsText(file);

btn_convert.disabled = true;
btn_download.disabled = false;
}

// Parses the SRT text into an array of sentences
function parseSrt(srtContent) {
// Split the SRT content into lines
const lines = srtContent.split("\n");

// Initialize an empty array to store the trimmed dialogue
const trimmedDialogue = [];

// Initialize a variable to hold the current dialogue
let currentDialogue = [];

for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
// console.log("line: " + line);

// Skip the line number and timestamp lines
if (
line === "" ||
/^\d+$/.test(line) ||
/^(\d{2}):(\d{2}):(\d{2}),(\d{3}) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})$/.test(
line
)
) {
// If we have accumulated dialogue, push it to the trimmedDialogue array
if (currentDialogue.length > 0) {
let dialogue = currentDialogue.join(" ");

// Replace punctuation, handling "..." specifically
let result = dialogue
.replace(/(\.\.\.)(?=\s)/g, "$1\n") // Add a newline after "..." if followed by space
.replace(/(\.\.\.)(?=\s)/g, "$1\n") // Add a newline after "..." if followed by space
.replace(/([.?!])(?=\s)/g, "$1\n") // Add newline for other punctuation followed by space
.replace(/([])(?=[^\s])/g, "$1\n"); // Add newline for other punctuation not followed by space

trimmedDialogue.push(result + "\n");

currentDialogue = []; // Reset current dialogue
}
// If the line is an empty string, push a newline character
if (line === "") {
trimmedDialogue.push("\n");
}
continue;
}

// Accumulate the dialogue lines
currentDialogue.push(line);
}

// Push the last accumulated dialogue if any
if (currentDialogue.length > 0) {
let dialogue = currentDialogue.join(" ");

// Replace punctuation, handling "..." specifically
let result = dialogue
.replace(/(\.\.\.)(?=\s)/g, "$1\n") // Add a newline after "..." if followed by space
.replace(/(\.\.\.)(?=\s)/g, "$1\n") // Add a newline after "..." if followed by space
.replace(/([.?!])(?=\s)/g, "$1\n") // Add newline for other punctuation followed by space
.replace(/([])(?=[^\s])/g, "$1\n"); // Add newline for other punctuation not followed by space

trimmedDialogue.push(result + "\n");
}

// Add line breaks at punctuation marks and an empty line between each section
const processedDialogue = trimmedDialogue.map((dialogue) => {
// Split by punctuation marks and ensure correct spacing
// console.log("dialogue: " + dialogue);
return dialogue;
});

// Ensure an empty line between each section
const finalDialogue = processedDialogue.join("").split("\n\n").join("\n\n\n");

// Return the array of processed dialogues
return finalDialogue;
}

// Displays the parsed sentences in the result div
function displayResult(sentences) {
const resultDiv = document.getElementById("result_div");
resultDiv.innerHTML = ""; // Clear previous results

// Ensure sentences is a string
if (typeof sentences === "string") {
sentences.split("\n\n").forEach((sentence) => {
const p = document.createElement("p");
// Replace newline characters with <br> tags
p.innerHTML = sentence.replace(/\n/g, "<br>");
// If the sentence is empty, add a <br> tag
if (sentence === "") {
p.innerHTML = "<br>";
}
resultDiv.appendChild(p);
});
} else {
console.error("Expected a string but got:", sentences);
}

generateDocxFile(); // Prepare the docx file for download
}

// Generates a DOCX file from the parsed sentences
function generateDocxFile() {
const resultDiv = document.getElementById("result_div");
const paragraphs = resultDiv.querySelectorAll("p");

// Split each paragraph by <br> and create separate Paragraph objects
const children = Array.from(paragraphs).flatMap((p) => {
return p.innerHTML
.split(/<br\s*\/?>/gi)
.map((line) => new docx.Paragraph(line.trim()));
});

const doc = new docx.Document({
creator: "SRT to DOCX Converter",
title: "Subtitle Document",
sections: [
{
children: children,
},
],
});

docx.Packer.toBlob(doc).then((blob) => {
docBlob = blob; // Store the blob for later download
});
}

// Downloads the generated DOCX file
function downloadDocx() {
if (!docBlob) {
alert("Please convert a file before downloading.");
return;
}

const fileName = fileInput.files[0].name.replace(".srt", "");
const url = URL.createObjectURL(docBlob);
const link = document.createElement("a");
link.href = url;
link.download = `${fileName}.docx`;
link.click();

// Reset after download
fileInput.value = "";
const resultDiv = document.getElementById("result_div");
resultDiv.innerHTML = "";
btn_convert.disabled = true;
btn_download.disabled = true;
docBlob = null;
}
94 changes: 94 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SRT Extractor</title>
<!-- meta tags -->
<meta property="og:title" content="SRT to DOCX Converter" />
<meta name="og:image" content="assets/og-image.jpeg" />
<meta property="og:image" content="assets/og-image.jpeg" />
<meta name="description"
content="This application streamlines the task of converting subtitle files to a format that's compatible with Word processors, making it perfect for educators, content creators, and anyone needing to integrate subtitle text into documents. Try it now and see how simple converting SRT files to DOCX can be!" />
<meta name="og:description"
content="This application streamlines the task of converting subtitle files to a format that's compatible with Word processors, making it perfect for educators, content creators, and anyone needing to integrate subtitle text into documents. Try it now and see how simple converting SRT files to DOCX can be!" />
<meta property="og:description"
content="This application streamlines the task of converting subtitle files to a format that's compatible with Word processors, making it perfect for educators, content creators, and anyone needing to integrate subtitle text into documents. Try it now and see how simple converting SRT files to DOCX can be!" />
<meta name="url" content="https://srt.hackettlai.com" />
<meta name="og:url" content="https://srt.hackettlai.com" />
<meta property="og:url" content="https://srt.hackettlai.com" />
<meta name="keywords"
content="SRT to DOCX converter, subtitle converter, SRT to Word, DOCX converter, subtitle to document, convert subtitles to Word, SRT file conversion, subtitle text extractor, caption to DOCX, convert SRT to document, subtitle processing, text conversion tool">
<meta http-equiv="CACHE-CONTROL" content="NO-CACHE" />
<!-- favicons -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#1f1f1f">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="theme-color" content="#ffffff">
<!-- stylesheets -->
<link rel="stylesheet" href="style.css" />
</head>

<body>
<h1>SRT to DOCX Converter</h1>
<p>Welcome to the SRT to DOCX Converter page, a user-friendly tool designed to transform your subtitle files into
easily shareable Word documents. This versatile application allows you to upload SRT files, view the converted
text directly within the webpage, and download a well-formatted DOCX file at your convenience.</p>
<div class="flex-r full">
<input type="file" id="srtFile" accept=".srt" />
<button onclick="convertSrtToDocx()" disabled id="btn_convert">Convert</button>
</div>
<div id="result_div"></div>
<button onclick="downloadDocx() " disabled id="btn_download">Download</button>
<footer>
<p id="version">Built Version 1.0.1</p>
<img class="footer-image" src="assets/footer-logo.png" />
<p><a href="https://tool.hackettlai.com" target="blank">Hackett.Lai</a> @ <span id="thisYear"
class="footer"></span>
</p>

</footer>
<!-- Changes Log -->
<div id="modal" class="modal">
<div class="modal-content">
<span id="closeModal" class="close">&times;</span>
<h2>Changes Log</h2>
<table class="modal-table">
<tr>
<td>v1.0.1</td>
<td>
<p>2024/08/26</p>
<ol>
<li><strong>Simple File Upload:</strong> Easily upload your `.srt` subtitle files using the
integrated file input option.</li>
<li><strong>Instant Text Display:</strong> Once converted, your subtitle text is displayed
instantly on the page, formatted for easy viewing and ready for review.</li>
<li><strong>Flexible Download Option:</strong> Choose to download the converted document
when you're ready—no need for immediate downloads after conversion.</li>
<li><strong>Automatic Sentence Separation:</strong> The tool intelligently processes your
subtitles, breaking them down into paragraphs based on sentence-ending punctuation,
including Western and Chinese marks like ".", "!", "?", "。", "!", and "?".</li>
<li><strong>Readability Enhancements:</strong> For enhanced readability, the converted text
includes sensible line breaks and section spacing, making your subtitles easier to
navigate.</li>
<li><strong>Intuitive Interface:</strong> The layout and functionality are designed to
provide an effortless user experience, ensuring even those unfamiliar with DOCX
conversions can navigate the process with ease.</li>
</ol>
</td>
</tr>
</table>
</div>
</div>
<!-- scripts -->
<!-- Include the docx.js library from a CDN -->
<script src="https://unpkg.com/docx@7.1.0/build/index.js"></script>
<script src='function.js'></script>
<script type="text/javascript" src="./changelog.js"></script>
</body>

</html>
Binary file added mstile-150x150.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions safari-pinned-tab.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions site.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "Hackett Lai",
"short_name": "Hackett Lai",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
Loading

0 comments on commit d3463b4

Please sign in to comment.