'read',
'channelType' => 'translation',
'contentType' => 'markdown',
'format' => 'react',
'debug' => [],
'studioId' => null,
'lang' => 'zh-Hans',
'footnote' => false,
'paragraph' => false,
];
public function __construct($options = [])
{
foreach ($options as $key => $value) {
$this->options[$key] = $value;
}
}
/**
* 将句子模版组成的段落复制一份,为了实现巴汉逐段对读
*/
private function preprocessingForParagraph($input)
{
if (! $this->options['paragraph']) {
return $input;
}
$paragraphs = explode("\n\n", $input);
$output = [];
foreach ($paragraphs as $key => $paragraph) {
// 判断是否是纯粹的句子模版
$pattern = "/\{\{sent\|id=([0-9].+?)\}\}/";
$replacement = '';
$space = preg_replace($pattern, $replacement, $paragraph);
$space = str_replace('>', '', $space);
if (empty(trim($space))) {
$output[] = str_replace('}}', '|text=origin}}', $paragraph);
$output[] = str_replace('}}', '|text=translation}}', $paragraph);
} else {
$output[] = $paragraph;
}
}
return implode("\n\n", $output);
}
/**
* 按照{{}}把字符串切分成三个部分。模版之前的,模版,和模版之后的
*/
private function tplSplit($tpl)
{
$before = strpos($tpl, '{{');
if ($before === false) {
// 未找到
return ['data' => [$tpl, '', ''], 'error' => 0];
} else {
$pointer = $before;
$stack = [];
$stack[] = $pointer;
$after = substr($tpl, $pointer + 2);
while (! empty($after) && count($stack) > 0 && count($stack) < STACK_DEEP) {
$nextBegin = strpos($after, '{{');
$nextEnd = strpos($after, '}}');
if ($nextBegin !== false) {
if ($nextBegin < $nextEnd) {
// 有嵌套找到最后一个}}
$pointer = $pointer + 2 + $nextBegin;
$stack[] = $pointer;
$after = substr($tpl, $pointer + 2);
} elseif ($nextEnd !== false) {
// 无嵌套有结束
$pointer = $pointer + 2 + $nextEnd;
array_pop($stack);
$after = substr($tpl, $pointer + 2);
} else {
// 无结束符 没找到
break;
}
} elseif ($nextEnd !== false) {
$pointer = $pointer + 2 + $nextEnd;
array_pop($stack);
$after = substr($tpl, $pointer + 2);
} else {
// 没找到
break;
}
}
if (count($stack) > 0) {
if (count($stack) === STACK_DEEP) {
return ['data' => [$tpl, '', ''], 'error' => 2];
} else {
// 未关闭
return ['data' => [$tpl, '', ''], 'error' => 1];
}
} else {
return [
'data' => [
substr($tpl, 0, $before),
substr($tpl, $before, $pointer - $before + 2),
substr($tpl, $pointer + 2),
],
'error' => 0,
];
}
}
}
private function wiki2xml(string $wiki, $channelId = []): string
{
/**
* 渲染markdown里面的模版
*/
$remain = $wiki;
$buffer = [];
do {
$arrWiki = $this->tplSplit($remain);
$buffer[] = $arrWiki['data'][0];
$tpl = $arrWiki['data'][1];
if (! empty($tpl)) {
/**
* 处理模版 提取参数
*/
$tpl = str_replace("|\n", '|', $tpl);
$pattern = "/\{\{(.+?)\|/";
$replacement = '
['.$footnote['sn'].'] '.$footnote['content'].'
'; } $output .= ']*>.*?<\/p>/is', $html, $matches); if (count($matches[0]) === 1) { return preg_replace( ['/^\s*
]*)>/i', '/<\/p>\s*$/i'], ['', ''], $html ); } return $html; } }