(function () {
"use strict";
var generatedHTML = "";
var code = document.getElementById("code");
var compileButton = document.getElementById("compileButton");
var copyButton = document.getElementById("copyButton");
var output = document.getElementById("output");
var message = document.getElementById("message");
compileButton.onclick = function () {
var source = code.value;
output.textContent = "";
message.textContent = "";
message.className = "";
copyButton.style.display = "none";
if (source.trim() === "") {
showError("לא הוזן קוד.");
return;
}
try {
var program = parseProgram(source);
generatedHTML = createHTML(program);
output.textContent = generatedHTML;
copyButton.style.display = "inline-block";
showSuccess("התרגום הצליח.");
} catch (error) {
showError(error.message);
}
};
function parseProgram(source) {
var lines = source.split(/\r?\n/);
var result = [];
var i = 0;
while (i < lines.length) {
var line = lines[i];
var trimmedLine = line.trim();
if (trimmedLine === "") {
i++;
continue;
}
if (trimmedLine.indexOf("*א1*") !== 0) {
throw new Error(
"פקודה לא תקינה בשורה " +
(i + 1) +
": " +
line
);
}
var value = trimmedLine
.substring(4)
.trim();
i++;
if (value !== "") {
result.push(value);
continue;
}
var content = [];
while (i < lines.length) {
var nextLine = lines[i];
var nextTrimmed = nextLine.trim();
if (
nextTrimmed.indexOf("*א1*") === 0
) {
break;
}
content.push(nextLine);
i++;
}
while (
content.length > 0 &&
content[0].trim() === ""
) {
content.shift();
}
while (
content.length > 0 &&
content[content.length - 1].trim() === ""
) {
content.pop();
}
if (content.length === 0) {
throw new Error(
"חסר תוכן אחרי *א1*"
);
}
value = content.join("\n");
result.push(value);
}
if (result.length === 0) {
throw new Error(
"לא נמצאו פקודות *א1*"
);
}
return result;
}
function createHTML(program) {
var html = "";
html += "\n";
html += "\n";
html += "
\n";
html += " \n";
html += " \n";
html += " אתר בשפת א\n";
html += " \n";
html += "\n";
html += "\n";
html += "
\n";
for (var i = 0; i < program.length; i++) {
html += createContent(program[i]);
}
html += "
\n";
html += "";
return html;
}
function createContent(value) {
var text = value.trim();
/*
* מפרידים בין טקסט לבין כתובות URL.
*
* כל URL מזוהה בפני עצמו,
* גם אם הוא נמצא באמצע טקסט.
*/
var urlPattern = /(https?:\/\/[^\s<>"']+)/gi;
var parts = [];
var lastIndex = 0;
var match;
while ((match = urlPattern.exec(text)) !== null) {
/*
* טקסט שלפני הקישור.
*/
if (match.index > lastIndex) {
var textBefore =
text.substring(
lastIndex,
match.index
);
parts.push(
createTextPart(textBefore)
);
}
/*
* הקישור עצמו.
*/
var url = cleanURL(match[0]);
parts.push(
createEmbeddedPart(url)
);
lastIndex =
match.index +
match[0].length;
}
/*
* הטקסט שנשאר אחרי הקישור האחרון.
*/
if (lastIndex < text.length) {
var textAfter =
text.substring(lastIndex);
parts.push(
createTextPart(textAfter)
);
}
/*
* אם לא נמצא אף קישור,
* מחזירים טקסט רגיל.
*/
if (parts.length === 0) {
return (
"
\n" +
"
" +
escapeHTML(text) +
"
\n" +
"
\n"
);
}
return (
"
\n" +
parts.join("") +
"
\n"
);
}
function createTextPart(text) {
if (text === "") {
return "";
}
return (
" " +
escapeHTML(text) +
"\n"
);
}
function createEmbeddedPart(url) {
/*
* YouTube
*/
var youtubeURL =
getYouTubeEmbedURL(url);
if (youtubeURL) {
return (
" \n"
);
}
/*
* תמונה
*/
if (isImageURL(url)) {
return (
" \n"
);
}
/*
* וידאו
*/
if (isVideoURL(url)) {
return (
" \n"
);
}
/*
* אודיו
*/
if (isAudioURL(url)) {
return (
" \n"
);
}
/*
* PDF
*/
if (isPDFURL(url)) {
return (
" \n"
);
}
/*
* אתר רגיל
*/
return (
" \n"
);
}
function cleanURL(url) {
/*
* הסרת סימני פיסוק נפוצים
* שמופיעים אחרי כתובת בתוך משפט.
*/
while (
/[.,!?;:)\]}]$/.test(url)
) {
url = url.substring(
0,
url.length - 1
);
}
return url;
}
function getYouTubeEmbedURL(url) {
var videoId = null;
/*
* youtu.be
*/
var shortMatch = url.match(
/^https?:\/\/(?:www\.)?youtu\.be\/([^?/]+)/i
);
if (shortMatch) {
videoId = shortMatch[1];
}
/*
* youtube.com/watch?v=
*/
var watchMatch = url.match(
/^https?:\/\/(?:www\.)?youtube\.com\/watch\?[^#]*v=([^]+)/i
);
if (watchMatch) {
videoId = watchMatch[1];
}
/*
* youtube.com/embed/
*/
var embedMatch = url.match(
/^https?:\/\/(?:www\.)?youtube\.com\/embed\/([^?/]+)/i
);
if (embedMatch) {
videoId = embedMatch[1];
}
/*
* youtube.com/shorts/
*/
var shortsMatch = url.match(
/^https?:\/\/(?:www\.)?youtube\.com\/shorts\/([^?/]+)/i
);
if (shortsMatch) {
videoId = shortsMatch[1];
}
/*
* youtube.com/live/
*/
var liveMatch = url.match(
/^https?:\/\/(?:www\.)?youtube\.com\/live\/([^?/]+)/i
);
if (liveMatch) {
videoId = liveMatch[1];
}
if (!videoId) {
return null;
}
if (!/^[A-Za-z0-9_-]{6,20}$/.test(videoId)) {
return null;
}
return (
"https://www.youtube.com/embed/" +
encodeURIComponent(videoId)
);
}
function isImageURL(url) {
return /\.(jpg|jpeg|png|gif|webp|svg|bmp|avif)(\?.*)?$/i.test(url);
}
function isVideoURL(url) {
return /\.(mp4|webm|ogv|mov|m4v)(\?.*)?$/i.test(url);
}
function isAudioURL(url) {
return /\.(mp3|wav|ogg|m4a|aac|flac)(\?.*)?$/i.test(url);
}
function isPDFURL(url) {
return /\.pdf(\?.*)?$/i.test(url);
}
function escapeHTML(text) {
return String(text)
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function escapeAttribute(text) {
return String(text)
.replace(/&/g, "&")
.replace(/"/g, """)
.replace(//g, ">");
}
copyButton.onclick = function () {
if (!generatedHTML) {
return;
}
if (navigator.clipboard) {
navigator.clipboard
.writeText(generatedHTML)
.then(function () {
showSuccess(
"ה־HTML הועתק בהצלחה."
);
})
.catch(function () {
fallbackCopy();
});
} else {
fallbackCopy();
}
};
function fallbackCopy() {
var box =
document.createElement("textarea");
box.value = generatedHTML;
box.style.position = "fixed";
box.style.left = "-9999px";
document.body.appendChild(box);
box.select();
document.execCommand("copy");
document.body.removeChild(box);
showSuccess(
"ה־HTML הועתק בהצלחה."
);
}
function showSuccess(text) {
message.textContent = text;
message.className = "success";
}
function showError(text) {
message.textContent = text;
message.className = "error";
}
})();