function markup(&$body, $track_cites = false, $op = false) { global $board, $config, $markup_urls; $modifiers = extract_modifiers($body); $body = preg_replace('@<tinyboard (?!escape )([\\w\\s]+)>(.+?)</tinyboard>@us', '', $body); $body = preg_replace('@<(tinyboard) escape ([\\w\\s]+)>@i', '<$1 $2>', $body); if (isset($modifiers['raw html']) && $modifiers['raw html'] == '1') { return array(); } $body = str_replace("\r", '', $body); $body = utf8tohtml($body); if (mysql_version() < 50503) { $body = mb_encode_numericentity($body, array(0x10000, 0xffffff, 0, 0xffffff), 'UTF-8'); } foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); } elseif (is_callable($markup[1])) { $body = preg_replace_callback($markup[0], $markup[1], $body); } } if ($config['markup_urls']) { $markup_urls = array(); $body = preg_replace_callback('/((?:https?:\\/\\/|ftp:\\/\\/|irc:\\/\\/)[^\\s<>()"]+?(?:\\([^\\s<>()"]*?\\)[^\\s<>()"]*?)*)((?:\\s|<|>|"|\\.||\\]|!|\\?|,|,|")*(?:[\\s<>()"]|$))/', 'markup_url', $body, -1, $num_links); if ($num_links > $config['max_links']) { error($config['error']['toomanylinks']); } if ($num_links < $config['min_links'] && $op) { error(sprintf($config['error']['notenoughlinks'], $config['min_links'])); } } if ($config['markup_repair_tidy']) { $body = str_replace(' ', ' ', $body); } if ($config['auto_unicode']) { $body = unicodify($body); if ($config['markup_urls']) { foreach ($markup_urls as &$url) { $body = str_replace(unicodify($url), $url, $body); } } } $tracked_cites = array(); // Cites if (isset($board) && preg_match_all('/(^|\\s)>>(\\d+?)([\\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } $skip_chars = 0; $body_tmp = $body; $search_cites = array(); foreach ($cites as $matches) { $search_cites[] = '`id` = ' . $matches[2][0]; } $search_cites = array_unique($search_cites); $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $search_cites), $board['uri'])) or error(db_error()); $cited_posts = array(); while ($cited = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$cited['id']] = $cited['thread'] ? $cited['thread'] : false; } foreach ($cites as $matches) { $cite = $matches[2][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if (isset($cited_posts[$cite])) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\', event);" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . ($cited_posts[$cite] ? $cited_posts[$cite] : $cite) . '.html#' . $cite . '">' . '>>' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $cite); } } } } // Cross-board linking if (preg_match_all('/(^|\\s)>>>\\/(' . $config['board_regex'] . 'f?)\\/(\\d+)?([\\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } $skip_chars = 0; $body_tmp = $body; if (isset($cited_posts)) { // Carry found posts from local board >>X links foreach ($cited_posts as $cite => $thread) { $cited_posts[$cite] = $config['root'] . $board['dir'] . $config['dir']['res'] . ($thread ? $thread : $cite) . '.html#' . $cite; } $cited_posts = array($board['uri'] => $cited_posts); } else { $cited_posts = array(); } $crossboard_indexes = array(); $search_cites_boards = array(); foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; if (!isset($search_cites_boards[$_board])) { $search_cites_boards[$_board] = array(); } $search_cites_boards[$_board][] = $cite; } $tmp_board = $board['uri']; foreach ($search_cites_boards as $_board => $search_cites) { $clauses = array(); foreach ($search_cites as $cite) { if (!$cite || isset($cited_posts[$_board][$cite])) { continue; } $clauses[] = '`id` = ' . $cite; } $clauses = array_unique($clauses); if ($board['uri'] != $_board) { if (!openBoard($_board)) { continue; } // Unknown board } if (!empty($clauses)) { $cited_posts[$_board] = array(); $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $clauses), $board['uri'])) or error(db_error()); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$_board][$cite['id']] = $config['root'] . $board['dir'] . $config['dir']['res'] . ($cite['thread'] ? $cite['thread'] : $cite['id']) . '.html#' . $cite['id']; } } $crossboard_indexes[$_board] = $config['root'] . $board['dir'] . $config['file_index']; } // Restore old board if (!$tmp_board) { unset($GLOBALS['board']); } elseif ($board['uri'] != $tmp_board) { openBoard($tmp_board); } foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if ($cite) { if (isset($cited_posts[$_board][$cite])) { $link = $cited_posts[$_board][$cite]; $replacement = '<a ' . ($_board == $board['uri'] ? 'onclick="highlightReply(\'' . $cite . '\', event);" ' : '') . 'href="' . $link . '">' . '>>>/' . $_board . '/' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($_board, $cite); } } } elseif (isset($crossboard_indexes[$_board])) { $replacement = '<a href="' . $crossboard_indexes[$_board] . '">' . '>>>/' . $_board . '/' . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); } } } $tracked_cites = array_unique($tracked_cites, SORT_REGULAR); if ($config['strip_superfluous_returns']) { $body = preg_replace('/\\s+$/', '', $body); } if ($config['markup_paragraphs']) { $paragraphs = explode("\n", $body); $bodyNew = ""; $tagsOpen = false; // Matches <a>, <a href="" title="">, but not <img/> and returns a $matchOpen = "#<([A-Z][A-Z0-9]*)+(?:(?:\\s+\\w+(?:\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))?)+\\s*|\\s*)>#i"; // Matches </a> returns a $matchClose = "#</([A-Z][A-Z0-9]*/?)>#i"; $tagsOpened = array(); $tagsClosed = array(); foreach ($paragraphs as $paragraph) { // Determine if RTL based on content of line. if (strlen(trim($paragraph)) > 0) { $paragraphDirection = is_rtl($paragraph) ? "rtl" : "ltr"; } else { $paragraphDirection = "empty"; } // Add in a quote class for >quotes. if (strpos($paragraph, ">") === 0) { $quoteClass = "quote"; } else { $quoteClass = ""; } // If tags are closed, start a new line. if ($tagsOpen === false) { $bodyNew .= "<p class=\"body-line {$paragraphDirection} {$quoteClass}\">"; } // If tags are open, add the paragraph to our temporary holder instead. if ($tagsOpen !== false) { $tagsOpen .= $paragraph; // Recheck tags to see if we've formed a complete tag with this latest line. if (preg_match_all($matchOpen, $tagsOpen, $tagsOpened) === preg_match_all($matchClose, $tagsOpen, $tagsClosed)) { sort($tagsOpened[1]); sort($tagsClosed[1]); // Double-check to make sure these are the same tags. if (count(array_diff_assoc($tagsOpened[1], $tagsClosed[1])) === 0) { // Tags are closed! \o/ $bodyNew .= $tagsOpen; $tagsOpen = false; } } } else { if (preg_match_all($matchOpen, $paragraph, $tagsOpened) === preg_match_all($matchClose, $paragraph, $tagsClosed)) { sort($tagsOpened[1]); sort($tagsClosed[1]); // Double-check to make sure these are the same tags. if (count(array_diff_assoc($tagsOpened[1], $tagsClosed[1])) === 0) { $bodyNew .= $paragraph; } } else { // Tags are open! $tagsOpen = $paragraph; } } // If tags are open, do not close it. if (!$tagsOpen) { $bodyNew .= "</p>"; } else { if ($tagsOpen !== false) { $tagsOpen .= "<br />"; } } } if ($tagsOpen !== false) { $bodyNew .= $tagsOpen; } $body = $bodyNew; } else { $body = preg_replace("/^\\s*>.*\$/m", '<span class="quote">$0</span>', $body); $body = preg_replace("/\n/", '<br/>', $body); } if ($config['markup_repair_tidy']) { $tidy = new tidy(); $body = str_replace("\t", '	', $body); $body = $tidy->repairString($body, array('doctype' => 'omit', 'bare' => true, 'literal-attributes' => true, 'indent' => false, 'show-body-only' => true, 'wrap' => 0, 'output-bom' => false, 'output-html' => true, 'newline' => 'LF', 'quiet' => true), 'utf8'); $body = str_replace("\n", '', $body); } // replace tabs with 8 spaces $body = str_replace("\t", '	', $body); return $tracked_cites; }
function nt_hash($passwd) { return strtoupper(bin2hex(mhash(MHASH_MD4, unicodify($passwd)))); }
function markup(&$body, $track_cites = false) { global $board, $config, $markup_urls; $body = str_replace("\r", '', $body); $body = utf8tohtml($body); foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); } elseif (is_callable($markup[1])) { $body = preg_replace_callback($markup[0], $markup[1], $body); } } if ($config['markup_urls']) { $markup_urls = array(); $body = preg_replace_callback('/((?:https?:\\/\\/|ftp:\\/\\/|irc:\\/\\/)[^\\s<>()"]+?(?:\\([^\\s<>()"]*?\\)[^\\s<>()"]*?)*)((?:\\s|<|>|"|\\.||\\]|!|\\?|,|,|")*(?:[\\s<>()"]|$))/', 'markup_url', $body, -1, $num_links); if ($num_links > $config['max_links']) { error($config['error']['toomanylinks']); } } if ($config['auto_unicode']) { $body = unicodify($body); if ($config['markup_urls']) { foreach ($markup_urls as &$url) { $body = str_replace(unicodify($url), $url, $body); } } } // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); $tracked_cites = array(); // Cites if (isset($board) && preg_match_all('/(^|\\s)>>(\\d+?)([\\s,.)?]|$)/m', $body, $cites)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } for ($index = 0; $index < count($cites[0]); $index++) { $cite = $cites[2][$index]; $query = prepare(sprintf("SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); if ($post = $query->fetch()) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread'] ? $post['thread'] : $post['id']) . '.html#' . $cite . '">' . '>>' . $cite . '</a>'; $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[3][$index], $body); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $post['id']); } } } } // Cross-board linking if (preg_match_all('/(^|\\s)>>>\\/(\\w+?)\\/(\\d+)?([\\s,.)?]|$)/m', $body, $cites)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } for ($index = 0; $index < count($cites[0]); $index++) { $_board = $cites[2][$index]; $cite = @$cites[3][$index]; // Temporarily store board information because it will be overwritten $tmp_board = $board['uri']; // Check if the board exists, and load settings if (openBoard($_board)) { if ($cite) { $query = prepare(sprintf("SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); if ($post = $query->fetch()) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread'] ? $post['thread'] : $post['id']) . '.html#' . $cite . '">' . '>>>/' . $_board . '/' . $cite . '</a>'; $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[4][$index], $body); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $post['id']); } } } else { $replacement = '<a href="' . $config['root'] . $board['dir'] . $config['file_index'] . '">' . '>>>/' . $_board . '/' . '</a>'; $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[4][$index], $body); } } // Restore main board settings openBoard($tmp_board); } } $body = preg_replace("/^\\s*>.*\$/m", '<span class="quote">$0</span>', $body); if ($config['strip_superfluous_returns']) { $body = preg_replace('/\\s+$/', '', $body); } $body = preg_replace("/\n/", '<br/>', $body); return $tracked_cites; }
function markup(&$body, $track_cites = false) { global $board, $config, $markup_urls; $modifiers = extract_modifiers($body); $body = preg_replace('@<tinyboard (?!escape )([\\w\\s]+)>(.+?)</tinyboard>@us', '', $body); $body = preg_replace('@<(tinyboard) escape ([\\w\\s]+)>@i', '<$1 $2>', $body); if (isset($modifiers['raw html']) && $modifiers['raw html'] == '1') { return array(); } $body = str_replace("\r", '', $body); $body = utf8tohtml($body); if (mysql_version() < 50503) { $body = mb_encode_numericentity($body, array(0x10000, 0xffffff, 0, 0xffffff), 'UTF-8'); } if ($config['markup_code']) { $code_markup = array(); $body = preg_replace_callback($config['markup_code'], function ($matches) use(&$code_markup) { $d = count($code_markup); $code_markup[] = $matches; return "<code {$d}>"; }, $body); } foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); } elseif (is_callable($markup[1])) { $body = preg_replace_callback($markup[0], $markup[1], $body); } } if ($config['markup_urls']) { $markup_urls = array(); $body = preg_replace_callback('/((?:https?:\\/\\/|ftp:\\/\\/|irc:\\/\\/)[^\\s<>()"]+?(?:\\([^\\s<>()"]*?\\)[^\\s<>()"]*?)*)((?:\\s|<|>|"|\\.||\\]|!|\\?|,|,|")*(?:[\\s<>()"]|$))/', 'markup_url', $body, -1, $num_links); if ($num_links > $config['max_links']) { error($config['error']['toomanylinks']); } } if ($config['markup_repair_tidy']) { $body = str_replace(' ', ' ', $body); } if ($config['auto_unicode']) { $body = unicodify($body); if ($config['markup_urls']) { foreach ($markup_urls as &$url) { $body = str_replace(unicodify($url), $url, $body); } } } $tracked_cites = array(); // Cites if (isset($board) && preg_match_all('/(^|\\s)>>(\\d+?)([\\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } $skip_chars = 0; $body_tmp = $body; $search_cites = array(); foreach ($cites as $matches) { $search_cites[] = '`id` = ' . $matches[2][0]; } $search_cites = array_unique($search_cites); $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $search_cites), $board['uri'])) or error(db_error()); $cited_posts = array(); while ($cited = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$cited['id']] = $cited['thread'] ? $cited['thread'] : false; } foreach ($cites as $matches) { $cite = $matches[2][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if (isset($cited_posts[$cite])) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . link_for(array('id' => $cite, 'thread' => $cited_posts[$cite])) . '#' . $cite . '">' . '>>' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $cite); } } } } // Cross-board linking if (preg_match_all('/(^|\\s)>>>\\/(' . $config['board_regex'] . 'f?)\\/(\\d+)?([\\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } $skip_chars = 0; $body_tmp = $body; if (isset($cited_posts)) { // Carry found posts from local board >>X links foreach ($cited_posts as $cite => $thread) { $cited_posts[$cite] = $config['root'] . $board['dir'] . $config['dir']['res'] . ($thread ? $thread : $cite) . '.html#' . $cite; } $cited_posts = array($board['uri'] => $cited_posts); } else { $cited_posts = array(); } $crossboard_indexes = array(); $search_cites_boards = array(); foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; if (!isset($search_cites_boards[$_board])) { $search_cites_boards[$_board] = array(); } $search_cites_boards[$_board][] = $cite; } $tmp_board = $board['uri']; foreach ($search_cites_boards as $_board => $search_cites) { $clauses = array(); foreach ($search_cites as $cite) { if (!$cite || isset($cited_posts[$_board][$cite])) { continue; } $clauses[] = '`id` = ' . $cite; } $clauses = array_unique($clauses); if ($board['uri'] != $_board) { if (!openBoard($_board)) { continue; } // Unknown board } if (!empty($clauses)) { $cited_posts[$_board] = array(); $query = query(sprintf('SELECT `thread`, `id`, `slug` FROM ``posts_%s`` WHERE ' . implode(' OR ', $clauses), $board['uri'])) or error(db_error()); while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { $cited_posts[$_board][$cite['id']] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($cite) . '#' . $cite['id']; } } $crossboard_indexes[$_board] = $config['root'] . $board['dir'] . $config['file_index']; } // Restore old board if ($board['uri'] != $tmp_board) { openBoard($tmp_board); } foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; // preg_match_all is not multibyte-safe foreach ($matches as &$match) { $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); } if ($cite) { if (isset($cited_posts[$_board][$cite])) { $link = $cited_posts[$_board][$cite]; $replacement = '<a ' . ($_board == $board['uri'] ? 'onclick="highlightReply(\'' . $cite . '\');" ' : '') . 'href="' . $link . '">' . '>>>/' . $_board . '/' . $cite . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($_board, $cite); } } } elseif (isset($crossboard_indexes[$_board])) { $replacement = '<a href="' . $crossboard_indexes[$_board] . '">' . '>>>/' . $_board . '/' . '</a>'; $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); } } } $tracked_cites = array_unique($tracked_cites, SORT_REGULAR); $body = preg_replace("/^\\s*>.*\$/m", '<span class="quote">$0</span>', $body); if ($config['strip_superfluous_returns']) { $body = preg_replace('/\\s+$/', '', $body); } $body = preg_replace("/\n/", '<br/>', $body); // Fix code markup if ($config['markup_code']) { foreach ($code_markup as $id => $val) { $code = isset($val[2]) ? $val[2] : $val[1]; $code_lang = isset($val[2]) ? $val[1] : ""; $code = "<pre class='code lang-{$code_lang}'>" . str_replace(array("\n", "\t"), array(" ", "	"), htmlspecialchars($code)) . "</pre>"; $body = str_replace("<code {$id}>", $code, $body); } } if ($config['markup_repair_tidy']) { $tidy = new tidy(); $body = str_replace("\t", '	', $body); $body = $tidy->repairString($body, array('doctype' => 'omit', 'bare' => true, 'literal-attributes' => true, 'indent' => false, 'show-body-only' => true, 'wrap' => 0, 'output-bom' => false, 'output-html' => true, 'newline' => 'LF', 'quiet' => true), 'utf8'); $body = str_replace("\n", '', $body); } // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); return $tracked_cites; }
function markup(&$body, $track_cites = false) { global $board, $config, $markup_urls; $body = utf8tohtml($body); if ($config['wiki_markup']) { $body = preg_replace("/(^|\n)==(.+?)==\n?/m", "<span class=\"heading\">\$2</span>", $body); $body = preg_replace("/'''(.+?)'''/m", "<strong>\$1</strong>", $body); $body = preg_replace("/''(.+?)''/m", "<em>\$1</em>", $body); $body = preg_replace("/\\*\\*(.+?)\\*\\*/m", "<span class=\"spoiler\">\$1</span>", $body); } if ($config['markup_urls']) { $markup_urls = array(); $body = preg_replace_callback($config['url_regex'], 'markup_url', $body, -1, $num_links); if ($num_links > $config['max_links']) { error($config['error']['toomanylinks']); } } if ($config['auto_unicode']) { $body = unicodify($body); foreach ($markup_urls as &$url) { $body = str_replace(unicodify($url), $url, $body); } } // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); $tracked_cites = array(); // Cites if (isset($board) && preg_match_all('/(^|\\s)>>(\\d+?)([\\s,.)?]|$)/', $body, $cites)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } for ($index = 0; $index < count($cites[0]); $index++) { $cite = $cites[2][$index]; $query = prepare(sprintf("SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); if ($post = $query->fetch()) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread'] ? $post['thread'] : $post['id']) . '.html#' . $cite . '">' . '>>' . $cite . '</a>'; $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[3][$index], $body); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $post['id']); } } } } // Cross-board linking if (preg_match_all('/(^|\\s)>>>\\/(\\w+?)\\/(\\d+)?([\\s,.)?]|$)/', $body, $cites)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycross']); } for ($index = 0; $index < count($cites[0]); $index++) { $_board = $cites[2][$index]; $cite = @$cites[3][$index]; // Temporarily store board information because it will be overwritten $tmp_board = $board['uri']; // Check if the board exists, and load settings if (openBoard($_board)) { if ($cite) { $query = prepare(sprintf("SELECT `thread`,`id` FROM `posts_%s` WHERE `id` = :id LIMIT 1", $board['uri'])); $query->bindValue(':id', $cite); $query->execute() or error(db_error($query)); if ($post = $query->fetch()) { $replacement = '<a onclick="highlightReply(\'' . $cite . '\');" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread'] ? $post['thread'] : $post['id']) . '.html#' . $cite . '">' . '>>>/' . $_board . '/' . $cite . '</a>'; $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[4][$index], $body); if ($track_cites && $config['track_cites']) { $tracked_cites[] = array($board['uri'], $post['id']); } } } else { $replacement = '<a href="' . $config['root'] . $board['dir'] . $config['file_index'] . '">' . '>>>/' . $_board . '/' . '</a>'; $body = str_replace($cites[0][$index], $cites[1][$index] . $replacement . $cites[4][$index], $body); } } // Restore main board settings openBoard($tmp_board); } } $body = str_replace("\r", '', $body); $body = preg_replace("/(^|\n)([\\s]+)?(>)([^\n]+)?(\$|\n)/m", '$1$2<span class="quote">$3$4</span>$5', $body); if ($config['strip_superfluous_returns']) { $body = preg_replace('/\\s+$/', '', $body); } $body = preg_replace("/\n/", '<br/>', $body); return $tracked_cites; }