function diff($from, $to) { $from = mb_convert_encoding($from, 'HTML-ENTITIES', 'UTF-8'); $to = mb_convert_encoding($to, 'HTML-ENTITIES', 'UTF-8'); require_once AppFile::lib('finediff'); $diff = new FineDiff($from, $to, FineDiff::$paragraphGranularity); $html = $diff->renderDiffToHTML(); $html = mb_convert_encoding($html, 'UTF-8', 'HTML-ENTITIES'); $html = html_entity_decode($html); $html = nl2br($html); return $html; }
/** * Gets all versions of a note * * @NoAdminRequired * @NoCSRFRequired * @CORS * * @return array */ public function getAllVersions() { $source = $this->request->getParam("file_name", ""); list($uid, $filename) = Storage::getUidAndFilename($source); $versions = Storage::getVersions($uid, $filename, $source); $versionsResults = array(); if (is_array($versions) && count($versions) > 0) { require_once __DIR__ . '/../3rdparty/finediff/finediff.php'; $users_view = new View('/' . $uid); $currentData = $users_view->file_get_contents('files/' . $filename); // $previousData = $currentData; // $versions = array_reverse( $versions, true ); foreach ($versions as $versionData) { // get timestamp of version $mtime = (int) $versionData["version"]; // get filename of note version $versionFileName = 'files_versions/' . $filename . '.v' . $mtime; // load the data from the file $data = $users_view->file_get_contents($versionFileName); // calculate diff between versions $opcodes = \FineDiff::getDiffOpcodes($currentData, $data); $html = \FineDiff::renderDiffToHTMLFromOpcodes($currentData, $opcodes); $versionsResults[] = array("timestamp" => $mtime, "humanReadableTimestamp" => $versionData["humanReadableTimestamp"], "diffHtml" => $html, "data" => $data); // $previousData = $data; } // $versionsResults = array_reverse( $versionsResults ); } return array("file_name" => $source, "versions" => $versionsResults); }
public static function compareLicense($fromText, $toText) { $from_text = mb_convert_encoding($fromText, 'HTML-ENTITIES', 'UTF-8'); $to_text = mb_convert_encoding($toText, 'HTML-ENTITIES', 'UTF-8'); $granularity = FineDiff::$wordGranularity; $diff_opcodes = FineDiff::getDiffOpcodes($from_text, $to_text, $granularity); self::$diffLength = strlen($diff_opcodes); $rendered_diff = FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes); return $rendered_diff; }
public static function diff($transcripts) { $str = ''; $transcriptA = $transcripts[0]['transcript']; $transcriptB = $transcripts[1]['transcript']; $opcodes = FineDiff::getDiffOpcodes($transcriptA, $transcriptB, FineDiff::$characterGranularity); $str = FineDiff::renderDiffToUnbinderyFromOpcodes($transcriptA, $opcodes); // TODO: UTF-8 encoding // mb_convert_encoding($from_text_utf8, 'HTML-ENTITIES', 'UTF-8'); return $str; }
/** * Smarty string diff plugin * * Type: insert<br> * Name: string_diff<br> * Date: August 26, 2014 * Purpose: Creates an HTML diff of two text strings * Input: two strings * Example: {insert name="string_diff" from_text="foo" to_text="bar"} * @license http://www.gnu.org/licenses/gpl.html * @copyright 2009-2015 Matt Jacobs * @author Matt Jacobs * @version 1.0 */ function smarty_insert_string_diff($params, &$smarty) { if (empty($params['from_text']) && empty($params['to_text'])) { trigger_error("Missing 'from_text' and 'to_text' paramaters"); return; } elseif (empty($params['from_text'])) { return "<ins>" . $params['to_text'] . "</ins>"; } elseif (empty($params['to_text'])) { return "<del>" . $params['from_text'] . "</del>"; } require_once THINKUP_WEBAPP_PATH . '_lib/extlib/FineDiff/finediff.php'; $opcodes = FineDiff::getDiffOpcodes($params['from_text'], $params['to_text'], $granularityStack = FineDiff::$wordGranularity); $diff = FineDiff::renderDiffToHTMLFromOpcodes($params['from_text'], $opcodes); if (isset($params['is_email']) && $params['is_email']) { $diff = str_replace('<ins', '<ins style="background: #e4f9e8; text-decoration: none;"', $diff); $diff = str_replace('<del', '<del style="background: #f8d9dd; color: #dc4154;"', $diff); } return $diff; }
/** * Prints a test result */ function test($file, $minExpected, $skip) { global $cssmin; if (!empty($skip) && in_array(basename($file), $skip)) { p("INFO: CSSmin: skipping " . basename($file), 'info'); return; } $src = file_get_contents($file); $minOutput = $cssmin->run($src); $passed = assertTrue(strcmp($minOutput, $minExpected) === 0, 'CSSmin: ' . basename(dirname($file)) . '/' . basename($file)); if (!$passed) { p("---Output: " . countBytes($minOutput) . " bytes", ''); $opcodes = FineDiff::getDiffOpcodes($minExpected, $minOutput); code(FineDiff::renderDiffToHTMLFromOpcodes($minExpected, $opcodes)); p("---Expected: " . countBytes($minExpected) . " bytes", ''); code($minExpected); p("---Source: " . countBytes($src) . " bytes", ''); code($src); } }
/** * Resolve diffs. * * @param array $current The current content as an array. * @param array[] $revisions An array of revisions of the content. * @param array $diffdFields The fields that are diff'd. * @param bool $merge Merge the current and revision to return 1 entry. (Cite) */ public static function resolve($current, $revisions, $diffdFields, $merge = true) { $return = array(); foreach ($revisions as $revision) { $nCurrent = $merge ? array_merge($current, $revision) : $revision; foreach ($diffdFields as $field) { if ($field[0] == '$') { $s = true; $field = substr($field, 1); $current[$field] = serialize($current[$field]); } $nCurrent[$field] = FineDiff::renderToTextFromOpcodes($current[$field], $nCurrent[$field]); } $current = $nCurrent; if ($s) { $current[$field] = unserialize($current[$field]); } array_push($return, $current); } return $return; }
continue; } if (!isset($both['remote'])) { 'fehlt remote'; continue; } $remote = file_get_contents($both['remote']); $local = file_get_contents($both['local']); if ($remote === $local) { echo '<span style="color:green">ok!</span>'; continue; } else { echo '<span style="color:red">different!</span>'; require_once __DIR__ . '/../lib/finediff.php'; $opcodes = \FineDiff::getDiffOpcodes($remote, $local); // store opcodes for later use... //Later, $to_text can be re-created from $from_text using $opcodes as follow: echo '<pre style="box-shadow:0 0 5px rgba(0,0,0,0.7); padding:10px">'; echo \FineDiff::renderDiffToHTMLFromOpcodes($remote, $opcodes); echo '</pre>'; echo '<style>' . 'del { color: red; background: #fdd; text-decoration: none; }' . 'ins { color: green; background: #dfd; text-decoration: none; }' . '</style>'; } } ?> </div> <?php } ?> </div><?php
public function generateRevision($update, $old) { $titleFD = new FineDiff($update['title'], $old['title']); $descriptionFD = new FineDiff($update['description'], $old['description']); $bodyFD = new FineDiff($update['body'], $old['body']); $tagsFD = new FineDiff(serialize($update['tags']), serialize($old['tags'])); $revision = array('title' => $titleFD->getOpcodes(), 'description' => $descriptionFD->getOpcodes(), 'body' => $bodyFD->getOpcodes(), 'tags' => $tagsFD->getOpcodes(), 'published' => $old['published'], 'commentable' => $old['commentable']); return $revision; }
/** * @param $from_text * @param $to_text * * @param bool $charDiff * * @return array */ function mb_renderDiffHtml($from_text, $to_text, $charDiff = null) { //if ($from_text === 'Lang' && $to_text === 'Language') xdebug_break(); if ($from_text == $to_text) { return $to_text; } $removeSpaces = false; if ($charDiff === null) { $charDiff = mb_strtolower($from_text) === mb_strtolower($to_text) || abs(mb_strlen($from_text) - mb_strlen($to_text)) <= 2 || $from_text && $to_text && (strpos($from_text, $to_text) !== false || $to_text && strpos($to_text, $from_text) !== false); } if ($charDiff) { //use word diff but space all entities so that we get char diff $removeSpaces = true; $from_text = mb_chunk_split($from_text, 1, ' '); $to_text = mb_chunk_split($to_text, 1, ' '); } $from_text = mb_convert_encoding($from_text, 'HTML-ENTITIES', 'UTF-8'); $to_text = mb_convert_encoding($to_text, 'HTML-ENTITIES', 'UTF-8'); $opcodes = \FineDiff::getDiffOpcodes($from_text, $to_text, \FineDiff::$wordGranularity); $diff = \FineDiff::renderDiffToHTMLFromOpcodes($from_text, $opcodes); $diff = mb_convert_encoding($diff, 'UTF-8', 'HTML-ENTITIES'); if ($removeSpaces) { $diff = mb_unsplit($diff, ' '); } return $diff; }
* https://github.com/asleepwalker/typographie */ if (!(isset($_POST['raw']) && isset($_POST['actions']) && isset($_POST['in']) && isset($_POST['out']) && isset($_POST['highlight']))) { echo json_encode(array('error' => '1')); exit; } require_once 'typographie.class.php'; require_once 'converter.class.php'; $engine = new TypographieModes($_POST['actions']); $engine->mode($_POST['in'], $_POST['out']); $result = $engine->process($_POST['raw']); if ($_POST['highlight'] == 'enabled') { require_once 'finediff.class.php'; $opcodes = FineDiff::getDiffOpcodes($_POST['raw'], $result); $result = ''; FineDiff::renderFromOpcodes($_POST['raw'], $opcodes, function ($opcode, $from, $from_offset, $from_len) use(&$result) { if ($opcode === 'c') { $result .= htmlspecialchars(mb_substr($from, $from_offset, $from_len)); } else { if ($opcode === 'i') { $result .= '<span class="fix">' . htmlspecialchars(mb_substr($from, $from_offset, $from_len), ENT_QUOTES) . '</span>'; } } }); } else { $result = htmlspecialchars($result, ENT_QUOTES, 'UTF-8'); } if ($_POST['out'] == 'html') { $result = preg_replace('/(<.+?>)/ui', '<span class="html">$1</span>', $result); } echo json_encode(array('response' => $result));
if ($row['content_flags'] & $content_nsfw) { $nsfw .= '<span class="nsfw">NSFW</span>'; } $subj = print_subject(encode_subject($row['subject'])); if (extension_loaded('mbstring')) { $content_to_compare = $row['compare_to']; if (is_null($content_to_compare)) { $content_to_compare = $row['msg_subject']; } $from_text = $subj; // htmlentities($body, HTML_ENTITIES,'UTF-8'); $to_text = print_subject(encode_subject($content_to_compare)); $from_text = mb_convert_encoding($from_text, 'HTML-ENTITIES', 'UTF-8'); $to_text = mb_convert_encoding($to_text, 'HTML-ENTITIES', 'UTF-8'); $diff_opcodes = FineDiff::getDiffOpcodes($from_text, $to_text); $subj = mb_convert_encoding(FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes), 'UTF-8', 'HTML-ENTITIES'); } $line = $icons . '<a id="' . $msg_id . '_' . $row['id'] . '" name="' . $msg_id . '_' . $row['id'] . '" target="bottom" href="' . $root_dir . $page_version . '?id=' . $msg_id . '&ver=' . $row['id'] . '">' . $subj . '</a> ' . $nsfw . ' ' . ' [' . $row['views'] . ' views] ' . $row['created'] . ' <b>' . $row['chars'] . '</b> bytes'; } if (isset($version) && $version == $row['id']) { print '<font color="green">></font>'; } else { print '<span style="opacity:0;">></span>'; } print '<i><font color="gray">' . $line . '</font></i>'; print '<br/>'; } print "</div>"; } mysql_free_result($result); }
/** * This is the core algorithm which actually perform the diff itself, * fragmenting the strings as per specified delimiters. * * This function is naturally recursive, however for performance purpose * a local job queue is used instead of outright recursivity. */ private static function doFragmentDiff($from_text, $to_text, $delimiters) { // Empty delimiter means character-level diffing. // In such case, use code path optimized for character-level // diffing. if (empty($delimiters)) { return FineDiff::doCharDiff($from_text, $to_text); } $result = array(); // fragment-level diffing $from_text_len = strlen($from_text); $to_text_len = strlen($to_text); $from_fragments = FineDiff::extractFragments($from_text, $delimiters); $to_fragments = FineDiff::extractFragments($to_text, $delimiters); $jobs = array(array(0, $from_text_len, 0, $to_text_len)); $cached_array_keys = array(); while ($job = array_pop($jobs)) { // get the segments which must be diff'ed list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; // catch easy cases first $from_segment_length = $from_segment_end - $from_segment_start; $to_segment_length = $to_segment_end - $to_segment_start; if (!$from_segment_length || !$to_segment_length) { if ($from_segment_length) { $result[$from_segment_start * 4] = new FineDiffDeleteOp($from_segment_length); } else { if ($to_segment_length) { $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_length)); } } continue; } // find longest copy operation for the current segments $best_copy_length = 0; $from_base_fragment_index = $from_segment_start; $cached_array_keys_for_current_segment = array(); while ($from_base_fragment_index < $from_segment_end) { $from_base_fragment = $from_fragments[$from_base_fragment_index]; $from_base_fragment_length = strlen($from_base_fragment); // performance boost: cache array keys if (!isset($cached_array_keys_for_current_segment[$from_base_fragment])) { if (!isset($cached_array_keys[$from_base_fragment])) { $to_all_fragment_indices = $cached_array_keys[$from_base_fragment] = array_keys($to_fragments, $from_base_fragment, true); } else { $to_all_fragment_indices = $cached_array_keys[$from_base_fragment]; } // get only indices which falls within current segment if ($to_segment_start > 0 || $to_segment_end < $to_text_len) { $to_fragment_indices = array(); foreach ($to_all_fragment_indices as $to_fragment_index) { if ($to_fragment_index < $to_segment_start) { continue; } if ($to_fragment_index >= $to_segment_end) { break; } $to_fragment_indices[] = $to_fragment_index; } $cached_array_keys_for_current_segment[$from_base_fragment] = $to_fragment_indices; } else { $to_fragment_indices = $to_all_fragment_indices; } } else { $to_fragment_indices = $cached_array_keys_for_current_segment[$from_base_fragment]; } // iterate through collected indices foreach ($to_fragment_indices as $to_base_fragment_index) { $fragment_index_offset = $from_base_fragment_length; // iterate until no more match for (;;) { $fragment_from_index = $from_base_fragment_index + $fragment_index_offset; if ($fragment_from_index >= $from_segment_end) { break; } $fragment_to_index = $to_base_fragment_index + $fragment_index_offset; if ($fragment_to_index >= $to_segment_end) { break; } if ($from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index]) { break; } $fragment_length = strlen($from_fragments[$fragment_from_index]); $fragment_index_offset += $fragment_length; } if ($fragment_index_offset > $best_copy_length) { $best_copy_length = $fragment_index_offset; $best_from_start = $from_base_fragment_index; $best_to_start = $to_base_fragment_index; } } $from_base_fragment_index += strlen($from_base_fragment); // If match is larger than half segment size, no point trying to find better // TODO: Really? if ($best_copy_length >= $from_segment_length / 2) { break; } // no point to keep looking if what is left is less than // current best match if ($from_base_fragment_index + $best_copy_length >= $from_segment_end) { break; } } if ($best_copy_length) { $jobs[] = array($from_segment_start, $best_from_start, $to_segment_start, $best_to_start); $result[$best_from_start * 4 + 2] = new FineDiffCopyOp($best_copy_length); $jobs[] = array($best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end); } else { $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length)); } } ksort($result, SORT_NUMERIC); return array_values($result); }
$row = mysql_fetch_assoc($result) or die('error to fetch parent row'); $proceeded = false; $parent_author = htmlentities($row['username'], HTML_ENTITIES, 'UTF-8'); $parent_date = $row['created']; if ($row['status'] == 2) { $in_response = 'In response to: <I><font color="gray"><del>This message has been deleted</del></font></I> by <b>' . $parent_author . '</b>' . ', ' . $parent_date . '<br> '; } else { $parent_subject = htmlentities(translit($row['subject'], $proceeded), HTML_ENTITIES, 'UTF-8'); $in_response = 'In response to: <a href="' . $root_dir . $page_msg . '?id=' . $parent . '">' . $parent_subject . '</a> by <b>' . $parent_author . '</b>' . ', ' . $parent_date . '<br> '; } } } } else { die('No such message'); } mysql_free_result($result); notify_about_new_pm($user_id, $last_pm_check_time, "bottom"); $modified = null; $trans_body = $msgbody; if (extension_loaded('mbstring')) { include 'finediff.php'; $from_text = $body; $to_text = $content_to_compare; $diff_opcodes = FineDiff::getDiffOpcodes($from_text, $to_text, FineDiff::$characterGranularity); $trans_body = nl2br(FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes)); } require_once 'msg_form_inc.php'; ?>
public function on_tested($num, $test, $ret) { $cc = urlencode($test['text']); $text = nl2br(htmlspecialchars($test['text'])); $result = htmlspecialchars($test['result']); $out = htmlspecialchars($ret['result']); $diffx = new FineDiff($out, $result, FineDiff::$characterGranularity); $diff = $diffx->renderDiffToHTML2(); //$diffy = new FineDiff($ret['result'], $test['result'], FineDiff::$characterGranularity); //$diff_text = $diffy->renderDiffToHTML2(); $block_html_inline = $this->build_posle_nuzhno_raznica_block($test['result_classes'] ? 1 : 0, $out, $result, $diff); $block_text_inline = $this->build_posle_nuzhno_raznica_block($test['result_classes'] ? 1 : 0, $ret['result'], $test['text']); $block_html_classes = ""; $block_text_classes = ""; if (isset($test['result_classes']) && $test['result_classes']) { $diffc_h = new FineDiff(htmlspecialchars($ret['result_classes']), htmlspecialchars($test['result_classes']), FineDiff::$characterGranularity); $diff_h = $diffc_h->renderDiffToHTML2(); //$diffc_t = new FineDiff($ret['result_classes'], $test['result_classes'], FineDiff::$characterGranularity); //$diff_t = $diffc_t->renderDiffToHTML2(); $block_html_classes = "<br>" . $this->build_posle_nuzhno_raznica_block(2, htmlspecialchars($ret['result_classes']), htmlspecialchars($test['result_classes']), $diff_h); $block_text_classes = "<br>" . $this->build_posle_nuzhno_raznica_block(2, $ret['result_classes'], $test['result_classes']); } // повторное тестирование<br> $second_html = ""; $second_text = ""; if (isset($ret['result_second']) && $ret['result_second']) { $out_second = htmlspecialchars($ret['result_second']); $diffx2 = new FineDiff($out_second, $result, FineDiff::$characterGranularity); $diff_second = $diffx2->renderDiffToHTML2(); $block_second_html_inline = $this->build_posle_nuzhno_raznica_block($test['result_classes'] ? 1 : 0, $out_second, $result, $diff_second); $block_second_text_inline = $this->build_posle_nuzhno_raznica_block($test['result_classes'] ? 1 : 0, $ret['result_second'], $test['text']); $block_second_html_classes = ""; $block_second_text_classes = ""; if (isset($test['result_classes_second']) && $test['result_classes_second']) { $diffc_h2 = new FineDiff(htmlspecialchars($ret['result_classes_second']), htmlspecialchars($test['result_classes']), FineDiff::$characterGranularity); $diff_second_h = $diffc_h2->renderDiffToHTML2(); $block_second_html_classes = "<br>" . $this->build_posle_nuzhno_raznica_block(2, htmlspecialchars($ret['result_classes_second']), htmlspecialchars($test['result_classes']), $diff_second_h); $block_second_text_classes = "<br>" . $this->build_posle_nuzhno_raznica_block(2, $ret['result_classes_second'], $test['result_classes']); } $second_html = <<<HTML \t\t\t<br> \t\t\t<h4>Повторное типографирование</h4> \t\t\t{$block_second_html_inline} \t\t\t{$block_second_html_classes} HTML; $second_text = <<<HTML \t\t\t<br> \t\t\t<h4>Повторное типографирование</h4> \t\t\t{$block_second_text_inline} \t\t\t{$block_second_text_classes} HTML; } $infoblock = <<<HTML \t\t<div id="test{$num}_block" style="display:none;margin: 30px;"> \t\t<div id="test{$num}_block_html" > \t\t\t<a href="#test{$num}" class="togglehtmlcode">Посмотреть текст</a> <a href="debug.php?inputdata={$cc}" target="_blank">Открыть в отладчике</a><br> \t\t\tДО: {$text}<br> \t\t\t<br> \t\t\t{$block_html_inline} \t\t\t{$block_html_classes} \t\t\t{$second_html} \t\t</div> \t\t<div id="test{$num}_block_code" style="display:none;"> \t\t\t<a href="#test{$num}" class="togglehtmlcode">Посмотреть HTML</a> <a href="debug.php?inputdata={$cc}" target="_blank">Открыть в отладчике</a><br> \t\t\tДО: {$text}<br> \t\t\t<br> \t\t\t{$block_text_inline} \t\t\t{$block_text_classes} \t\t\t{$second_text} \t\t</div> \t\t \t\t</div> HTML; $cnt = $this->get_test_count(); // первый тест в группе тестов if ($test['grnum'] == 1) { echo <<<HTML \t</ul> \t<h3 style="margin-left: 20px">{$test['grtitle']}</h3> \t<ul style="list-style: none"> HTML; } echo "\t\t<li id='test{$num}'><span class='openlink " . ($ret['error'] ? "witherror" : "") . "'><a href='#test{$num}' class='seetest'><img style='margin-right: 0.7em' src='../misc/" . ($ret['error'] ? "no" : "yes") . ".png'>Тест {$test['grid']}" . sprintf("%02d", $test['grnum']) . " (" . sprintf("%02d", $num) . "/{$cnt})" . (isset($test['title']) ? ": " . $test['title'] . "" : "") . "</a></span> {$infoblock}</li>\n"; $this->doflush(); }
public static function textDiff($from, $to, $truncate = false) { require_once 'lib/finediff.php'; $diff = new FineDiff($from, $to, FineDiff::$wordGranularity); if (!$truncate) { return $diff->renderDiffToHTML(); } else { $html = $diff->renderDiffToHTML(); // find first change $firstDel = strpos($html, '<del>'); $firstIns = strpos($html, '<ins>'); if ($firstDel === false) { $firstDel = $firstIns; } if ($firstIns === false) { $firstIns = $firstDel; } $first = min($firstDel, $firstIns); $first = max(0, $first - $truncate); // find last change $lastDel = strrpos($html, '</del>'); $lastIns = strrpos($html, '</ins>'); if ($lastDel === false) { $lastDel = $lastIns; } if ($lastIns === false) { $lastIns = $lastDel; } $last = max($lastDel, $lastIns); $last = min(strlen($html), $last + $truncate); // create truncated string return ($first > 0 ? '<span>....</span> ' : '') . substr($html, $first, $last - $first) . ($last < strlen($html) ? ' <span>....</span>' : ''); } }
} $array_diff = $values[$key]['diff'][$granularity]; $diff_text = ''; if ($array_diff[0] != 0) { $diff_text .= '<ins class="elgg-subtext"> +' . $array_diff[0] . ' </ins>'; } if ($array_diff[1] != 0) { $diff_text .= '<del class="elgg-subtext"> -' . $array_diff[1] . ' </del>'; } $annotationSummary[$key] = <<<HTML <div id='owner-{$key}' class='owner'> \t{$summary}<br/> \t<span class="elgg-subtext"> \t\t{$diff_text} {$owner_link} {$time} \t</span> </div> HTML; } $diff = new FineDiff(htmlspecialchars($values[0]['text'], ENT_QUOTES, 'UTF-8', false), htmlspecialchars($values[1]['text'], ENT_QUOTES, 'UTF-8', false), $granularity_fine); $diffOutput = str_replace(' ', ' ', $diff->renderDiffToHTML()); $diffOutput = str_replace(CHR(13), '<br/>', $diffOutput); $diffHTML = "<div id='diff-from' class='diff'>" . $diffOutput . '</div>'; $content = "<div class='diff-output'>" . $diffHTML . '</div>'; $title = elgg_echo('markdown_wiki:compare:result', array($markdown_wiki->title)); $sidebar .= elgg_view('markdown_wiki/sidebar/compare_sidebar', array('from' => $annotationSummary[0], 'to' => $annotationSummary[1])); } else { $content = elgg_view_form('markdown_wiki/compare', array('disable_security' => true, 'action' => "wiki/compare/{$markdown_wiki_guid}/{$markdown_wiki->title}"), array('markdown_wiki' => $markdown_wiki, 'annoff' => $annoff)); $title = elgg_echo('markdown_wiki:compare', array($markdown_wiki->title)); } $body = elgg_view_layout('content', array('filter' => '', 'content' => $content, 'title' => $title, 'sidebar' => $sidebar)); echo elgg_view_page($title, $body);
$num_files -= 1; if ($num_files < $cache_lo_water_mark) { break; } } } } // save diff in cache $data_to_serialize = array('granularity' => $granularity, 'from_text' => $from_text, 'diff_opcodes' => $diff_opcodes, 'data_key' => $data_key); $serialized_data = serialize($data_to_serialize); @file_put_contents("./cache/{$filename}", gzcompress($serialized_data)); @chmod("./cache/{$filename}", 0666); } } } $rendered_diff = FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes); $from_len = strlen($from_text); $to_len = strlen($to_text); ?> <div class="panecontainer" style="width:80%;text-align: left;"> <p>Diff <span style="color:gray"> (diff: <?php printf('%.3f', $exec_time); ?> seconds, diff len: <?php echo $diff_opcodes_len; ?> chars) </span>  / Show
} } } $jsonResponse['success'] = true; $jsonResponse['content'] = $content; } else { $jsonResponse['message'] = 'Vous ne pouvez pas editer tant que vous n\'êtes pas connecté.'; } echo json_encode($jsonResponse); break; case 'save': if ($myUser != false) { $newContent = html_entity_decode($_['content'], ENT_QUOTES, 'UTF-8'); $oldContent = file_exists($pagePath) ? file_get_contents($pagePath) : ''; if ($newContent != $oldContent) { $mod = FineDiff::getDiffOpcodes($newContent, $oldContent); event('UPDATE_FILE', array('page' => $page), $myUser->login); if (!is_dir(ARCHIVES_ROOT)) { mkdir(ARCHIVES_ROOT); } $folders = explode('/', $pagePath); $p = array_pop($folders); $path = MD_ROOT; $archives = ARCHIVES_ROOT; foreach ($folders as $key => $dir) { if ($key == 1) { $path = $dir; } elseif ($key != 0) { $path .= '/' . $dir; $archives .= '/' . $dir; }
/** * Get difference between current and previous version * * @param string $from_text Original text * @param string $to_text Changed text * * @return difference */ function getRevisiondifference($from_text, $to_text) { // limit input $from_text = substr($from_text, 0, 1024 * 100); $to_text = substr($to_text, 0, 1024 * 100); $granularity = 2; // 0: Paragraph/lines, 1: Sentence, 2: Word, 3: Character $granularityStacks = array(FineDiff::$paragraphGranularity, FineDiff::$sentenceGranularity, FineDiff::$wordGranularity, FineDiff::$characterGranularity); $diff_opcodes = FineDiff::getDiffOpcodes($from_text, $to_text, $granularityStacks[$granularity]); $difference = FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes); return $difference; }
function getPaste($seg = 2, $replies = false, $diff = false) { if ($this->uri->segment($seg) == '') { redirect(''); } else { $pid = $this->uri->segment($seg); $data['script'] = 'jquery.js'; } $this->load->library('process'); $this->db->where('pid', $pid); $query = $this->db->get('pastes'); foreach ($query->result_array() as $row) { $data['title'] = $row['title']; $data['pid'] = $row['pid']; $data['name'] = $row['name']; $data['lang_code'] = $row['lang']; $data['lang'] = $this->languages->code_to_description($row['lang']); $data['paste'] = $this->process->syntax(htmlspecialchars_decode($row['raw']), $row['lang']); $data['created'] = $row['created']; $data['private'] = $row['private']; $data['expire'] = $row['expire']; $data['toexpire'] = $row['toexpire']; $data['url'] = $this->_get_url($row['pid']); $data['raw'] = $row['raw']; $data['hits'] = $row['hits']; $data['hits_updated'] = $row['hits_updated']; $data['snipurl'] = $row['snipurl']; $inreply = $row['replyto']; } if ($inreply) { $this->db->select('name, title'); $this->db->where('pid', $inreply); $query = $this->db->get('pastes'); if ($query->num_rows() > 0) { foreach ($query->result_array() as $row) { $data['inreply']['title'] = $row['title']; $data['inreply']['name'] = $row['name']; $data['inreply']['url'] = site_url('view/' . $inreply); } } else { $data['inreply'] = false; } if ($diff) { $this->db->select('raw'); $this->db->where('pid', $inreply); $query = $this->db->get('pastes'); if ($query->num_rows() > 0) { foreach ($query->result_array() as $row) { //diff //yes, I'm aware, two times htmlspecialchars_decode(). Needs to be, since it's saved that way in the DB from the original stikked author ages ago ;) include_once APPPATH . '/libraries/finediff.php'; $from_text = htmlspecialchars_decode(utf8_decode($row['raw'])); $to_text = htmlspecialchars_decode(utf8_decode($data['raw'])); $opcodes = FineDiff::getDiffOpcodes($from_text, $to_text, FineDiff::$wordGranularity); $to_text = FineDiff::renderToTextFromOpcodes($from_text, $opcodes); $data['paste'] = htmlspecialchars_decode($this->_format_diff(nl2br(FineDiff::renderDiffToHTMLFromOpcodes($from_text, $opcodes)))); } } else { $data['inreply'] = false; } } } if ($replies) { $amount = $this->config->item('per_page'); $page = $this->uri->segment(3) ? $this->uri->segment(3) : 0; $this->db->select('title, name, created, pid, lang'); $this->db->where('replyto', $data['pid']); $this->db->order_by('id', 'desc'); $this->db->limit($amount); $query = $this->db->get('pastes', $amount, $page); if ($query->num_rows() > 0) { $n = 0; foreach ($query->result_array() as $row) { $data['replies'][$n]['title'] = $row['title']; $data['replies'][$n]['name'] = $row['name']; $data['replies'][$n]['lang'] = $row['lang']; $data['replies'][$n]['created'] = $row['created']; $data['replies'][$n]['pid'] = $row['pid']; $n++; } $config['base_url'] = site_url('view/' . $data['pid']); $config['total_rows'] = $this->countReplies($data['pid']); $config['per_page'] = $amount; $config['num_links'] = 9; $config['full_tag_open'] = '<div class="pages">'; $config['full_tag_close'] = '</div>'; $config['uri_segment'] = 3; $this->load->library('pagination'); $this->pagination->initialize($config); $data['pages'] = $this->pagination->create_links(); } else { $replies = false; } } /* * Hits * First check if record already exists. If it does, do not insert. * INSERT IGNORE INTO does not work for postgres. */ $this->db->select('count(paste_id) as count'); $this->db->where('paste_id', $pid); $this->db->where('ip_address', $this->input->ip_address()); $query = $this->db->get('trending'); $hits_count = $query->result_array(); $hits_count = $hits_count[0]['count']; if ($hits_count == 0) { $this->db->insert('trending', array('paste_id' => $pid, 'ip_address' => $this->input->ip_address(), 'created' => time())); } //update hits counter every minute if (time() > 60 + $data['hits_updated']) { $this->calculate_hits($pid, $data['hits']); } //burn if necessary if ($data['expire'] == 0 and $data['toexpire'] == 1) { $this->delete_paste($data['pid']); } return $data; }
/** * wrapper for PHP-FineDiff library * * @param string $from_text * @param string $to_text */ function diff($from_text, $to_text) { /** @noinspection PhpUndefinedClassInspection */ $opcodes = FineDiff::getDiffOpcodes($from_text, $to_text); /** @noinspection PhpUndefinedClassInspection */ echo FineDiff::renderDiffToHTMLFromOpcodes($from_text, $opcodes); }
public function yoloDiff($t1, $t2) { include 'includes/framework/frameworkClasses/finediff.php'; $opcodes = FineDiff::getDiffOpcodes($t1, $t2, FineDiff::$wordGranularity); debug(array('HTML' => FineDiff::renderDiffToHTMLFromOpcodes($t1, $opcodes), 'text' => FineDiff::renderToTextFromOpcodes($t1, $opcodes))); return FineDiff::renderDiffToHTMLFromOpcodes($t1, $opcodes); }
public function GET_page_compare($key, $left, $right) { $page = $this->getPage($key); $slug = $page->slug; if (!$slug) { // 존재하지 않는 문서이므로 생성 권장 return redirect("/wiki/{$key}", 302); } if ($slug && $slug != $key) { // 이미 존재하는 문서인데 slug가 아니라 title로 들어왔다면 slug로 바꿔서 redirect 한다. // url 에 title 보다는 slug 를 권장하므로 영구적이동(301) return redirect("/wiki/{$slug}/compare/{$left}/{$right}", 301); } $l_page = WikiHistory::where('wiki_page_id', $page->id)->where('rev', $left)->first(); $r_page = WikiHistory::where('wiki_page_id', $page->id)->where('rev', $right)->first(); if (!$l_page || !$r_page) { // l 과 r 중 하나가 revision 이 없으므로 문서로 이동 return redirect("/wiki/{$slug}", 302); } $this->setMetaTas($page); include "finediff.php"; $l_text = mb_convert_encoding($l_page->content, 'HTML-ENTITIES', 'UTF-8'); $r_text = mb_convert_encoding($r_page->content, 'HTML-ENTITIES', 'UTF-8'); $opcodes = \FineDiff::getDiffOpcodes($l_text, $r_text, [\FineDiff::paragraphDelimiters, \FineDiff::sentenceDelimiters, \FineDiff::wordDelimiters, ';']); $rendered_diff = \FineDiff::renderDiffToHTMLFromOpcodes($l_text, $opcodes); $rendered_diff = mb_convert_encoding($rendered_diff, 'UTF-8', 'HTML-ENTITIES'); $rendered_diff = str_replace('\\r\\n', '\\n', $rendered_diff); $rendered_diff = str_replace('\\r', '\\n', $rendered_diff); $rendered_diff = str_replace('\\n', ' <br/>', $rendered_diff); return view('ncells::wiki.pages.wiki_compare', ['page' => $page, 'rendered_diff' => $rendered_diff]); }
/** * Get difference between current and previous version * * @param string $from_text Original text * @param string $to_text Changed text * * @return difference */ function getRevisiondifference($from_text, $to_text) { // limit input $from_text = substr($from_text, 0, 1024 * 100); $to_text = substr($to_text, 0, 1024 * 100); // ensure input is suitable for diff $from_text = mb_convert_encoding($from_text, 'HTML-ENTITIES', 'UTF-8'); $to_text = mb_convert_encoding($to_text, 'HTML-ENTITIES', 'UTF-8'); $granularity = 2; // 0: Paragraph/lines, 1: Sentence, 2: Word, 3: Character $granularityStacks = array(FineDiff::$paragraphGranularity, FineDiff::$sentenceGranularity, FineDiff::$wordGranularity, FineDiff::$characterGranularity); $diff_opcodes = FineDiff::getDiffOpcodes($from_text, $to_text, $granularityStacks[$granularity]); $difference = FineDiff::renderDiffToHTMLFromOpcodes($from_text, $diff_opcodes); return $difference; }
} } } } } $rendered_diff = ob_get_clean(); $rendering_time = sprintf('%.3f sec', gettimeofday(true) - $start_time); } else { $edits = false; $exec_time = '?'; $rendering_time = '?'; $rendered_diff = '<span style="color:gray">Character-level granularity not allowed when using <code>Text_Diff</code>, due to performance issues.</span>'; } } else { $granularityStacks = array(FineDiff::$paragraphGranularity, FineDiff::$sentenceGranularity, FineDiff::$wordGranularity, FineDiff::$characterGranularity); $diff = new FineDiff($from, $to, $granularityStacks[$granularity]); $edits = $diff->getOps(); $exec_time = sprintf('%.3f sec', gettimeofday(true) - $start_time); $rendered_diff = $diff->renderDiffToHTML(); $rendering_time = sprintf('%.3f sec', gettimeofday(true) - $start_time); } if ($edits !== false) { $opcodes = array(); $opcodes_len = 0; foreach ($edits as $edit) { $opcode = $edit->getOpcode(); $opcodes_len += strlen($opcode); $opcode = htmlentities($opcode); if ($edit instanceof FineDiffCopyOp) { $opcodes[] = "{$opcode}"; } else {
} $ttf_title = $ttf_label; // let's output a page to the user require_once "include_header.php"; // start counting revisions $revnum = 0; // grab the revisions $sql = "SELECT ttf_revision.*, ttf_user.username " . "FROM ttf_revision, ttf_user " . "WHERE ttf_revision.author_id = ttf_user.user_id " . " && type='{$type}' && ref_id='{$ref_id}' " . "ORDER BY date ASC"; if (!($result = mysql_query($sql))) { showerror(); } while ($rev = mysql_fetch_array($result)) { $date = formatdate($rev["date"]); if (isset($lastrev)) { $opcodes = FineDiff::getDiffOpcodes(output($lastrev), output($rev["body"]), FineDiff::$wordGranularity); $revbody = FineDiff::renderDiffToHTMLFromOpcodes(output($lastrev), $opcodes); $lastrev = $rev["body"]; } else { $revbody = $rev["body"]; $lastrev = $rev["body"]; } echo " <div class=\"contenttitle_sm\">\n"; echo " rev {$revnum}, rev_id {$rev["rev_id"]} by\n"; echo " <a class=\"link\" href=\"profile.php?user_id={$rev["author_id"]}\">" . output($rev["username"]) . "</a>"; if (!empty($rev["ip"])) { echo " ({$rev["ip"]})\n"; } echo " <span title=\"{$date[1]}\">{$date[0]}</span>\n"; echo " </div>\n"; echo " <div class=\"contentbox_sm\">\n"; echo nl2br($revbody) . "\n";
function formatEventDetails($event) { $details = ''; switch ($event->getEventTypeID()) { case 'edit_update_uploads': case 'edit_task_uploads': $addedIDs = explode(',', $event->getData2()); $added = ''; foreach ($addedIDs as $a) { if ($a == '') { continue; } // skip blanks $upload = Upload::load($a); $added .= $upload->getOriginalName() . ' (' . formatFileSize($upload->getSize()) . ')<br /><br />'; } if (!empty($added)) { $details .= '<ins>' . $added . '</ins>'; } $deletedIDs = explode(',', $event->getData1()); $deleted = ''; foreach ($deletedIDs as $d) { if ($d == '') { continue; } // skip blanks $upload = Upload::load($d); $deleted .= $upload->getOriginalName() . ' (' . formatFileSize($upload->getSize()) . ')<br /><br />'; } if (!empty($deleted)) { $details .= '<del>' . $deleted . '</del>'; } break; case 'edit_pitch': case 'edit_specs': case 'edit_rules': case 'edit_task_description': case 'edit_update_message': $from = $event->getData1(); $to = $event->getData2(); $from = str_replace(' ', '<br />', $from); $to = str_replace(' ', '<br />', $to); $diff = new FineDiff($from, $to); $htmlDiff = $diff->renderDiffToHTML(); $htmlDiff = html_entity_decode($htmlDiff, ENT_QUOTES, 'UTF-8'); $htmlDiff = html_entity_decode($htmlDiff, ENT_QUOTES, 'UTF-8'); $details .= $htmlDiff; break; case 'edit_task_title': case 'edit_update_title': $from = $event->getData1(); $to = $event->getData2(); $diff = new FineDiff($from, $to); $htmlDiff = $diff->renderDiffToHTML(); $htmlDiff = html_entity_decode($htmlDiff, ENT_QUOTES, 'UTF-8'); $htmlDiff = html_entity_decode($htmlDiff, ENT_QUOTES, 'UTF-8'); $details .= $htmlDiff; break; case 'edit_task_leader': $details .= 'Old Leader: <del>' . formatUserLink($event->getUser1ID(), $event->getProjectID()) . '</del><br /><br />'; $details .= 'New Leader: <ins>' . formatUserLink($event->getUser2ID(), $event->getProjectID()) . '</ins>'; break; case 'edit_task_num_needed': $old = $event->getData1() != null ? $event->getData1() : '∞'; $new = $event->getData2() != null ? $event->getData2() : '∞'; $details .= 'Old: <del>' . $old . '</del> people needed<br /><br />'; $details .= 'New: <ins>' . $new . '</ins> people needed'; break; case 'edit_task_deadline': case 'edit_project_deadline': $old = $event->getData1() != null ? formatTimeTag($event->getData1()) : '(none)'; $new = $event->getData2() != null ? formatTimeTag($event->getData2()) : '(none)'; $details .= 'Old Deadline: <del>' . $old . '</del><br /><br />'; $details .= 'New Deadline: <ins>' . $new . '</ins>'; break; case 'edit_project_status': $old = formatProjectStatus($event->getData1()); $new = formatProjectStatus($event->getData2()); $details .= 'Old Project Status: <del>' . $old . '</del><br /><br />'; $details .= 'New Project Status: <ins>' . $new . '</ins>'; break; case 'edit_accepted_status': $old = formatAcceptedStatus($event->getData1()); $new = formatAcceptedStatus($event->getData2()); $details .= 'Old Status: <del>' . $old . '</del><br /><br />'; $details .= 'New Status: <ins>' . $new . '</ins>'; break; case 'create_task_comment': case 'create_task_comment_reply': case 'create_update_comment': case 'create_update_comment_reply': $details .= formatComment($event->getData1()); break; case 'create_discussion': $details .= '<strong>' . $event->getData1() . '</strong><br /><br />'; $details .= formatDiscussionReply($event->getData2()); break; case 'create_discussion_reply': $details .= formatDiscussionReply($event->getData1()); break; case 'create_update': if ($event->getData1() != '') { $details .= '<strong>' . $event->getData1() . '</strong><br /><br />'; } if ($event->getData2() != '') { $details .= formatUpdate($event->getData2()); } break; case 'create_task': if ($event->getData1() != '') { $details .= '<strong>' . $event->getData1() . '</strong><br /><br />'; } if ($event->getData2() != '') { $details .= formatTaskDescription($event->getData2()); } break; } return $details; }
unset($input['guid']); // don't want to override guid cause if it's new page if (sizeof($input) > 0) { foreach ($input as $name => $value) { $markdown_wiki->{$name} = $value; } } if ($markdown_wiki->save()) { elgg_clear_sticky_form('markdown_wiki'); elgg_load_library('markdown_wiki:fineDiff'); // set diff $compare = new FineDiff($old_description, $markdown_wiki->description, array(FineDiff::wordDelimiters)); $compared['word'] = calc_diff_markdown_wiki($compare->renderDiffToHTML()); $compare = new FineDiff($old_description, $markdown_wiki->description, array(FineDiff::sentenceDelimiters)); $compared['sentence'] = calc_diff_markdown_wiki($compare->renderDiffToHTML()); $compare = new FineDiff($old_description, $markdown_wiki->description, array(FineDiff::paragraphDelimiters)); $compared['paragraph'] = calc_diff_markdown_wiki($compare->renderDiffToHTML()); $array_change = array('text' => $markdown_wiki->description, 'diff' => $compared, 'summary' => get_input('summary')); // Now save description as an annotation $annotation_id = create_annotation($markdown_wiki->guid, 'markdown_wiki', serialize($array_change), '', 0, $markdown_wiki->access_id); system_message(elgg_echo('markdown_wiki:saved')); if ($new_markdown_wiki) { add_to_river('river/object/markdown_wiki/create', 'create', $user_guid, $markdown_wiki->guid); } else { if (!get_input('minorchange', false)) { add_to_river('river/object/markdown_wiki/update', 'update', $user_guid, $markdown_wiki->guid, '', 0, $annotation_id); } } forward($markdown_wiki->getURL()); } else { register_error(elgg_echo('markdown_wiki:error:no_save'));
$from_text = ''; $to_text = ''; if (!empty($_REQUEST['from']) || !empty($_REQUEST['to'])) { if (!empty($_REQUEST['from'])) { $from_text = $_REQUEST['from']; } if (!empty($_REQUEST['to'])) { $to_text = $_REQUEST['to']; } } $diff = ''; $granularityStacks = array(FineDiff::$paragraphGranularity, FineDiff::$sentenceGranularity, FineDiff::$wordGranularity, FineDiff::$characterGranularity); $from_len = strlen($from_text); $to_len = strlen($to_text); $start_time = gettimeofday(true); $diff = new FineDiff($from_text, $to_text, $granularityStacks[$granularity]); $edits = $diff->getOps(); $exec_time = gettimeofday(true) - $start_time; $rendered_diff = $diff->renderDiffToHTML(); $rendering_time = gettimeofday(true) - $start_time; $diff_len = strlen($diff->getOpcodes()); ?> <form action="viewdiff.php" method="post"> <div class="panecontainer" style="display:inline-block;width:49.5%"><p>From</p><div><textarea name="from" class="pane"><?php echo htmlentities($from_text); ?> </textarea></div></div> <div class="panecontainer" style="display:inline-block;width:49.5%"><p>To</p><div><textarea name="to" class="pane"><?php echo htmlentities($to_text); ?> </textarea></div></div>