因此我向 AI 諮詢, AI 說如果使用 XML 檔案製作數據,便能完成我所希望的工具。
卻發現完全無法運作。後來在另一個 AI 那裡進行分析,得知代碼的結構有些過舊,出於安全原因而無法運行。
現在已經修正了代碼,使其能夠正常輸入,因此我上傳了參考資料。
因為當時很急,所以只有日文的表述,還請見諒。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小説表示</title>
<style>
body {
font-family: 'Hiragino Kaku Gothic Pro', 'Meiryo', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.8;
background-color: #f9f9f9;
}
#novelContent {
background: white;
padding: 30px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 30px;
}
.editor-panel {
background: white;
padding: 30px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 30px;
}
.editor-panel h3 {
color: #333;
margin-top: 0;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
font-weight: bold;
margin-bottom: 5px;
color: #555;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: inherit;
box-sizing: border-box;
}
.form-group textarea {
min-height: 150px;
resize: vertical;
}
.btn {
background-color: #4CAF50;
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.btn:hover {
background-color: #45a049;
}
h1 {
color: #333;
border-bottom: 2px solid #333;
padding-bottom: 10px;
}
.author {
color: #666;
font-style: italic;
margin-bottom: 30px;
}
h2 {
color: #555;
margin-top: 40px;
border-left: 4px solid #555;
padding-left: 10px;
}
p {
text-indent: 1em;
white-space: pre-line;
}
.line-break {
border-bottom: 1px solid #ccc;
margin: 20px 0;
height: 1px;
}
</style>
</head>
<body>
<!-- XMLデータをscriptタグ内に埋め込む -->
<script id="novelData" type="application/xml">
<novel>
<novelTitle>小説のタイトル</novelTitle>
<author>作者名</author>
<section id="1">
<title>第一章</title>
<content>ここに小説の第一章の本文が入ります。
例えば、登場人物の紹介や場面の描写など。
ここでは改行を使って場面の転換を表しています。</content>
</section>
<section id="2">
<title>第二章</title>
<content>第二章では、物語が新たな展開を迎えます。
重要な出来事が発生し、登場人物たちの関係が変化します。</content>
</section>
</novel>
</script>
<!-- 入力フォーム -->
<div class="editor-panel">
<h3>新しい章を追加</h3>
<div class="form-group">
<label for="chapterTitle">章のタイトル</label>
<input type="text" id="chapterTitle" placeholder="例: 第三章">
</div>
<div class="form-group">
<label for="chapterContent">本文</label>
<textarea id="chapterContent" placeholder="ここに本文を入力してください..."></textarea>
</div>
<div class="form-group">
<label for="lineBreakCount">区切り線を入れる文字数(0で無効)</label>
<input type="number" id="lineBreakCount" value="100" min="0" placeholder="例: 100">
</div>
<button class="btn" onclick="addChapter()">章を追加</button>
</div>
<!-- 小説表示エリア -->
<div id="novelContent"></div>
<script>
let xmlDoc;
function displayData() {
try {
const xmlText = document.getElementById("novelData").textContent.trim();
const parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlText, "text/xml");
const parseError = xmlDoc.getElementsByTagName("parsererror");
if (parseError.length > 0) {
console.error("XML Parse Error:", xmlDoc.documentElement.textContent);
document.getElementById("novelContent").innerHTML = "<p>XMLの解析に失敗しました</p>";
return;
}
renderNovel();
} catch (error) {
console.error("Error:", error);
document.getElementById("novelContent").innerHTML = "<p>エラーが発生しました: " + error.message + "</p>";
}
}
function renderNovel() {
const novelRoot = xmlDoc.getElementsByTagName("novel")[0];
const novelTitle = novelRoot.getElementsByTagName("novelTitle")[0].textContent;
const author = novelRoot.getElementsByTagName("author")[0].textContent;
const sections = xmlDoc.getElementsByTagName("section");
let output = "<h1>" + novelTitle + "</h1>";
output += "<div class='author'>著者: " + author + "</div>";
for (let i = 0; i < sections.length; i++) {
const title = sections[i].getElementsByTagName("title")[0].textContent;
const content = sections[i].getElementsByTagName("content")[0].textContent;
output += "<h2>" + title + "</h2>";
// 区切り線(---)をHTMLの区切り線に変換
const lines = content.split('\n---\n');
for (let j = 0; j < lines.length; j++) {
output += "<p>" + lines[j] + "</p>";
if (j < lines.length - 1) {
output += '<div class="line-break"></div>';
}
}
}
document.getElementById("novelContent").innerHTML = output;
}
function addChapter() {
const titleInput = document.getElementById("chapterTitle");
const contentInput = document.getElementById("chapterContent");
const lineBreakInput = document.getElementById("lineBreakCount");
const title = titleInput.value.trim();
let content = contentInput.value.trim();
const lineBreakCount = parseInt(lineBreakInput.value) || 0;
if (!title || !content) {
alert("タイトルと本文を入力してください");
return;
}
// 区切り線を挿入
if (lineBreakCount > 0) {
content = insertLineBreaks(content, lineBreakCount);
console.log("区切り線処理実行: " + lineBreakCount + "文字ごと");
}
// 新しいセクションを作成
const novelRoot = xmlDoc.getElementsByTagName("novel")[0];
const sections = xmlDoc.getElementsByTagName("section");
const newId = sections.length + 1;
const newSection = xmlDoc.createElement("section");
newSection.setAttribute("id", newId);
const titleElement = xmlDoc.createElement("title");
titleElement.textContent = title;
const contentElement = xmlDoc.createElement("content");
contentElement.textContent = content;
newSection.appendChild(titleElement);
newSection.appendChild(contentElement);
novelRoot.appendChild(newSection);
// 表示を更新
renderNovel();
// フォームをクリア
titleInput.value = "";
contentInput.value = "";
alert("章を追加しました!");
}
function insertLineBreaks(text, charCount) {
if (charCount <= 0) return text;
let result = "";
let currentCount = 0;
let i = 0;
while (i < text.length) {
result += text[i];
currentCount++;
// 指定文字数に達した場合
if (currentCount >= charCount) {
// 次の句読点を探す
let foundPunctuation = false;
let j = i + 1;
// 最大50文字先まで句読点を探す
while (j < text.length && j - i < 50) {
result += text[j];
if (text[j] === '。' || text[j] === '!' || text[j] === '?' || text[j] === '\n') {
foundPunctuation = true;
j++;
break;
}
j++;
}
// 句読点が見つかったら区切り線を挿入
if (foundPunctuation) {
result += "\n---\n";
currentCount = 0;
}
i = j - 1;
}
i++;
}
console.log("区切り線挿入後:", result);
return result;
}
window.onload = displayData;
</script>
</body>
</html>