latex received_time update
This commit is contained in:
338
application/api/controller/Latex.php
Normal file
338
application/api/controller/Latex.php
Normal file
@@ -0,0 +1,338 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\api\controller;
|
||||||
|
|
||||||
|
class Latex extends Base
|
||||||
|
{
|
||||||
|
public function __construct(\think\Request $request = null)
|
||||||
|
{
|
||||||
|
parent::__construct($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateLatexPdf()
|
||||||
|
{
|
||||||
|
$data = $this->request->post();
|
||||||
|
$rule = new Validate([
|
||||||
|
'p_article_id' => 'require|number'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$rule->check($data)) {
|
||||||
|
return jsonError($rule->getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取文章信息
|
||||||
|
$p_info = $this->production_article_obj->where('p_article_id', $data['p_article_id'])->find();
|
||||||
|
if (!$p_info) {
|
||||||
|
return jsonError('文章实例不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取作者信息
|
||||||
|
$authors = $this->production_article_author_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
|
||||||
|
|
||||||
|
// 获取机构信息
|
||||||
|
$organs = $this->production_article_organ_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
|
||||||
|
|
||||||
|
// 获取正文内容
|
||||||
|
$main_contents = $this->production_article_main_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('p_main_id')->select();
|
||||||
|
|
||||||
|
// 获取参考文献
|
||||||
|
$references = $this->production_article_refer_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('index')->select();
|
||||||
|
|
||||||
|
// 构建LaTeX内容
|
||||||
|
$latex_content = $this->buildLatexContent($p_info, $authors, $organs, $main_contents, $references);
|
||||||
|
|
||||||
|
// 创建临时目录
|
||||||
|
$temp_dir = ROOT_PATH . 'public' . DS . 'temp_latex' . DS;
|
||||||
|
if (!is_dir($temp_dir)) {
|
||||||
|
mkdir($temp_dir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成唯一的文件名
|
||||||
|
$filename = 'article_' . $p_info['p_article_id'] . '_' . time();
|
||||||
|
$tex_file = $temp_dir . $filename . '.tex';
|
||||||
|
$pdf_file = $temp_dir . $filename . '.pdf';
|
||||||
|
|
||||||
|
// 写入LaTeX文件
|
||||||
|
file_put_contents($tex_file, $latex_content);
|
||||||
|
|
||||||
|
// 执行LaTeX编译命令生成PDF
|
||||||
|
$command = sprintf(
|
||||||
|
'cd %s && pdflatex -interaction=nonstopmode -output-directory=%s %s',
|
||||||
|
escapeshellarg($temp_dir),
|
||||||
|
escapeshellarg($temp_dir),
|
||||||
|
escapeshellarg($tex_file)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
$output = [];
|
||||||
|
$return_var = 0;
|
||||||
|
exec($command, $output, $return_var);
|
||||||
|
|
||||||
|
// 检查PDF是否生成成功
|
||||||
|
if (!file_exists($pdf_file) || filesize($pdf_file) == 0) {
|
||||||
|
return jsonError('PDF生成失败,请检查LaTeX内容或系统环境');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动PDF到正式目录
|
||||||
|
$pdf_dir = ROOT_PATH . 'public' . DS . 'latex_pdfs' . DS;
|
||||||
|
if (!is_dir($pdf_dir)) {
|
||||||
|
mkdir($pdf_dir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$final_pdf_path = $pdf_dir . $filename . '.pdf';
|
||||||
|
rename($pdf_file, $final_pdf_path);
|
||||||
|
|
||||||
|
// 清理临时文件
|
||||||
|
if (file_exists($tex_file)) {
|
||||||
|
unlink($tex_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理辅助文件(.aux, .log等)
|
||||||
|
$aux_file = $temp_dir . $filename . '.aux';
|
||||||
|
$log_file = $temp_dir . $filename . '.log';
|
||||||
|
if (file_exists($aux_file)) unlink($aux_file);
|
||||||
|
if (file_exists($log_file)) unlink($log_file);
|
||||||
|
|
||||||
|
// 返回PDF路径
|
||||||
|
$relative_path = 'latex_pdfs/' . $filename . '.pdf';
|
||||||
|
return jsonSuccess([
|
||||||
|
'pdf_url' => $relative_path,
|
||||||
|
'message' => 'PDF生成成功'
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return jsonError('生成过程中发生错误: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建LaTeX文档内容
|
||||||
|
* @param $p_info
|
||||||
|
* @param $authors
|
||||||
|
* @param $organs
|
||||||
|
* @param $main_contents
|
||||||
|
* @param $references
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function buildLatexContent($p_info, $authors, $organs, $main_contents, $references)
|
||||||
|
{
|
||||||
|
// 构建机构映射
|
||||||
|
$organ_map = [];
|
||||||
|
foreach ($organs as $index => $organ) {
|
||||||
|
$organ_map[$organ['p_article_organ_id']] = $index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LaTeX文档开始
|
||||||
|
$latex = '\documentclass[twocolumn]{article}' . "\n";
|
||||||
|
$latex .= '\usepackage[utf8]{inputenc}' . "\n";
|
||||||
|
$latex .= '\usepackage[T1]{fontenc}' . "\n";
|
||||||
|
$latex .= '\usepackage{geometry}' . "\n";
|
||||||
|
$latex .= '\usepackage{graphicx}' . "\n";
|
||||||
|
$latex .= '\usepackage{amsmath}' . "\n";
|
||||||
|
$latex .= '\usepackage{amsfonts}' . "\n";
|
||||||
|
$latex .= '\usepackage{amssymb}' . "\n";
|
||||||
|
$latex .= '\usepackage{setspace}' . "\n";
|
||||||
|
$latex .= '\usepackage{titlesec}' . "\n";
|
||||||
|
$latex .= '\usepackage{hyperref}' . "\n";
|
||||||
|
$latex .= '\usepackage{caption}' . "\n";
|
||||||
|
$latex .= '\usepackage{multicol}' . "\n";
|
||||||
|
$latex .= '\usepackage{abstract}' . "\n";
|
||||||
|
|
||||||
|
$latex .= '\geometry{left=1.5cm,right=1.5cm,top=2.5cm,bottom=2.5cm}' . "\n";
|
||||||
|
$latex .= '\setstretch{1.5}' . "\n";
|
||||||
|
|
||||||
|
$latex .= '\title{' . $this->escapeLatexText($p_info['title']) . '}' . "\n";
|
||||||
|
|
||||||
|
// 处理作者和机构
|
||||||
|
if (!empty($authors)) {
|
||||||
|
$author_text = '';
|
||||||
|
$affiliations = [];
|
||||||
|
|
||||||
|
foreach ($authors as $author) {
|
||||||
|
if ($author_text !== '') {
|
||||||
|
$author_text .= ', ';
|
||||||
|
}
|
||||||
|
$author_text .= $this->escapeLatexText($author['first_name'] . ' ' . $author['last_name']);
|
||||||
|
|
||||||
|
// 获取作者的机构
|
||||||
|
$author_organs = $this->production_article_author_to_organ_obj
|
||||||
|
->where('p_article_author_id', $author['p_article_author_id'])
|
||||||
|
->where('state', 0)
|
||||||
|
->select();
|
||||||
|
|
||||||
|
foreach ($author_organs as $ao) {
|
||||||
|
if (isset($organ_map[$ao['p_article_organ_id']])) {
|
||||||
|
$author_text .= '$^{' . $organ_map[$ao['p_article_organ_id']] . '}$';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($author['is_report'] == 1) {
|
||||||
|
$author_text .= '$^{*}$';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$latex .= '\author{' . $author_text . "\n";
|
||||||
|
|
||||||
|
// 添加机构信息
|
||||||
|
foreach ($organs as $index => $organ) {
|
||||||
|
$latex .= '\\\\$' . ($index + 1) . '$ ' . $this->escapeLatexText($organ['organ_name']) . "\n";
|
||||||
|
}
|
||||||
|
if (!empty($authors)) {
|
||||||
|
// 查找通讯作者
|
||||||
|
$corresponding_authors = array_filter($authors, function($author) {
|
||||||
|
return $author['is_report'] == 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!empty($corresponding_authors)) {
|
||||||
|
$corr_author = reset($corresponding_authors);
|
||||||
|
$latex .= '\\\\$*$ Corresponding author: ' .
|
||||||
|
$this->escapeLatexText($corr_author['email']) . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$latex .= '}' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$latex .= '\date{}' . "\n";
|
||||||
|
$latex .= '\begin{document}' . "\n";
|
||||||
|
$latex .= '\maketitle' . "\n";
|
||||||
|
|
||||||
|
// 摘要
|
||||||
|
if (!empty($p_info['abstract'])) {
|
||||||
|
$latex .= '\begin{abstract}' . "\n";
|
||||||
|
$latex .= $this->escapeLatexText($p_info['abstract']) . "\n";
|
||||||
|
$latex .= '\end{abstract}' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关键词
|
||||||
|
if (!empty($p_info['keywords'])) {
|
||||||
|
$latex .= '\textbf{Keywords:} ' . $this->escapeLatexText($p_info['keywords']) . "\n";
|
||||||
|
$latex .= '\sectionbreak' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正文内容
|
||||||
|
$in_section = false;
|
||||||
|
$section_count = 0;
|
||||||
|
|
||||||
|
foreach ($main_contents as $content) {
|
||||||
|
$text = trim($content['content']);
|
||||||
|
|
||||||
|
// 跳过空内容
|
||||||
|
if (empty($text)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否是标题
|
||||||
|
$clean_text = strip_tags($text);
|
||||||
|
$lower_text = strtolower($clean_text);
|
||||||
|
|
||||||
|
// 判断是否为章节标题
|
||||||
|
if (stripos($lower_text, 'introduction') === 0 ||
|
||||||
|
stripos($lower_text, 'methods') === 0 ||
|
||||||
|
stripos($lower_text, 'results') === 0 ||
|
||||||
|
stripos($lower_text, 'discussion') === 0 ||
|
||||||
|
stripos($lower_text, 'conclusion') === 0 ||
|
||||||
|
stripos($lower_text, 'references') === 0) {
|
||||||
|
|
||||||
|
// 结束前一节
|
||||||
|
if ($in_section) {
|
||||||
|
$latex .= "\n" . '\sectionbreak' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始新节
|
||||||
|
$section_count++;
|
||||||
|
$section_title = $this->escapeLatexText($clean_text);
|
||||||
|
$latex .= '\section{' . $section_title . '}' . "\n";
|
||||||
|
$in_section = true;
|
||||||
|
}
|
||||||
|
// 检查是否是图片或表格占位符
|
||||||
|
else if (preg_match('/<img[^>]*imageId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $img_matches)) {
|
||||||
|
$image_id = $img_matches[1];
|
||||||
|
// 这里可以添加图片处理逻辑
|
||||||
|
$latex .= '% 图片插入位置 (ID: ' . $image_id . ')' . "\n";
|
||||||
|
$latex .= '\begin{figure}[htbp]' . "\n";
|
||||||
|
$latex .= '\centering' . "\n";
|
||||||
|
$latex .= '\includegraphics[width=0.8\textwidth]{image_' . $image_id . '}' . "\n";
|
||||||
|
$latex .= '\caption{图片说明}' . "\n";
|
||||||
|
$latex .= '\end{figure}' . "\n";
|
||||||
|
}
|
||||||
|
else if (preg_match('/<table[^>]*tableId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $table_matches)) {
|
||||||
|
$table_id = $table_matches[1];
|
||||||
|
// 这里可以添加表格处理逻辑
|
||||||
|
$latex .= '% 表格插入位置 (ID: ' . $table_id . ')' . "\n";
|
||||||
|
$latex .= '\begin{table}[htbp]' . "\n";
|
||||||
|
$latex .= '\centering' . "\n";
|
||||||
|
$latex .= '\caption{表格说明}' . "\n";
|
||||||
|
$latex .= '\begin{tabular}{|c|c|c|}' . "\n";
|
||||||
|
$latex .= '\hline' . "\n";
|
||||||
|
$latex .= '列1 & 列2 & 列3 \\\\' . "\n";
|
||||||
|
$latex .= '\hline' . "\n";
|
||||||
|
$latex .= '% 表格数据' . "\n";
|
||||||
|
$latex .= '\hline' . "\n";
|
||||||
|
$latex .= '\end{tabular}' . "\n";
|
||||||
|
$latex .= '\end{table}' . "\n";
|
||||||
|
}
|
||||||
|
// 普通段落文本
|
||||||
|
else {
|
||||||
|
// 移除HTML标签并转义特殊字符
|
||||||
|
$plain_text = $this->escapeLatexText(strip_tags($text));
|
||||||
|
$latex .= $plain_text . "\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参考文献
|
||||||
|
if (!empty($references)) {
|
||||||
|
$latex .= '\section*{References}' . "\n";
|
||||||
|
$latex .= '\begin{thebibliography}{99}' . "\n";
|
||||||
|
|
||||||
|
foreach ($references as $index => $ref) {
|
||||||
|
$ref_text = isset($ref['refer_frag']) ? $ref['refer_frag'] : $ref['refer_content'];
|
||||||
|
$latex .= '\bibitem{} ' . $this->escapeLatexText($ref_text) . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$latex .= '\end{thebibliography}' . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$latex .= '\end{document}' . "\n";
|
||||||
|
|
||||||
|
return $latex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转义LaTeX特殊字符
|
||||||
|
* @param string $text
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function escapeLatexText($text)
|
||||||
|
{
|
||||||
|
// 移除HTML标签
|
||||||
|
$text = strip_tags($text);
|
||||||
|
|
||||||
|
// 转义LaTeX特殊字符
|
||||||
|
$escape_chars = [
|
||||||
|
'\\' => '\\textbackslash{}',
|
||||||
|
'&' => '\\&',
|
||||||
|
'%' => '\\%',
|
||||||
|
'$' => '\\$',
|
||||||
|
'#' => '\\#',
|
||||||
|
'_' => '\\_',
|
||||||
|
'{' => '\\{',
|
||||||
|
'}' => '\\}',
|
||||||
|
'~' => '\\textasciitilde{}',
|
||||||
|
'^' => '\\textasciicircum{}',
|
||||||
|
'"' => '\\"{}',
|
||||||
|
'\'' => '\\\'{}',
|
||||||
|
'<' => '\\textless{}',
|
||||||
|
'>' => '\\textgreater{}',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($escape_chars as $char => $replacement) {
|
||||||
|
$text = str_replace($char, $replacement, $text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1250,338 +1250,6 @@ class Production extends Base
|
|||||||
// return jsonSuccess([]);
|
// return jsonSuccess([]);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成LaTeX文档并转换为PDF
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
public function generateLatexPdf()
|
|
||||||
{
|
|
||||||
$data = $this->request->post();
|
|
||||||
$rule = new Validate([
|
|
||||||
'p_article_id' => 'require|number'
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!$rule->check($data)) {
|
|
||||||
return jsonError($rule->getError());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 获取文章信息
|
|
||||||
$p_info = $this->production_article_obj->where('p_article_id', $data['p_article_id'])->find();
|
|
||||||
if (!$p_info) {
|
|
||||||
return jsonError('文章实例不存在');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取作者信息
|
|
||||||
$authors = $this->production_article_author_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
|
|
||||||
|
|
||||||
// 获取机构信息
|
|
||||||
$organs = $this->production_article_organ_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->select();
|
|
||||||
|
|
||||||
// 获取正文内容
|
|
||||||
$main_contents = $this->production_article_main_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('p_main_id')->select();
|
|
||||||
|
|
||||||
// 获取参考文献
|
|
||||||
$references = $this->production_article_refer_obj->where('p_article_id', $data['p_article_id'])->where('state', 0)->order('index')->select();
|
|
||||||
|
|
||||||
// 构建LaTeX内容
|
|
||||||
$latex_content = $this->buildLatexContent($p_info, $authors, $organs, $main_contents, $references);
|
|
||||||
|
|
||||||
// 创建临时目录
|
|
||||||
$temp_dir = ROOT_PATH . 'public' . DS . 'temp_latex' . DS;
|
|
||||||
if (!is_dir($temp_dir)) {
|
|
||||||
mkdir($temp_dir, 0755, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成唯一的文件名
|
|
||||||
$filename = 'article_' . $p_info['p_article_id'] . '_' . time();
|
|
||||||
$tex_file = $temp_dir . $filename . '.tex';
|
|
||||||
$pdf_file = $temp_dir . $filename . '.pdf';
|
|
||||||
|
|
||||||
// 写入LaTeX文件
|
|
||||||
file_put_contents($tex_file, $latex_content);
|
|
||||||
|
|
||||||
// 执行LaTeX编译命令生成PDF
|
|
||||||
$command = sprintf(
|
|
||||||
'cd %s && pdflatex -interaction=nonstopmode -output-directory=%s %s',
|
|
||||||
escapeshellarg($temp_dir),
|
|
||||||
escapeshellarg($temp_dir),
|
|
||||||
escapeshellarg($tex_file)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 执行命令
|
|
||||||
$output = [];
|
|
||||||
$return_var = 0;
|
|
||||||
exec($command, $output, $return_var);
|
|
||||||
|
|
||||||
// 检查PDF是否生成成功
|
|
||||||
if (!file_exists($pdf_file) || filesize($pdf_file) == 0) {
|
|
||||||
return jsonError('PDF生成失败,请检查LaTeX内容或系统环境');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移动PDF到正式目录
|
|
||||||
$pdf_dir = ROOT_PATH . 'public' . DS . 'latex_pdfs' . DS;
|
|
||||||
if (!is_dir($pdf_dir)) {
|
|
||||||
mkdir($pdf_dir, 0755, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$final_pdf_path = $pdf_dir . $filename . '.pdf';
|
|
||||||
rename($pdf_file, $final_pdf_path);
|
|
||||||
|
|
||||||
// 清理临时文件
|
|
||||||
if (file_exists($tex_file)) {
|
|
||||||
unlink($tex_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清理辅助文件(.aux, .log等)
|
|
||||||
$aux_file = $temp_dir . $filename . '.aux';
|
|
||||||
$log_file = $temp_dir . $filename . '.log';
|
|
||||||
if (file_exists($aux_file)) unlink($aux_file);
|
|
||||||
if (file_exists($log_file)) unlink($log_file);
|
|
||||||
|
|
||||||
// 返回PDF路径
|
|
||||||
$relative_path = 'latex_pdfs/' . $filename . '.pdf';
|
|
||||||
return jsonSuccess([
|
|
||||||
'pdf_url' => $relative_path,
|
|
||||||
'message' => 'PDF生成成功'
|
|
||||||
]);
|
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return jsonError('生成过程中发生错误: ' . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建LaTeX文档内容
|
|
||||||
* @param $p_info
|
|
||||||
* @param $authors
|
|
||||||
* @param $organs
|
|
||||||
* @param $main_contents
|
|
||||||
* @param $references
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function buildLatexContent($p_info, $authors, $organs, $main_contents, $references)
|
|
||||||
{
|
|
||||||
// 构建机构映射
|
|
||||||
$organ_map = [];
|
|
||||||
foreach ($organs as $index => $organ) {
|
|
||||||
$organ_map[$organ['p_article_organ_id']] = $index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LaTeX文档开始
|
|
||||||
$latex = '\documentclass[twocolumn]{article}' . "\n";
|
|
||||||
$latex .= '\usepackage[utf8]{inputenc}' . "\n";
|
|
||||||
$latex .= '\usepackage[T1]{fontenc}' . "\n";
|
|
||||||
$latex .= '\usepackage{geometry}' . "\n";
|
|
||||||
$latex .= '\usepackage{graphicx}' . "\n";
|
|
||||||
$latex .= '\usepackage{amsmath}' . "\n";
|
|
||||||
$latex .= '\usepackage{amsfonts}' . "\n";
|
|
||||||
$latex .= '\usepackage{amssymb}' . "\n";
|
|
||||||
$latex .= '\usepackage{setspace}' . "\n";
|
|
||||||
$latex .= '\usepackage{titlesec}' . "\n";
|
|
||||||
$latex .= '\usepackage{hyperref}' . "\n";
|
|
||||||
$latex .= '\usepackage{caption}' . "\n";
|
|
||||||
$latex .= '\usepackage{multicol}' . "\n";
|
|
||||||
$latex .= '\usepackage{abstract}' . "\n";
|
|
||||||
|
|
||||||
$latex .= '\geometry{left=1.5cm,right=1.5cm,top=2.5cm,bottom=2.5cm}' . "\n";
|
|
||||||
$latex .= '\setstretch{1.5}' . "\n";
|
|
||||||
|
|
||||||
$latex .= '\title{' . $this->escapeLatexText($p_info['title']) . '}' . "\n";
|
|
||||||
|
|
||||||
// 处理作者和机构
|
|
||||||
if (!empty($authors)) {
|
|
||||||
$author_text = '';
|
|
||||||
$affiliations = [];
|
|
||||||
|
|
||||||
foreach ($authors as $author) {
|
|
||||||
if ($author_text !== '') {
|
|
||||||
$author_text .= ', ';
|
|
||||||
}
|
|
||||||
$author_text .= $this->escapeLatexText($author['first_name'] . ' ' . $author['last_name']);
|
|
||||||
|
|
||||||
// 获取作者的机构
|
|
||||||
$author_organs = $this->production_article_author_to_organ_obj
|
|
||||||
->where('p_article_author_id', $author['p_article_author_id'])
|
|
||||||
->where('state', 0)
|
|
||||||
->select();
|
|
||||||
|
|
||||||
foreach ($author_organs as $ao) {
|
|
||||||
if (isset($organ_map[$ao['p_article_organ_id']])) {
|
|
||||||
$author_text .= '$^{' . $organ_map[$ao['p_article_organ_id']] . '}$';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($author['is_report'] == 1) {
|
|
||||||
$author_text .= '$^{*}$';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$latex .= '\author{' . $author_text . "\n";
|
|
||||||
|
|
||||||
// 添加机构信息
|
|
||||||
foreach ($organs as $index => $organ) {
|
|
||||||
$latex .= '\\\\$' . ($index + 1) . '$ ' . $this->escapeLatexText($organ['organ_name']) . "\n";
|
|
||||||
}
|
|
||||||
if (!empty($authors)) {
|
|
||||||
// 查找通讯作者
|
|
||||||
$corresponding_authors = array_filter($authors, function($author) {
|
|
||||||
return $author['is_report'] == 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!empty($corresponding_authors)) {
|
|
||||||
$corr_author = reset($corresponding_authors);
|
|
||||||
$latex .= '\\\\$*$ Corresponding author: ' .
|
|
||||||
$this->escapeLatexText($corr_author['email']) . "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$latex .= '}' . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$latex .= '\date{}' . "\n";
|
|
||||||
$latex .= '\begin{document}' . "\n";
|
|
||||||
$latex .= '\maketitle' . "\n";
|
|
||||||
|
|
||||||
// 摘要
|
|
||||||
if (!empty($p_info['abstract'])) {
|
|
||||||
$latex .= '\begin{abstract}' . "\n";
|
|
||||||
$latex .= $this->escapeLatexText($p_info['abstract']) . "\n";
|
|
||||||
$latex .= '\end{abstract}' . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关键词
|
|
||||||
if (!empty($p_info['keywords'])) {
|
|
||||||
$latex .= '\textbf{Keywords:} ' . $this->escapeLatexText($p_info['keywords']) . "\n";
|
|
||||||
$latex .= '\sectionbreak' . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 正文内容
|
|
||||||
$in_section = false;
|
|
||||||
$section_count = 0;
|
|
||||||
|
|
||||||
foreach ($main_contents as $content) {
|
|
||||||
$text = trim($content['content']);
|
|
||||||
|
|
||||||
// 跳过空内容
|
|
||||||
if (empty($text)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否是标题
|
|
||||||
$clean_text = strip_tags($text);
|
|
||||||
$lower_text = strtolower($clean_text);
|
|
||||||
|
|
||||||
// 判断是否为章节标题
|
|
||||||
if (stripos($lower_text, 'introduction') === 0 ||
|
|
||||||
stripos($lower_text, 'methods') === 0 ||
|
|
||||||
stripos($lower_text, 'results') === 0 ||
|
|
||||||
stripos($lower_text, 'discussion') === 0 ||
|
|
||||||
stripos($lower_text, 'conclusion') === 0 ||
|
|
||||||
stripos($lower_text, 'references') === 0) {
|
|
||||||
|
|
||||||
// 结束前一节
|
|
||||||
if ($in_section) {
|
|
||||||
$latex .= "\n" . '\sectionbreak' . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开始新节
|
|
||||||
$section_count++;
|
|
||||||
$section_title = $this->escapeLatexText($clean_text);
|
|
||||||
$latex .= '\section{' . $section_title . '}' . "\n";
|
|
||||||
$in_section = true;
|
|
||||||
}
|
|
||||||
// 检查是否是图片或表格占位符
|
|
||||||
else if (preg_match('/<img[^>]*imageId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $img_matches)) {
|
|
||||||
$image_id = $img_matches[1];
|
|
||||||
// 这里可以添加图片处理逻辑
|
|
||||||
$latex .= '% 图片插入位置 (ID: ' . $image_id . ')' . "\n";
|
|
||||||
$latex .= '\begin{figure}[htbp]' . "\n";
|
|
||||||
$latex .= '\centering' . "\n";
|
|
||||||
$latex .= '\includegraphics[width=0.8\textwidth]{image_' . $image_id . '}' . "\n";
|
|
||||||
$latex .= '\caption{图片说明}' . "\n";
|
|
||||||
$latex .= '\end{figure}' . "\n";
|
|
||||||
}
|
|
||||||
else if (preg_match('/<table[^>]*tableId=[\'"]([^\'"]+)[\'"][^>]*>/i', $text, $table_matches)) {
|
|
||||||
$table_id = $table_matches[1];
|
|
||||||
// 这里可以添加表格处理逻辑
|
|
||||||
$latex .= '% 表格插入位置 (ID: ' . $table_id . ')' . "\n";
|
|
||||||
$latex .= '\begin{table}[htbp]' . "\n";
|
|
||||||
$latex .= '\centering' . "\n";
|
|
||||||
$latex .= '\caption{表格说明}' . "\n";
|
|
||||||
$latex .= '\begin{tabular}{|c|c|c|}' . "\n";
|
|
||||||
$latex .= '\hline' . "\n";
|
|
||||||
$latex .= '列1 & 列2 & 列3 \\\\' . "\n";
|
|
||||||
$latex .= '\hline' . "\n";
|
|
||||||
$latex .= '% 表格数据' . "\n";
|
|
||||||
$latex .= '\hline' . "\n";
|
|
||||||
$latex .= '\end{tabular}' . "\n";
|
|
||||||
$latex .= '\end{table}' . "\n";
|
|
||||||
}
|
|
||||||
// 普通段落文本
|
|
||||||
else {
|
|
||||||
// 移除HTML标签并转义特殊字符
|
|
||||||
$plain_text = $this->escapeLatexText(strip_tags($text));
|
|
||||||
$latex .= $plain_text . "\n\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 参考文献
|
|
||||||
if (!empty($references)) {
|
|
||||||
$latex .= '\section*{References}' . "\n";
|
|
||||||
$latex .= '\begin{thebibliography}{99}' . "\n";
|
|
||||||
|
|
||||||
foreach ($references as $index => $ref) {
|
|
||||||
$ref_text = isset($ref['refer_frag']) ? $ref['refer_frag'] : $ref['refer_content'];
|
|
||||||
$latex .= '\bibitem{} ' . $this->escapeLatexText($ref_text) . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$latex .= '\end{thebibliography}' . "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$latex .= '\end{document}' . "\n";
|
|
||||||
|
|
||||||
return $latex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转义LaTeX特殊字符
|
|
||||||
* @param string $text
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function escapeLatexText($text)
|
|
||||||
{
|
|
||||||
// 移除HTML标签
|
|
||||||
$text = strip_tags($text);
|
|
||||||
|
|
||||||
// 转义LaTeX特殊字符
|
|
||||||
$escape_chars = [
|
|
||||||
'\\' => '\\textbackslash{}',
|
|
||||||
'&' => '\\&',
|
|
||||||
'%' => '\\%',
|
|
||||||
'$' => '\\$',
|
|
||||||
'#' => '\\#',
|
|
||||||
'_' => '\\_',
|
|
||||||
'{' => '\\{',
|
|
||||||
'}' => '\\}',
|
|
||||||
'~' => '\\textasciitilde{}',
|
|
||||||
'^' => '\\textasciicircum{}',
|
|
||||||
'"' => '\\"{}',
|
|
||||||
'\'' => '\\\'{}',
|
|
||||||
'<' => '\\textless{}',
|
|
||||||
'>' => '\\textgreater{}',
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($escape_chars as $char => $replacement) {
|
|
||||||
$text = str_replace($char, $replacement, $text);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function addProductTopic(){
|
public function addProductTopic(){
|
||||||
$data = $this->request->post();
|
$data = $this->request->post();
|
||||||
$rule = new Validate([
|
$rule = new Validate([
|
||||||
@@ -1705,8 +1373,8 @@ private function escapeLatexText($text)
|
|||||||
$typesetInfo['website'] = $journal_info['website'];
|
$typesetInfo['website'] = $journal_info['website'];
|
||||||
$typesetInfo['acknowledgment'] = $p_info['acknowledgment'];
|
$typesetInfo['acknowledgment'] = $p_info['acknowledgment'];
|
||||||
|
|
||||||
$received_info = $this->article_msg_obj->where("article_id",$p_info['article_id'])->where("state_from",4)->where("state_to",1)->find();
|
// $received_info = $this->article_msg_obj->where("article_id",$p_info['article_id'])->where("state_from",4)->where("state_to",1)->find();
|
||||||
$received_data = $received_info?$received_info['ctime']:$article_info['ctime'];
|
$received_data = $article_info['received_time']>0?$article_info['received_time']:$article_info['ctime'];
|
||||||
$typesetInfo['received_date'] = date("d F Y", $received_data);
|
$typesetInfo['received_date'] = date("d F Y", $received_data);
|
||||||
|
|
||||||
$super_num = $this->article_author_obj->where("article_id",$p_info['article_id'])->where("state",0)->where("is_super",1)->count();
|
$super_num = $this->article_author_obj->where("article_id",$p_info['article_id'])->where("state",0)->where("is_super",1)->count();
|
||||||
|
|||||||
Reference in New Issue
Block a user