Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
junta-m authored Dec 31, 2024
0 parents commit ff61ac1
Showing 1 changed file with 360 additions and 0 deletions.
360 changes: 360 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,360 @@
<!DOCTYPE html>
<html lang="ja">

<head>
<meta charset="UTF-8">
<title>researchmap 論文リストダウンロードツール</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/encoding.min.js"></script>
<style>
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-size: 16px;
}

h1 {
font-size: 28px;
margin-bottom: 1em;
}

.description {
margin-bottom: 2em;
line-height: 1.6;
color: #333;
}

.description ol {
margin-left: 1.5em;
padding-left: 0;
}

.description li {
margin-bottom: 0.5em;
}

.input-form {
margin-bottom: 2em;
font-size: 18px;
}

.input-form input {
width: 80%;
padding: 12px;
margin-right: 10px;
font-size: 18px;
border: 2px solid #ccc;
border-radius: 4px;
}

.input-form button {
padding: 12px 24px;
font-size: 18px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

.input-form button:hover {
background-color: #45a049;
}

.paper {
margin-bottom: 1em;
padding: 1em;
border-bottom: 1px solid #eee;
font-size: 16px;
}

.title {
font-weight: bold;
}

.authors {
color: #666;
margin: 0.5em 0;
}

.journal {
font-style: italic;
}

.error {
color: red;
margin: 1em 0;
}

.download-buttons {
margin: 1em 0;
display: none;
}

.download-buttons button {
padding: 8px 16px;
margin-right: 10px;
font-size: 16px;
background-color: #2196F3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

.download-buttons button:hover {
background-color: #1976D2;
}
</style>
</head>

<body>
<div class="container">
<h1>researchmap 論文リストダウンロードツール</h1>
<div class="description">
<p>このツールは、researchmapの論文リストを様々な形式でダウンロードするためのものです。</p>
<p>使い方:</p>
<ol>
<li>researchmapのプロフィールURL(例:https://researchmap.jp/ユーザーID)を入力</li>
<li>「表示」ボタンをクリックして論文リストを表示</li>
<li>必要な形式(Word、CSV、LaTeX)を選んでダウンロード</li>
</ol>
</div>
<div class="input-form">
<input type="text" id="urlInput" placeholder="https://researchmap.jp/ユーザーID">
<button onclick="handleSubmit()">表示</button>
</div>
<div class="download-buttons" id="downloadButtons">
<button onclick="downloadAs('text')">TEXT形式</button>
<button onclick="downloadAs('word')">Word形式</button>
<button onclick="downloadAs('csv')">CSV形式</button>
</div>
<div id="papers"></div>
</div>

<script>
let currentPapers = []; // 現在表示中の論文データを保持

function extractUserId(url) {
try {
const urlObj = new URL(url);
const path = urlObj.pathname;
const userId = path.split('/').filter(p => p).pop();
return userId;
} catch (error) {
console.error('URLの解析に失敗:', error);
return null;
}
}

async function fetchPapers(userId) {
try {
const response = await fetch(`https://api.researchmap.jp/${userId}/published_papers`);
if (!response.ok) {
throw new Error('APIの呼び出しに失敗しました');
}
const data = await response.json();
const papers = data.items || [];
displayPapers(papers);
} catch (error) {
console.error('エラー:', error);
document.getElementById('papers').innerHTML =
`<p class="error">論文データの取得に失敗しました。${error.message}</p>`;
}
}

function displayPapers(papers) {
currentPapers = papers; // データを保存
const container = document.getElementById('papers');
if (papers.length === 0) {
container.innerHTML = '<p>論文データが見つかりませんでした。</p>';
document.getElementById('downloadButtons').style.display = 'none';
return;
}

container.innerHTML = '';
papers.forEach(paper => {
const paperDiv = document.createElement('div');
paperDiv.className = 'paper';

const title = paper.paper_title?.ja || paper.paper_title?.en || '';
const authors = paper.authors?.ja || paper.authors?.en || [];
const authorNames = authors.map(author => author.name).join(', ');
const journalName = paper.publication_name?.ja || paper.publication_name?.en || '';
const doi = paper.identifiers?.doi?.[0] || '';

paperDiv.innerHTML = `
<div class="title">${title}</div>
<div class="authors">${authorNames}</div>
<div class="journal">${journalName} ${paper.publication_date || ''}</div>
${doi ? `<div class="doi">DOI: ${doi}</div>` : ''}
`;

container.appendChild(paperDiv);
});

// ダウンロードボタンを表示
document.getElementById('downloadButtons').style.display = 'block';
}

function handleSubmit() {
const url = document.getElementById('urlInput').value.trim();
if (!url) {
document.getElementById('papers').innerHTML =
'<p class="error">URLを入力してください。</p>';
return;
}

const userId = extractUserId(url);
if (!userId) {
document.getElementById('papers').innerHTML =
'<p class="error">URLからユーザーIDを抽出できませんでした。</p>';
return;
}

fetchPapers(userId);
}

function downloadAs(format) {
if (currentPapers.length === 0) return;

let content = '';
const filename = `papers.${getFileExtension(format)}`;

switch (format) {
case 'text':
content = generateTextContent(currentPapers);
break;
case 'word':
content = generateHTMLContent(currentPapers, format);
break;
case 'csv': {
const csvContent = generateCSVContent(currentPapers);
// SJISエンコーディングに変換
const unicodeArray = Encoding.stringToCode(csvContent);
const sjisArray = Encoding.convert(unicodeArray, 'SJIS', 'UNICODE');
content = new Uint8Array(sjisArray);
break;
}
}

const blob = new Blob([content], { type: getMimeType(format) });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}

function getFileExtension(format) {
switch (format) {
case 'text': return 'txt';
case 'word': return 'doc';
case 'csv': return 'csv';
}
}

function getMimeType(format) {
switch (format) {
case 'text':
return 'text/plain';
case 'word':
return 'text/html';
case 'csv':
return 'text/csv';
}
}

function generateHTMLContent(papers, format) {
return `<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>論文リスト</title>
<style>
body { font-family: "MS Mincho", serif; line-height: 1.5; }
.paper { margin-bottom: 1em; }
.title { font-weight: bold; }
.authors { color: #000; }
</style>
</head>
<body>
<h1>論文リスト</h1>
${papers.map(paper => {
const title = paper.paper_title?.ja || paper.paper_title?.en || '';
const authors = (paper.authors?.ja || paper.authors?.en || [])
.map(author => author.name).join(', ');
const journal = paper.publication_name?.ja || paper.publication_name?.en || '';
const date = paper.publication_date || '';
const doi = paper.identifiers?.doi?.[0] || '';
return `<div class="paper">
<div class="title">${escapeHTML(title)}</div>
<div class="authors">${escapeHTML(authors)}</div>
<div class="journal">${escapeHTML(journal)} ${date}</div>
${doi ? `<div class="doi">DOI: ${doi}</div>` : ''}
</div>`;
}).join('\n')}
</body>
</html>`;
}

function escapeHTML(str) {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}

function generateCSVContent(papers) {
const header = '"Title","Authors","Journal","Date","DOI"\n';
const rows = papers.map(paper => {
const title = paper.paper_title?.ja || paper.paper_title?.en || '';
const authors = (paper.authors?.ja || paper.authors?.en || [])
.map(author => author.name).join('; ');
const journal = paper.publication_name?.ja || paper.publication_name?.en || '';
const date = paper.publication_date || '';
const doi = paper.identifiers?.doi?.[0] || '';
return `"${escapeCSV(title)}","${escapeCSV(authors)}","${escapeCSV(journal)}","${date}","${doi}"`;
}).join('\n');
return header + rows;
}

function generateTextContent(papers) {
return papers.map(paper => {
const title = paper.paper_title?.ja || paper.paper_title?.en || '';
const authors = (paper.authors?.ja || paper.authors?.en || [])
.map(author => author.name).join(', ');
const journal = paper.publication_name?.ja || paper.publication_name?.en || '';
const date = paper.publication_date || '';
const doi = paper.identifiers?.doi?.[0] || '';

return `タイトル:${title}\n` +
`著者:${authors}\n` +
`掲載誌:${journal}\n` +
`出版年:${date}\n` +
(doi ? `DOI:${doi}\n` : '') +
'----------------------------------------\n';
}).join('\n');
}

function escapeCSV(str) {
return str.replace(/"/g, '""');
}

// URLパラメータがある場合は自動的に実行
const urlParams = new URLSearchParams(window.location.search);
const initialUrl = urlParams.get('url');
if (initialUrl) {
document.getElementById('urlInput').value = initialUrl;
handleSubmit();
}
</script>
</body>

</html>

0 comments on commit ff61ac1

Please sign in to comment.