生成pdf

This commit is contained in:
chengxl
2025-12-31 16:06:35 +08:00
parent 85d441cc60
commit 838e25028f

View File

@@ -37,7 +37,7 @@ year={{stage_year}},%年
volume={{stage_vol}},%卷
no={{stage_no}},%期
page={{stage_page}},%号
]{tmr-tex}
]{../tmr-tex}
\doi{{{doi}}}
\journalweb{{{website}}}
@@ -49,18 +49,15 @@ page={{stage_page}},%号
\usepackage[nopatch]{microtype}
\usepackage{booktabs}
\usepackage[backend=biber]{biblatex}
\usepackage{xcolor} % 蓝色字体(参考文献)
\usepackage{multirow} % 单元格合并(必选)
\usepackage{array} % 列格式居中(必选)
\usepackage{geometry} % 页面适配,避免内容溢出
\addbibresource{example.bib}
\usepackage{xcolor}
\usepackage{tabularray}
\addbibresource{references_{{p_article_id}}.bib}
\definecolor{evenRowColor}{RGB}{250,231,232}
\title{{{article_title}}}
{{author_info}}
\addbibresource{example.bib}
{{correspondence_info}}
@@ -87,6 +84,8 @@ page={{stage_page}},%号
\twocolumn
{{tmr_highlight}}
{{article_main}}
\nocite{*}
\printbibliography[title={References}]
\end{document}';
/**
* 生成初稿-基本内容
@@ -211,6 +210,7 @@ page={{stage_page}},%号
$aSearch['{{article_icon}}'] = $sIcon;
$aSearch['{{keywords}}'] = $sKeywords;
$aSearch['{{CLSFILEURL}}'] = ROOT_PATH.'public/latex/cls';
$aSearch['{{p_article_id}}'] = $aProductionArticle['p_article_id'];
//模版内容替换
$sTemplateInfo = str_replace(array_keys($aSearch), array_values($aSearch), $sTemplateInfo);
//返回内容
@@ -220,8 +220,11 @@ page={{stage_page}},%号
* 生成初稿-主内容
* @param article_id 文章ID
*/
public function buildMain($aProductionArticle = []){
public function buildMain($aParam = []){
//生产环境文章信息
$aProductionArticle = empty($aParam['production_article']) ? [] : $aParam['production_article'];
//参考文献信息
$aReferences = empty($aParam['references']) ? [] : $aParam['references'];
//获取模版
$sTemplateInfo = $this->sMain;
@@ -256,17 +259,19 @@ page={{stage_page}},%号
$aWhere = ['ami_id' => ['in',$aAmiId],'state' => 0];
$aArticleMainImage = Db::name('article_main_image')->field('ami_id,url,note')->where($aWhere)->select();
$aArticleMainImage = empty($aArticleMainImage) ? [] : array_column($aArticleMainImage, null,'ami_id');
//查询表格
$aAmtId = array_unique(array_column($aArticleMain, 'amt_id'));
$aWhere = ['amt_id' => ['in',$aAmtId],'state' => 0];
$aArticleMainTable = Db::name('article_main_table')->field('amt_id,type,table_data,url,title,note')->where($aWhere)->select();
$aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
// //查询表格
// $aAmtId = array_unique(array_column($aArticleMain, 'amt_id'));
// $aWhere = ['amt_id' => ['in',$aAmtId],'state' => 0];
// $aArticleMainTable = Db::name('article_main_table')->field('amt_id,type,table_data,url,title,note')->where($aWhere)->select();
// $aArticleMainTable = empty($aArticleMainTable) ? [] : array_column($aArticleMainTable, null,'amt_id');
//获取图片模版
$sImageTempalte = $this->sImageTempalte;
//数据处理
$iStart = 0;
$sMain = '';
$oLatexTable = new LaTeXTable;
//字符串处理
$oProduction = new \app\api\controller\Production;
foreach ($aArticleMain as $key => $value) {
if(empty($iStart)){
if($value['is_h1'] == 0){
@@ -296,7 +301,7 @@ page={{stage_page}},%号
}
if($value['is_h1'] == 0 && $value['is_h2'] == 0 && $value['is_h3'] == 0){
if($value['type'] == 0 ){
$sMain .= $this->dealContent($value['content'])."\\par\n";
$sMain .= $this->dealContent($value['content'],$aReferences)."\\par\n";
}
if($value['type'] == 1 ){//图片
$aImageInfo = empty($aArticleMainImage[$value['ami_id']]) ? [] : $aArticleMainImage[$value['ami_id']];
@@ -321,8 +326,20 @@ page={{stage_page}},%号
$sMain .= $sImageTempalteInfo."\\par\n";
}
if($value['type'] == 2 ){//表格
continue;
$sTableInfo = $oProduction->tableCovertLatex($value['amt_id'],$aReferences);
var_dump($sTableInfo);
$sMain .= $sTableInfo."\\par\n";
// $aTableInfo = empty($aArticleMainTable[$value['amt_id']]) ? [] : $aArticleMainTable[$value['amt_id']];
// if(empty($aTableInfo['table_data'])){
// continue;
// }
// $aTableResult = $oLatexTable->generateTable($aTableInfo);
// var_dump($aTableResult);exit;
// if(empty($aTableResult['data'])){
// continue;
// }
}
}
}
}
@@ -536,40 +553,138 @@ page={{stage_page}},%号
/**
* 内容处理
*/
private function dealContent($content = '', $target = 'latex',$iIsDeal = 1) {
// private function dealContent($content = '', $target = 'latex',$iIsDeal = 1) {
// // 空值直接返回
// if (empty($content)) {
// return '';
// }
// //统一编码为UTF-8
// $content = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content));
// //过滤不可见/非法字符
// $content = preg_replace('/[\x00-\x1F\x7F]/u', '', $content);
// //整合所有替换规则按优先级排序先处理HTML实体再处理LaTeX特殊字符
// $replaceRules = [
// // ========== HTML实体替换 ==========
// ' ' => '~', // HTML非断行空格 → LaTeX非断行空格
// '&nbsp' => '~', // 兼容无分号的&nbsp
// '&' => '\&', // HTML& → LaTeX转义&
// '&lt;' => '<', // HTML< → 直接保留
// '&gt;' => '>', // HTML> → 直接保留
// // ========== LaTeX特殊字符转义 ==========
// '{' => '\{', // 左花括号转义
// '}' => '\}', // 右花括号转义
// '&' => '\&', // 原生&转义(需在&amp;之后,避免覆盖)
// '%' => '\%', // 百分号转义LaTeX注释符
// '_' => '\_', // 下划线转义LaTeX下标符
// 'κ' => '$\kappa$', // 希腊字母κ → LaTeX数学环境避免乱码
// '-' => '\text{-}', // 短横线强制保留形态
// ':' => ':', // 冒号无需转义(占位,便于统一维护)
// ];
// //执行批量替换
// $content = strtr($content, $replaceRules);
// //清理多余空格/换行
// $content = preg_replace('/\s+/u', ' ', trim($content));
// if($iIsDeal == 1){
// $content = $this->htmlToLaTeX($content);
// }
// return $content;
// }
private function dealContent($content = '',$aReferences = []) {
// 空值直接返回
if (empty($content)) {
if(empty($content)){
return '';
}
//统一编码为UTF-8
$content = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content));
//过滤不可见/非法字符
$content = preg_replace('/[\x00-\x1F\x7F]/u', '', $content);
//整合所有替换规则按优先级排序先处理HTML实体再处理LaTeX特殊字符
$replaceRules = [
// ========== HTML实体替换 ==========
'&nbsp;' => '~', // HTML非断行空格 → LaTeX非断行空格
'&nbsp' => '~', // 兼容无分号的&nbsp
'&amp;' => '\&', // HTML& → LaTeX转义&
'&lt;' => '<', // HTML< → 直接保留
'&gt;' => '>', // HTML> → 直接保留
// ========== LaTeX特殊字符转义 ==========
'{' => '\{', // 左花括号转义
'}' => '\}', // 右花括号转义
'&' => '\&', // 原生&转义(需在&amp;之后,避免覆盖)
'%' => '\%', // 百分号转义LaTeX注释符
'_' => '\_', // 下划线转义LaTeX下标符
'κ' => '$\kappa$', // 希腊字母κ → LaTeX数学环境避免乱码
'-' => '\text{-}', // 短横线强制保留形态
':' => ':', // 冒号无需转义(占位,便于统一维护)
//字符串处理
$oProduction = new \app\api\controller\Production;
$sContent = $oProduction->convertToLatex($content,$aReferences);
$content = $this->htmlToLaTeX($content);
return $sContent;
// //整合所有替换规则按优先级排序先处理HTML实体再处理LaTeX特殊字符
// $replaceRules = [
// // ========== HTML实体替换 ==========
// '&nbsp;' => '~', // HTML非断行空格 → LaTeX非断行空格
// '&nbsp' => '~', // 兼容无分号的&nbsp
// '&amp;' => '\&', // HTML& → LaTeX转义&
// '&lt;' => '<', // HTML< → 直接保留
// '&gt;' => '>', // HTML> → 直接保留
// // ========== LaTeX特殊字符转义 ==========
// '{' => '\{', // 左花括号转义
// '}' => '\}', // 右花括号转义
// '&' => '\&', // 原生&转义(需在&amp;之后,避免覆盖)
// '%' => '\%', // 百分号转义LaTeX注释符
// '_' => '\_', // 下划线转义LaTeX下标符
// 'κ' => '$\kappa$', // 希腊字母κ → LaTeX数学环境避免乱码
// '-' => '\text{-}', // 短横线强制保留形态
// ':' => ':', // 冒号无需转义(占位,便于统一维护)
// ];
// //执行批量替换
// $content = strtr($content, $replaceRules);
// //清理多余空格/换行
// $content = preg_replace('/\s+/u', ' ', trim($content));
// if($iIsDeal == 1){
// $content = $this->htmlToLaTeX($content);
// }
// return $content;
}
private function htmlToLaTeX($text = ''){
if(empty($text)){
return '';
}
$replaceMap = [
// 基础标签转换
'<i>' => '\textit{',
'</i>' => '}',
'<em>' => '\textit{',
'</em>' => '}',
'<b>' => '\textbf{',
'</b>' => '}',
'<blue>' => '\textcolor{blue}{',
'</blue>' => '}',
'<p>' => '',
'</p>' => '',
'<sub>' => '$_{',
'</sub>' => '}$',
'<sup>' => '$^{',
'</sup>' => '}$',
'~' => '--', // 波浪号→范围符
'' => '(', // 全角左括号→半角
'' => ')', // 全角右括号→半角
'(' => '(', // 重复括号去重
')' => ')',
// ========== 新增:<span> 标签处理 ==========
// 场景1纯空 <span> 标签(无属性)→ 直接删除,保留内容
'<span>' => '',
'</span>' => '',
// 场景2带蓝色样式的 <span style="color:blue"> → 转为 LaTeX 蓝色命令
'<span style="color:blue">' => '\textcolor{blue}{',
'<span style="color: Blue;">' => '\textcolor{blue}{', // 兼容大小写/空格
'<span style="color:red">' => '\textcolor{red}{', // 扩展:红色
'</span>' => '}', // 所有 span 闭标签统一转为 }(匹配开标签的 LaTeX 命令)
// 扩展:其他常用 span 样式(按需添加)
'<span style="font-weight:bold">' => '\textbf{',
'<span style="font-style:italic">' => '\textit{',
];
//执行批量替换
$content = strtr($content, $replaceRules);
//清理多余空格/换行
$content = preg_replace('/\s+/u', ' ', trim($content));
return $content;
// 第一步:替换所有标签(优先处理带属性的 span再处理空 span
$text = strtr($text, $replaceMap);
// 第二步:清理残留的特殊 span 标签(如未匹配的属性,直接删除标签保留内容)
// 匹配 <span ...> 形式的标签(任意属性),仅删除标签,保留内容
$text = preg_replace('/<span(\s+[^>]*?)?>/i', '', $text);
$text = preg_replace('/<\/span>/i', '', $text);
return $text;
}
/**
* @title curl 请求获取图片保存到本地