Deploying to gh-pages from @ Wilfred/difftastic@d615490493 🚀
@ -0,0 +1 @@
|
||||
This file makes sure that Github Pages doesn't process mdBook's output.
|
||||
@ -0,0 +1,217 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Page not found - Difftastic Manual</title>
|
||||
<base href="/">
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="document-not-found-404"><a class="header" href="#document-not-found-404">Document not found (404)</a></h1>
|
||||
<p>This URL is invalid, sorry. Please use the navigation bar or search to continue.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 434 KiB |
@ -0,0 +1,319 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Adding A Parser - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html" class="active"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="adding-a-parser"><a class="header" href="#adding-a-parser">Adding A Parser</a></h1>
|
||||
<h2 id="finding-a-parser"><a class="header" href="#finding-a-parser">Finding a parser</a></h2>
|
||||
<p>New parsers for difftastic must be reasonably complete and maintained.</p>
|
||||
<p>There are many tree-sitter parsers available, and the tree-sitter
|
||||
website includes <a href="https://tree-sitter.github.io/tree-sitter/#available-parsers">a list of some well-known
|
||||
parsers</a>.</p>
|
||||
<h2 id="add-the-source-code"><a class="header" href="#add-the-source-code">Add the source code</a></h2>
|
||||
<p>Ideally, the parser should be available as a Rust crate on crates.io.
|
||||
If that's the case, add it to <code>Cargo.toml</code> in the alphabetically sorted list
|
||||
of parser dependencies. For instance:</p>
|
||||
<pre><code>tree-sitter-json = "0.24.8"
|
||||
</code></pre>
|
||||
<p>Otherwise, it is possible to <a href="./parser_vendoring.html">vendor the parser in difftastic's source code</a>,
|
||||
but this should only be used as a last resort.</p>
|
||||
<h2 id="configure-parsing"><a class="header" href="#configure-parsing">Configure parsing</a></h2>
|
||||
<p>Add an entry to <code>tree_sitter_parser.rs</code> for your language.</p>
|
||||
<pre><pre class="playground"><code class="language-rust"><span class="boring">#![allow(unused)]
|
||||
</span><span class="boring">fn main() {
|
||||
</span>Json => {
|
||||
let language_fn = tree_sitter_json::LANGUAGE;
|
||||
let language = tree_sitter::Language::new(language_fn);
|
||||
|
||||
TreeSitterConfig {
|
||||
language,
|
||||
atom_nodes: vec!["string"].into_iter().collect(),
|
||||
delimiter_tokens: vec![("{", "}"), ("[", "]")],
|
||||
highlight_query: ts::Query::new(language, tree_sitter_json::HIGHLIGHTS_QUERY)
|
||||
.unwrap(),
|
||||
sub_languages: vec![],
|
||||
}
|
||||
}
|
||||
<span class="boring">}</span></code></pre></pre>
|
||||
<p>If the Rust crate does not include a <code>HIGHLIGHTS_QUERY</code>, then you need to include
|
||||
it from a file instead, with</p>
|
||||
<pre><code>include_str!("../../vendored_parsers/highlights/json.scm")
|
||||
</code></pre>
|
||||
<p>Many parser repositories include a highlights query in the repository without
|
||||
exposing it in the Rust crate. In that case you can include it as
|
||||
<code>vendored_parsers/highlights/json.scm</code> in the repository.</p>
|
||||
<p><code>atom_nodes</code> is a list of tree-sitter node names that should be
|
||||
treated as atoms even though the nodes have children. This is common
|
||||
for things like string literals or interpolated strings, where the
|
||||
node might have children for the opening and closing quote.</p>
|
||||
<p>If you don't set <code>atom_nodes</code>, you may notice added/removed content
|
||||
shown in white. This is usually a sign that child node should have its
|
||||
parent treated as an atom.</p>
|
||||
<p><code>delimiter_tokens</code> are delimiters that difftastic stores on
|
||||
the enclosing list node. This allows difftastic to distinguish
|
||||
delimiter tokens from other punctuation in the language.</p>
|
||||
<p>If you don't set <code>delimiter_tokens</code>, difftastic will consider the
|
||||
tokens in isolation, and may think that a <code>(</code> was added but the <code>)</code>
|
||||
was unchanged.</p>
|
||||
<p>You can use <code>difft --dump-ts foo.json</code> to see the results of the
|
||||
tree-sitter parser, and <code>difft --dump-syntax foo.json</code> to confirm that
|
||||
you've set atoms and delimiters correctly.</p>
|
||||
<p><code>sub-languages</code> is empty for most languages: see the code documentation for details.</p>
|
||||
<h2 id="configure-language-detection"><a class="header" href="#configure-language-detection">Configure language detection</a></h2>
|
||||
<p>Update <code>language_name</code> in <code>guess_language.rs</code> to detect your new
|
||||
language. Insert a match arm like:</p>
|
||||
<pre><code>Json => "json",
|
||||
</code></pre>
|
||||
<p>There may also file names or shebangs associated with your language; configure those
|
||||
by adapting the <code>language_globs</code>, <code>from_emacs_mode_header</code> and <code>from_shebang</code> functions
|
||||
in that file.
|
||||
<a href="https://github.com/github/linguist/blob/master/lib/linguist/languages.yml">GitHub's linguist definitions</a>
|
||||
are a useful source of common file extensions.</p>
|
||||
<h2 id="syntax-highlighting-optional"><a class="header" href="#syntax-highlighting-optional">Syntax highlighting (Optional)</a></h2>
|
||||
<p>To add syntax highlighting for your language, you'll also need a symlink
|
||||
to the <code>queries/highlights.scm</code> file, if available.</p>
|
||||
<pre><code>$ cd vendored_parsers/highlights
|
||||
$ ln -s ../tree-sitter-json/queries/highlights.scm json.scm
|
||||
</code></pre>
|
||||
<h2 id="test-it"><a class="header" href="#test-it">Test It</a></h2>
|
||||
<p>Search GitHub for a popular repository in your target language
|
||||
(<a href="https://github.com/search?l=&o=desc&q=stars%3A%3E100+language%3AJSON&s=stars&type=repositories">example
|
||||
search</a>)
|
||||
and confirm that git history looks sensible with difftastic.</p>
|
||||
<h2 id="add-a-regression-test"><a class="header" href="#add-a-regression-test">Add a regression test</a></h2>
|
||||
<p>Finally, add a regression test for your language. This ensures that
|
||||
the output for your test file doesn't change unexpectedly.</p>
|
||||
<p>Regression test files live in <code>sample_files/</code> and have the form
|
||||
<code>foo_1.abc</code> and <code>foo_2.abc</code>.</p>
|
||||
<pre><code>$ nano simple_1.json
|
||||
$ nano simple_2.json
|
||||
</code></pre>
|
||||
<p>Run the regression test script and update the <code>.expected</code> file.</p>
|
||||
<pre><code>$ ./sample_files/compare_all.sh
|
||||
$ cp sample_files/compare.result sample_files/compare.expected
|
||||
</code></pre>
|
||||
<h2 id="maintenance"><a class="header" href="#maintenance">Maintenance</a></h2>
|
||||
<p>To update a parser that is already imported, use <code>git subtree pull</code>.</p>
|
||||
<pre><code>$ git subtree pull --prefix=vendored_parsers/tree-sitter-json git@github.com:tree-sitter/tree-sitter-json.git master
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="contributing.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="parser_vendoring.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="contributing.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="parser_vendoring.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,230 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Alternative Projects - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html" class="active"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="alternative-projects"><a class="header" href="#alternative-projects">Alternative Projects</a></h1>
|
||||
<p>Many different tools exist for diffing files. This section of the
|
||||
manual discusses the design of other tools that have influenced
|
||||
difftastic.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="glossary.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="tree_diffing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="glossary.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="tree_diffing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Based off of the Ayu theme
|
||||
Original by Dempfi (https://github.com/dempfi/ayu)
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #191f26;
|
||||
color: #e6e1cf;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6773;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-attr,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ff7733;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #ffee99;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-bullet {
|
||||
color: #b8cc52;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-built_in,
|
||||
.hljs-section {
|
||||
color: #ffb454;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-symbol {
|
||||
color: #ff7733;
|
||||
}
|
||||
|
||||
.hljs-name {
|
||||
color: #36a3d9;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #00568d;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #91b362;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #d96c75;
|
||||
}
|
||||
@ -0,0 +1,697 @@
|
||||
"use strict";
|
||||
|
||||
// Fix back button cache problem
|
||||
window.onunload = function () { };
|
||||
|
||||
// Global variable, shared between modules
|
||||
function playground_text(playground, hidden = true) {
|
||||
let code_block = playground.querySelector("code");
|
||||
|
||||
if (window.ace && code_block.classList.contains("editable")) {
|
||||
let editor = window.ace.edit(code_block);
|
||||
return editor.getValue();
|
||||
} else if (hidden) {
|
||||
return code_block.textContent;
|
||||
} else {
|
||||
return code_block.innerText;
|
||||
}
|
||||
}
|
||||
|
||||
(function codeSnippets() {
|
||||
function fetch_with_timeout(url, options, timeout = 6000) {
|
||||
return Promise.race([
|
||||
fetch(url, options),
|
||||
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
|
||||
]);
|
||||
}
|
||||
|
||||
var playgrounds = Array.from(document.querySelectorAll(".playground"));
|
||||
if (playgrounds.length > 0) {
|
||||
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
|
||||
headers: {
|
||||
'Content-Type': "application/json",
|
||||
},
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
// get list of crates available in the rust playground
|
||||
let playground_crates = response.crates.map(item => item["id"]);
|
||||
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
|
||||
});
|
||||
}
|
||||
|
||||
function handle_crate_list_update(playground_block, playground_crates) {
|
||||
// update the play buttons after receiving the response
|
||||
update_play_button(playground_block, playground_crates);
|
||||
|
||||
// and install on change listener to dynamically update ACE editors
|
||||
if (window.ace) {
|
||||
let code_block = playground_block.querySelector("code");
|
||||
if (code_block.classList.contains("editable")) {
|
||||
let editor = window.ace.edit(code_block);
|
||||
editor.addEventListener("change", function (e) {
|
||||
update_play_button(playground_block, playground_crates);
|
||||
});
|
||||
// add Ctrl-Enter command to execute rust code
|
||||
editor.commands.addCommand({
|
||||
name: "run",
|
||||
bindKey: {
|
||||
win: "Ctrl-Enter",
|
||||
mac: "Ctrl-Enter"
|
||||
},
|
||||
exec: _editor => run_rust_code(playground_block)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updates the visibility of play button based on `no_run` class and
|
||||
// used crates vs ones available on https://play.rust-lang.org
|
||||
function update_play_button(pre_block, playground_crates) {
|
||||
var play_button = pre_block.querySelector(".play-button");
|
||||
|
||||
// skip if code is `no_run`
|
||||
if (pre_block.querySelector('code').classList.contains("no_run")) {
|
||||
play_button.classList.add("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
// get list of `extern crate`'s from snippet
|
||||
var txt = playground_text(pre_block);
|
||||
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
|
||||
var snippet_crates = [];
|
||||
var item;
|
||||
while (item = re.exec(txt)) {
|
||||
snippet_crates.push(item[1]);
|
||||
}
|
||||
|
||||
// check if all used crates are available on play.rust-lang.org
|
||||
var all_available = snippet_crates.every(function (elem) {
|
||||
return playground_crates.indexOf(elem) > -1;
|
||||
});
|
||||
|
||||
if (all_available) {
|
||||
play_button.classList.remove("hidden");
|
||||
} else {
|
||||
play_button.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function run_rust_code(code_block) {
|
||||
var result_block = code_block.querySelector(".result");
|
||||
if (!result_block) {
|
||||
result_block = document.createElement('code');
|
||||
result_block.className = 'result hljs language-bash';
|
||||
|
||||
code_block.append(result_block);
|
||||
}
|
||||
|
||||
let text = playground_text(code_block);
|
||||
let classes = code_block.querySelector('code').classList;
|
||||
let edition = "2015";
|
||||
if(classes.contains("edition2018")) {
|
||||
edition = "2018";
|
||||
} else if(classes.contains("edition2021")) {
|
||||
edition = "2021";
|
||||
}
|
||||
var params = {
|
||||
version: "stable",
|
||||
optimize: "0",
|
||||
code: text,
|
||||
edition: edition
|
||||
};
|
||||
|
||||
if (text.indexOf("#![feature") !== -1) {
|
||||
params.version = "nightly";
|
||||
}
|
||||
|
||||
result_block.innerText = "Running...";
|
||||
|
||||
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
|
||||
headers: {
|
||||
'Content-Type': "application/json",
|
||||
},
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
body: JSON.stringify(params)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.result.trim() === '') {
|
||||
result_block.innerText = "No output";
|
||||
result_block.classList.add("result-no-output");
|
||||
} else {
|
||||
result_block.innerText = response.result;
|
||||
result_block.classList.remove("result-no-output");
|
||||
}
|
||||
})
|
||||
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
|
||||
}
|
||||
|
||||
// Syntax highlighting Configuration
|
||||
hljs.configure({
|
||||
tabReplace: ' ', // 4 spaces
|
||||
languages: [], // Languages used for auto-detection
|
||||
});
|
||||
|
||||
let code_nodes = Array
|
||||
.from(document.querySelectorAll('code'))
|
||||
// Don't highlight `inline code` blocks in headers.
|
||||
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
|
||||
|
||||
if (window.ace) {
|
||||
// language-rust class needs to be removed for editable
|
||||
// blocks or highlightjs will capture events
|
||||
code_nodes
|
||||
.filter(function (node) {return node.classList.contains("editable"); })
|
||||
.forEach(function (block) { block.classList.remove('language-rust'); });
|
||||
|
||||
code_nodes
|
||||
.filter(function (node) {return !node.classList.contains("editable"); })
|
||||
.forEach(function (block) { hljs.highlightBlock(block); });
|
||||
} else {
|
||||
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
|
||||
}
|
||||
|
||||
// Adding the hljs class gives code blocks the color css
|
||||
// even if highlighting doesn't apply
|
||||
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
|
||||
|
||||
Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) {
|
||||
|
||||
var lines = Array.from(block.querySelectorAll('.boring'));
|
||||
// If no lines were hidden, return
|
||||
if (!lines.length) { return; }
|
||||
block.classList.add("hide-boring");
|
||||
|
||||
var buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
|
||||
|
||||
// add expand button
|
||||
var pre_block = block.parentNode;
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
|
||||
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
|
||||
if (e.target.classList.contains('fa-eye')) {
|
||||
e.target.classList.remove('fa-eye');
|
||||
e.target.classList.add('fa-eye-slash');
|
||||
e.target.title = 'Hide lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.remove('hide-boring');
|
||||
} else if (e.target.classList.contains('fa-eye-slash')) {
|
||||
e.target.classList.remove('fa-eye-slash');
|
||||
e.target.classList.add('fa-eye');
|
||||
e.target.title = 'Show hidden lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.add('hide-boring');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (window.playground_copyable) {
|
||||
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
|
||||
var pre_block = block.parentNode;
|
||||
if (!pre_block.classList.contains('playground')) {
|
||||
var buttons = pre_block.querySelector(".buttons");
|
||||
if (!buttons) {
|
||||
buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
}
|
||||
|
||||
var clipButton = document.createElement('button');
|
||||
clipButton.className = 'fa fa-copy clip-button';
|
||||
clipButton.title = 'Copy to clipboard';
|
||||
clipButton.setAttribute('aria-label', clipButton.title);
|
||||
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
|
||||
|
||||
buttons.insertBefore(clipButton, buttons.firstChild);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process playground code blocks
|
||||
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
|
||||
// Add play button
|
||||
var buttons = pre_block.querySelector(".buttons");
|
||||
if (!buttons) {
|
||||
buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
}
|
||||
|
||||
var runCodeButton = document.createElement('button');
|
||||
runCodeButton.className = 'fa fa-play play-button';
|
||||
runCodeButton.hidden = true;
|
||||
runCodeButton.title = 'Run this code';
|
||||
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||
|
||||
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||
runCodeButton.addEventListener('click', function (e) {
|
||||
run_rust_code(pre_block);
|
||||
});
|
||||
|
||||
if (window.playground_copyable) {
|
||||
var copyCodeClipboardButton = document.createElement('button');
|
||||
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
|
||||
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||
copyCodeClipboardButton.title = 'Copy to clipboard';
|
||||
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
|
||||
|
||||
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
|
||||
}
|
||||
|
||||
let code_block = pre_block.querySelector("code");
|
||||
if (window.ace && code_block.classList.contains("editable")) {
|
||||
var undoChangesButton = document.createElement('button');
|
||||
undoChangesButton.className = 'fa fa-history reset-button';
|
||||
undoChangesButton.title = 'Undo changes';
|
||||
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||
|
||||
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||
|
||||
undoChangesButton.addEventListener('click', function () {
|
||||
let editor = window.ace.edit(code_block);
|
||||
editor.setValue(editor.originalCode);
|
||||
editor.clearSelection();
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function themes() {
|
||||
var html = document.querySelector('html');
|
||||
var themeToggleButton = document.getElementById('theme-toggle');
|
||||
var themePopup = document.getElementById('theme-list');
|
||||
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||
var stylesheets = {
|
||||
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||||
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
|
||||
highlight: document.querySelector("[href$='highlight.css']"),
|
||||
};
|
||||
|
||||
function showThemes() {
|
||||
themePopup.style.display = 'block';
|
||||
themeToggleButton.setAttribute('aria-expanded', true);
|
||||
themePopup.querySelector("button#" + get_theme()).focus();
|
||||
}
|
||||
|
||||
function updateThemeSelected() {
|
||||
themePopup.querySelectorAll('.theme-selected').forEach(function (el) {
|
||||
el.classList.remove('theme-selected');
|
||||
});
|
||||
themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected');
|
||||
}
|
||||
|
||||
function hideThemes() {
|
||||
themePopup.style.display = 'none';
|
||||
themeToggleButton.setAttribute('aria-expanded', false);
|
||||
themeToggleButton.focus();
|
||||
}
|
||||
|
||||
function get_theme() {
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
||||
if (theme === null || theme === undefined) {
|
||||
return default_theme;
|
||||
} else {
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
|
||||
function set_theme(theme, store = true) {
|
||||
let ace_theme;
|
||||
|
||||
if (theme == 'coal' || theme == 'navy') {
|
||||
stylesheets.ayuHighlight.disabled = true;
|
||||
stylesheets.tomorrowNight.disabled = false;
|
||||
stylesheets.highlight.disabled = true;
|
||||
|
||||
ace_theme = "ace/theme/tomorrow_night";
|
||||
} else if (theme == 'ayu') {
|
||||
stylesheets.ayuHighlight.disabled = false;
|
||||
stylesheets.tomorrowNight.disabled = true;
|
||||
stylesheets.highlight.disabled = true;
|
||||
ace_theme = "ace/theme/tomorrow_night";
|
||||
} else {
|
||||
stylesheets.ayuHighlight.disabled = true;
|
||||
stylesheets.tomorrowNight.disabled = true;
|
||||
stylesheets.highlight.disabled = false;
|
||||
ace_theme = "ace/theme/dawn";
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
|
||||
}, 1);
|
||||
|
||||
if (window.ace && window.editors) {
|
||||
window.editors.forEach(function (editor) {
|
||||
editor.setTheme(ace_theme);
|
||||
});
|
||||
}
|
||||
|
||||
var previousTheme = get_theme();
|
||||
|
||||
if (store) {
|
||||
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
|
||||
}
|
||||
|
||||
html.classList.remove(previousTheme);
|
||||
html.classList.add(theme);
|
||||
updateThemeSelected();
|
||||
}
|
||||
|
||||
// Set theme
|
||||
var theme = get_theme();
|
||||
|
||||
set_theme(theme, false);
|
||||
|
||||
themeToggleButton.addEventListener('click', function () {
|
||||
if (themePopup.style.display === 'block') {
|
||||
hideThemes();
|
||||
} else {
|
||||
showThemes();
|
||||
}
|
||||
});
|
||||
|
||||
themePopup.addEventListener('click', function (e) {
|
||||
var theme;
|
||||
if (e.target.className === "theme") {
|
||||
theme = e.target.id;
|
||||
} else if (e.target.parentElement.className === "theme") {
|
||||
theme = e.target.parentElement.id;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
set_theme(theme);
|
||||
});
|
||||
|
||||
themePopup.addEventListener('focusout', function(e) {
|
||||
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||||
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
|
||||
hideThemes();
|
||||
}
|
||||
});
|
||||
|
||||
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
|
||||
document.addEventListener('click', function(e) {
|
||||
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
|
||||
hideThemes();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||
if (!themePopup.contains(e.target)) { return; }
|
||||
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
e.preventDefault();
|
||||
hideThemes();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
var li = document.activeElement.parentElement;
|
||||
if (li && li.previousElementSibling) {
|
||||
li.previousElementSibling.querySelector('button').focus();
|
||||
}
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
var li = document.activeElement.parentElement;
|
||||
if (li && li.nextElementSibling) {
|
||||
li.nextElementSibling.querySelector('button').focus();
|
||||
}
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
themePopup.querySelector('li:first-child button').focus();
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
themePopup.querySelector('li:last-child button').focus();
|
||||
break;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function sidebar() {
|
||||
var body = document.querySelector("body");
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
||||
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
||||
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
|
||||
var firstContact = null;
|
||||
|
||||
function showSidebar() {
|
||||
body.classList.remove('sidebar-hidden')
|
||||
body.classList.add('sidebar-visible');
|
||||
Array.from(sidebarLinks).forEach(function (link) {
|
||||
link.setAttribute('tabIndex', 0);
|
||||
});
|
||||
sidebarToggleButton.setAttribute('aria-expanded', true);
|
||||
sidebar.setAttribute('aria-hidden', false);
|
||||
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
|
||||
}
|
||||
|
||||
|
||||
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
|
||||
|
||||
function toggleSection(ev) {
|
||||
ev.currentTarget.parentElement.classList.toggle('expanded');
|
||||
}
|
||||
|
||||
Array.from(sidebarAnchorToggles).forEach(function (el) {
|
||||
el.addEventListener('click', toggleSection);
|
||||
});
|
||||
|
||||
function hideSidebar() {
|
||||
body.classList.remove('sidebar-visible')
|
||||
body.classList.add('sidebar-hidden');
|
||||
Array.from(sidebarLinks).forEach(function (link) {
|
||||
link.setAttribute('tabIndex', -1);
|
||||
});
|
||||
sidebarToggleButton.setAttribute('aria-expanded', false);
|
||||
sidebar.setAttribute('aria-hidden', true);
|
||||
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
|
||||
}
|
||||
|
||||
// Toggle sidebar
|
||||
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
|
||||
if (body.classList.contains("sidebar-hidden")) {
|
||||
var current_width = parseInt(
|
||||
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||||
if (current_width < 150) {
|
||||
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||||
}
|
||||
showSidebar();
|
||||
} else if (body.classList.contains("sidebar-visible")) {
|
||||
hideSidebar();
|
||||
} else {
|
||||
if (getComputedStyle(sidebar)['transform'] === 'none') {
|
||||
hideSidebar();
|
||||
} else {
|
||||
showSidebar();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
||||
|
||||
function initResize(e) {
|
||||
window.addEventListener('mousemove', resize, false);
|
||||
window.addEventListener('mouseup', stopResize, false);
|
||||
body.classList.add('sidebar-resizing');
|
||||
}
|
||||
function resize(e) {
|
||||
var pos = (e.clientX - sidebar.offsetLeft);
|
||||
if (pos < 20) {
|
||||
hideSidebar();
|
||||
} else {
|
||||
if (body.classList.contains("sidebar-hidden")) {
|
||||
showSidebar();
|
||||
}
|
||||
pos = Math.min(pos, window.innerWidth - 100);
|
||||
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
|
||||
}
|
||||
}
|
||||
//on mouseup remove windows functions mousemove & mouseup
|
||||
function stopResize(e) {
|
||||
body.classList.remove('sidebar-resizing');
|
||||
window.removeEventListener('mousemove', resize, false);
|
||||
window.removeEventListener('mouseup', stopResize, false);
|
||||
}
|
||||
|
||||
document.addEventListener('touchstart', function (e) {
|
||||
firstContact = {
|
||||
x: e.touches[0].clientX,
|
||||
time: Date.now()
|
||||
};
|
||||
}, { passive: true });
|
||||
|
||||
document.addEventListener('touchmove', function (e) {
|
||||
if (!firstContact)
|
||||
return;
|
||||
|
||||
var curX = e.touches[0].clientX;
|
||||
var xDiff = curX - firstContact.x,
|
||||
tDiff = Date.now() - firstContact.time;
|
||||
|
||||
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
||||
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
|
||||
showSidebar();
|
||||
else if (xDiff < 0 && curX < 300)
|
||||
hideSidebar();
|
||||
|
||||
firstContact = null;
|
||||
}
|
||||
}, { passive: true });
|
||||
})();
|
||||
|
||||
(function chapterNavigation() {
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||||
if (window.search && window.search.hasFocus()) { return; }
|
||||
var html = document.querySelector('html');
|
||||
|
||||
function next() {
|
||||
var nextButton = document.querySelector('.nav-chapters.next');
|
||||
if (nextButton) {
|
||||
window.location.href = nextButton.href;
|
||||
}
|
||||
}
|
||||
function prev() {
|
||||
var previousButton = document.querySelector('.nav-chapters.previous');
|
||||
if (previousButton) {
|
||||
window.location.href = previousButton.href;
|
||||
}
|
||||
}
|
||||
switch (e.key) {
|
||||
case 'ArrowRight':
|
||||
e.preventDefault();
|
||||
if (html.dir == 'rtl') {
|
||||
prev();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
e.preventDefault();
|
||||
if (html.dir == 'rtl') {
|
||||
next();
|
||||
} else {
|
||||
prev();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
(function clipboard() {
|
||||
var clipButtons = document.querySelectorAll('.clip-button');
|
||||
|
||||
function hideTooltip(elem) {
|
||||
elem.firstChild.innerText = "";
|
||||
elem.className = 'fa fa-copy clip-button';
|
||||
}
|
||||
|
||||
function showTooltip(elem, msg) {
|
||||
elem.firstChild.innerText = msg;
|
||||
elem.className = 'fa fa-copy tooltipped';
|
||||
}
|
||||
|
||||
var clipboardSnippets = new ClipboardJS('.clip-button', {
|
||||
text: function (trigger) {
|
||||
hideTooltip(trigger);
|
||||
let playground = trigger.closest("pre");
|
||||
return playground_text(playground, false);
|
||||
}
|
||||
});
|
||||
|
||||
Array.from(clipButtons).forEach(function (clipButton) {
|
||||
clipButton.addEventListener('mouseout', function (e) {
|
||||
hideTooltip(e.currentTarget);
|
||||
});
|
||||
});
|
||||
|
||||
clipboardSnippets.on('success', function (e) {
|
||||
e.clearSelection();
|
||||
showTooltip(e.trigger, "Copied!");
|
||||
});
|
||||
|
||||
clipboardSnippets.on('error', function (e) {
|
||||
showTooltip(e.trigger, "Clipboard error!");
|
||||
});
|
||||
})();
|
||||
|
||||
(function scrollToTop () {
|
||||
var menuTitle = document.querySelector('.menu-title');
|
||||
|
||||
menuTitle.addEventListener('click', function () {
|
||||
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
});
|
||||
})();
|
||||
|
||||
(function controllMenu() {
|
||||
var menu = document.getElementById('menu-bar');
|
||||
|
||||
(function controllPosition() {
|
||||
var scrollTop = document.scrollingElement.scrollTop;
|
||||
var prevScrollTop = scrollTop;
|
||||
var minMenuY = -menu.clientHeight - 50;
|
||||
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
|
||||
menu.style.top = scrollTop + 'px';
|
||||
// Same as parseInt(menu.style.top.slice(0, -2), but faster
|
||||
var topCache = menu.style.top.slice(0, -2);
|
||||
menu.classList.remove('sticky');
|
||||
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
|
||||
document.addEventListener('scroll', function () {
|
||||
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
|
||||
// `null` means that it doesn't need to be updated
|
||||
var nextSticky = null;
|
||||
var nextTop = null;
|
||||
var scrollDown = scrollTop > prevScrollTop;
|
||||
var menuPosAbsoluteY = topCache - scrollTop;
|
||||
if (scrollDown) {
|
||||
nextSticky = false;
|
||||
if (menuPosAbsoluteY > 0) {
|
||||
nextTop = prevScrollTop;
|
||||
}
|
||||
} else {
|
||||
if (menuPosAbsoluteY > 0) {
|
||||
nextSticky = true;
|
||||
} else if (menuPosAbsoluteY < minMenuY) {
|
||||
nextTop = prevScrollTop + minMenuY;
|
||||
}
|
||||
}
|
||||
if (nextSticky === true && stickyCache === false) {
|
||||
menu.classList.add('sticky');
|
||||
stickyCache = true;
|
||||
} else if (nextSticky === false && stickyCache === true) {
|
||||
menu.classList.remove('sticky');
|
||||
stickyCache = false;
|
||||
}
|
||||
if (nextTop !== null) {
|
||||
menu.style.top = nextTop + 'px';
|
||||
topCache = nextTop;
|
||||
}
|
||||
prevScrollTop = scrollTop;
|
||||
}, { passive: true });
|
||||
})();
|
||||
(function controllBorder() {
|
||||
function updateBorder() {
|
||||
if (menu.offsetTop === 0) {
|
||||
menu.classList.remove('bordered');
|
||||
} else {
|
||||
menu.classList.add('bordered');
|
||||
}
|
||||
}
|
||||
updateBorder();
|
||||
document.addEventListener('scroll', updateBorder, { passive: true });
|
||||
})();
|
||||
})();
|
||||
@ -0,0 +1,281 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Contributing - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html" class="active"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="contributing"><a class="header" href="#contributing">Contributing</a></h1>
|
||||
<h2 id="building"><a class="header" href="#building">Building</a></h2>
|
||||
<p>Install Rust with <a href="https://rustup.rs/">rustup</a>, then clone the code.</p>
|
||||
<pre><code>$ git clone git@github.com:Wilfred/difftastic.git
|
||||
$ cd difftastic
|
||||
</code></pre>
|
||||
<p>Difftastic uses <a href="https://doc.rust-lang.org/cargo/">Cargo</a> for
|
||||
building.</p>
|
||||
<pre><code>$ cargo build
|
||||
</code></pre>
|
||||
<p>Debug builds are significantly slower than release builds. For files
|
||||
with more than fifty lines, it's usually worth using an optimised
|
||||
build.</p>
|
||||
<pre><code>$ cargo build --release
|
||||
</code></pre>
|
||||
<h2 id="manual"><a class="header" href="#manual">Manual</a></h2>
|
||||
<p>This website is generated with
|
||||
<a href="https://github.com/rust-lang/mdBook/">mdbook</a>. mdbook can be
|
||||
installed with Cargo.</p>
|
||||
<p><em>Note: difftastic uses an older Rust toolchain version. You have to run <code>cargo install mdbook</code> outside of the repository directory. Otherwise, installation fails.</em></p>
|
||||
<pre><code>$ cargo install mdbook
|
||||
</code></pre>
|
||||
<p>You can then use the <code>mdbook</code> binary to build and serve the site
|
||||
locally.</p>
|
||||
<pre><code>$ cd manual
|
||||
$ mdbook serve
|
||||
</code></pre>
|
||||
<h2 id="api-documentation"><a class="header" href="#api-documentation">API Documentation</a></h2>
|
||||
<p>You can browse the internal API documentation generated by rustdoc
|
||||
<a href="https://difftastic.wilfred.me.uk/rustdoc/difft/">here</a>.</p>
|
||||
<p>Difftastic's internal docs are not available on docs.rs, as it <a href="https://difftastic.wilfred.me.uk/rustdoc/difft/">does
|
||||
not support binary crates today</a>.</p>
|
||||
<h2 id="testing"><a class="header" href="#testing">Testing</a></h2>
|
||||
<pre><code>$ cargo test
|
||||
</code></pre>
|
||||
<p>There are also several files in <code>sample_files/</code> that you can use.</p>
|
||||
<p>The best way to test difftastic is to look at history from a real
|
||||
project. Set <code>GIT_EXTERNAL_DIFF</code> to point to your current build.</p>
|
||||
<p>For example, you can run difftastic on its own source code.</p>
|
||||
<pre><code>$ GIT_EXTERNAL_DIFF=./target/release/difft git log -p --ext-diff -- src
|
||||
</code></pre>
|
||||
<h2 id="logging"><a class="header" href="#logging">Logging</a></h2>
|
||||
<p>Difftastic uses the <code>pretty_env_logger</code> library to log some additional
|
||||
debug information.</p>
|
||||
<pre><code>$ DFT_LOG=debug cargo run sample_files/old.jsx sample_files/new.jsx
|
||||
</code></pre>
|
||||
<p>See the <a href="https://docs.rs/env_logger/0.9.0/env_logger/"><code>env_logger</code>
|
||||
documentation</a> for full details.</p>
|
||||
<h2 id="releasing"><a class="header" href="#releasing">Releasing</a></h2>
|
||||
<p>Use Cargo to create a new release, and tag it in git. Difftastic has a
|
||||
helper script for this:</p>
|
||||
<pre><code>$ ./scripts/release.sh
|
||||
</code></pre>
|
||||
<p>You can now increment the version in Cargo.toml and add a new entry to
|
||||
CHANGELOG.md.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="tricky_cases.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="adding_a_parser.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="tricky_cases.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="adding_a_parser.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,604 @@
|
||||
/* CSS for UI elements (a.k.a. chrome) */
|
||||
|
||||
html {
|
||||
scrollbar-color: var(--scrollbar) var(--bg);
|
||||
}
|
||||
#searchresults a,
|
||||
.content a:link,
|
||||
a:visited,
|
||||
a > .hljs {
|
||||
color: var(--links);
|
||||
}
|
||||
|
||||
/*
|
||||
body-container is necessary because mobile browsers don't seem to like
|
||||
overflow-x on the body tag when there is a <meta name="viewport"> tag.
|
||||
*/
|
||||
#body-container {
|
||||
/*
|
||||
This is used when the sidebar pushes the body content off the side of
|
||||
the screen on small screens. Without it, dragging on mobile Safari
|
||||
will want to reposition the viewport in a weird way.
|
||||
*/
|
||||
overflow-x: clip;
|
||||
}
|
||||
|
||||
/* Menu Bar */
|
||||
|
||||
#menu-bar,
|
||||
#menu-bar-hover-placeholder {
|
||||
z-index: 101;
|
||||
margin: auto calc(0px - var(--page-padding));
|
||||
}
|
||||
#menu-bar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: var(--bg);
|
||||
border-block-end-color: var(--bg);
|
||||
border-block-end-width: 1px;
|
||||
border-block-end-style: solid;
|
||||
}
|
||||
#menu-bar.sticky,
|
||||
.js #menu-bar-hover-placeholder:hover + #menu-bar,
|
||||
.js #menu-bar:hover,
|
||||
.js.sidebar-visible #menu-bar {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0 !important;
|
||||
}
|
||||
#menu-bar-hover-placeholder {
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: 0;
|
||||
height: var(--menu-bar-height);
|
||||
}
|
||||
#menu-bar.bordered {
|
||||
border-block-end-color: var(--table-border-color);
|
||||
}
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
position: relative;
|
||||
padding: 0 8px;
|
||||
z-index: 10;
|
||||
line-height: var(--menu-bar-height);
|
||||
cursor: pointer;
|
||||
transition: color 0.5s;
|
||||
}
|
||||
@media only screen and (max-width: 420px) {
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
.icon-button i {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.right-buttons {
|
||||
margin: 0 15px;
|
||||
}
|
||||
.right-buttons a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.left-buttons {
|
||||
display: flex;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.no-js .left-buttons button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu-title {
|
||||
display: inline-block;
|
||||
font-weight: 200;
|
||||
font-size: 2.4rem;
|
||||
line-height: var(--menu-bar-height);
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.js .menu-title {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.menu-bar,
|
||||
.menu-bar:visited,
|
||||
.nav-chapters,
|
||||
.nav-chapters:visited,
|
||||
.mobile-nav-chapters,
|
||||
.mobile-nav-chapters:visited,
|
||||
.menu-bar .icon-button,
|
||||
.menu-bar a i {
|
||||
color: var(--icons);
|
||||
}
|
||||
|
||||
.menu-bar i:hover,
|
||||
.menu-bar .icon-button:hover,
|
||||
.nav-chapters:hover,
|
||||
.mobile-nav-chapters i:hover {
|
||||
color: var(--icons-hover);
|
||||
}
|
||||
|
||||
/* Nav Icons */
|
||||
|
||||
.nav-chapters {
|
||||
font-size: 2.5em;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
max-width: 150px;
|
||||
min-width: 90px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
flex-direction: column;
|
||||
|
||||
transition: color 0.5s, background-color 0.5s;
|
||||
}
|
||||
|
||||
.nav-chapters:hover {
|
||||
text-decoration: none;
|
||||
background-color: var(--theme-hover);
|
||||
transition: background-color 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.nav-wrapper {
|
||||
margin-block-start: 50px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-nav-chapters {
|
||||
font-size: 2.5em;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
width: 90px;
|
||||
border-radius: 5px;
|
||||
background-color: var(--sidebar-bg);
|
||||
}
|
||||
|
||||
/* Only Firefox supports flow-relative values */
|
||||
.previous { float: left; }
|
||||
[dir=rtl] .previous { float: right; }
|
||||
|
||||
/* Only Firefox supports flow-relative values */
|
||||
.next {
|
||||
float: right;
|
||||
right: var(--page-padding);
|
||||
}
|
||||
[dir=rtl] .next {
|
||||
float: left;
|
||||
right: unset;
|
||||
left: var(--page-padding);
|
||||
}
|
||||
|
||||
/* Use the correct buttons for RTL layouts*/
|
||||
[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";}
|
||||
[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; }
|
||||
|
||||
@media only screen and (max-width: 1080px) {
|
||||
.nav-wide-wrapper { display: none; }
|
||||
.nav-wrapper { display: block; }
|
||||
}
|
||||
|
||||
/* sidebar-visible */
|
||||
@media only screen and (max-width: 1380px) {
|
||||
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; }
|
||||
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; }
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
|
||||
:not(pre) > .hljs {
|
||||
display: inline;
|
||||
padding: 0.1em 0.3em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
:not(pre):not(a) > .hljs {
|
||||
color: var(--inline-code-color);
|
||||
overflow-x: initial;
|
||||
}
|
||||
|
||||
a:hover > .hljs {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
pre {
|
||||
position: relative;
|
||||
}
|
||||
pre > .buttons {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
right: 0px;
|
||||
top: 2px;
|
||||
margin: 0px;
|
||||
padding: 2px 0px;
|
||||
|
||||
color: var(--sidebar-fg);
|
||||
cursor: pointer;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: visibility 0.1s linear, opacity 0.1s linear;
|
||||
}
|
||||
pre:hover > .buttons {
|
||||
visibility: visible;
|
||||
opacity: 1
|
||||
}
|
||||
pre > .buttons :hover {
|
||||
color: var(--sidebar-active);
|
||||
border-color: var(--icons-hover);
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
pre > .buttons i {
|
||||
margin-inline-start: 8px;
|
||||
}
|
||||
pre > .buttons button {
|
||||
cursor: inherit;
|
||||
margin: 0px 5px;
|
||||
padding: 3px 5px;
|
||||
font-size: 14px;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 4px;
|
||||
border-color: var(--icons);
|
||||
background-color: var(--theme-popup-bg);
|
||||
transition: 100ms;
|
||||
transition-property: color,border-color,background-color;
|
||||
color: var(--icons);
|
||||
}
|
||||
@media (pointer: coarse) {
|
||||
pre > .buttons button {
|
||||
/* On mobile, make it easier to tap buttons. */
|
||||
padding: 0.3rem 1rem;
|
||||
}
|
||||
|
||||
.sidebar-resize-indicator {
|
||||
/* Hide resize indicator on devices with limited accuracy */
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
pre > code {
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
/* FIXME: ACE editors overlap their buttons because ACE does absolute
|
||||
positioning within the code block which breaks padding. The only solution I
|
||||
can think of is to move the padding to the outer pre tag (or insert a div
|
||||
wrapper), but that would require fixing a whole bunch of CSS rules.
|
||||
*/
|
||||
.hljs.ace_editor {
|
||||
padding: 0rem 0rem;
|
||||
}
|
||||
|
||||
pre > .result {
|
||||
margin-block-start: 10px;
|
||||
}
|
||||
|
||||
/* Search */
|
||||
|
||||
#searchresults a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
mark {
|
||||
border-radius: 2px;
|
||||
padding-block-start: 0;
|
||||
padding-block-end: 1px;
|
||||
padding-inline-start: 3px;
|
||||
padding-inline-end: 3px;
|
||||
margin-block-start: 0;
|
||||
margin-block-end: -1px;
|
||||
margin-inline-start: -3px;
|
||||
margin-inline-end: -3px;
|
||||
background-color: var(--search-mark-bg);
|
||||
transition: background-color 300ms linear;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
mark.fade-out {
|
||||
background-color: rgba(0,0,0,0) !important;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.searchbar-outer {
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: auto;
|
||||
max-width: var(--content-max-width);
|
||||
}
|
||||
|
||||
#searchbar {
|
||||
width: 100%;
|
||||
margin-block-start: 5px;
|
||||
margin-block-end: 0;
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: auto;
|
||||
padding: 10px 16px;
|
||||
transition: box-shadow 300ms ease-in-out;
|
||||
border: 1px solid var(--searchbar-border-color);
|
||||
border-radius: 3px;
|
||||
background-color: var(--searchbar-bg);
|
||||
color: var(--searchbar-fg);
|
||||
}
|
||||
#searchbar:focus,
|
||||
#searchbar.active {
|
||||
box-shadow: 0 0 3px var(--searchbar-shadow-color);
|
||||
}
|
||||
|
||||
.searchresults-header {
|
||||
font-weight: bold;
|
||||
font-size: 1em;
|
||||
padding-block-start: 18px;
|
||||
padding-block-end: 0;
|
||||
padding-inline-start: 5px;
|
||||
padding-inline-end: 0;
|
||||
color: var(--searchresults-header-fg);
|
||||
}
|
||||
|
||||
.searchresults-outer {
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: auto;
|
||||
max-width: var(--content-max-width);
|
||||
border-block-end: 1px dashed var(--searchresults-border-color);
|
||||
}
|
||||
|
||||
ul#searchresults {
|
||||
list-style: none;
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
ul#searchresults li {
|
||||
margin: 10px 0px;
|
||||
padding: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
ul#searchresults li.focus {
|
||||
background-color: var(--searchresults-li-bg);
|
||||
}
|
||||
ul#searchresults span.teaser {
|
||||
display: block;
|
||||
clear: both;
|
||||
margin-block-start: 5px;
|
||||
margin-block-end: 0;
|
||||
margin-inline-start: 20px;
|
||||
margin-inline-end: 0;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
ul#searchresults span.teaser em {
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: var(--sidebar-width);
|
||||
font-size: 0.875em;
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior-y: contain;
|
||||
background-color: var(--sidebar-bg);
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
[dir=rtl] .sidebar { left: unset; right: 0; }
|
||||
.sidebar-resizing {
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.no-js .sidebar,
|
||||
.js:not(.sidebar-resizing) .sidebar {
|
||||
transition: transform 0.3s; /* Animation: slide away */
|
||||
}
|
||||
.sidebar code {
|
||||
line-height: 2em;
|
||||
}
|
||||
.sidebar .sidebar-scrollbox {
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 10px 10px;
|
||||
}
|
||||
.sidebar .sidebar-resize-handle {
|
||||
position: absolute;
|
||||
cursor: col-resize;
|
||||
width: 0;
|
||||
right: calc(var(--sidebar-resize-indicator-width) * -1);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sidebar-resize-handle .sidebar-resize-indicator {
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background-color: var(--icons);
|
||||
margin-inline-start: var(--sidebar-resize-indicator-space);
|
||||
}
|
||||
|
||||
[dir=rtl] .sidebar .sidebar-resize-handle {
|
||||
left: calc(var(--sidebar-resize-indicator-width) * -1);
|
||||
right: unset;
|
||||
}
|
||||
.js .sidebar .sidebar-resize-handle {
|
||||
cursor: col-resize;
|
||||
width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space));
|
||||
}
|
||||
/* sidebar-hidden */
|
||||
#sidebar-toggle-anchor:not(:checked) ~ .sidebar {
|
||||
transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
|
||||
z-index: -1;
|
||||
}
|
||||
[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar {
|
||||
transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
|
||||
}
|
||||
.sidebar::-webkit-scrollbar {
|
||||
background: var(--sidebar-bg);
|
||||
}
|
||||
.sidebar::-webkit-scrollbar-thumb {
|
||||
background: var(--scrollbar);
|
||||
}
|
||||
|
||||
/* sidebar-visible */
|
||||
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||
transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
|
||||
}
|
||||
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||
transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
|
||||
}
|
||||
@media only screen and (min-width: 620px) {
|
||||
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||
transform: none;
|
||||
margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width));
|
||||
}
|
||||
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.chapter {
|
||||
list-style: none outside none;
|
||||
padding-inline-start: 0;
|
||||
line-height: 2.2em;
|
||||
}
|
||||
|
||||
.chapter ol {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chapter li {
|
||||
display: flex;
|
||||
color: var(--sidebar-non-existant);
|
||||
}
|
||||
.chapter li a {
|
||||
display: block;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
color: var(--sidebar-fg);
|
||||
}
|
||||
|
||||
.chapter li a:hover {
|
||||
color: var(--sidebar-active);
|
||||
}
|
||||
|
||||
.chapter li a.active {
|
||||
color: var(--sidebar-active);
|
||||
}
|
||||
|
||||
.chapter li > a.toggle {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin-inline-start: auto;
|
||||
padding: 0 10px;
|
||||
user-select: none;
|
||||
opacity: 0.68;
|
||||
}
|
||||
|
||||
.chapter li > a.toggle div {
|
||||
transition: transform 0.5s;
|
||||
}
|
||||
|
||||
/* collapse the section */
|
||||
.chapter li:not(.expanded) + li > ol {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chapter li.chapter-item {
|
||||
line-height: 1.5em;
|
||||
margin-block-start: 0.6em;
|
||||
}
|
||||
|
||||
.chapter li.expanded > a.toggle div {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.spacer {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
margin: 5px 0px;
|
||||
}
|
||||
.chapter .spacer {
|
||||
background-color: var(--sidebar-spacer);
|
||||
}
|
||||
|
||||
@media (-moz-touch-enabled: 1), (pointer: coarse) {
|
||||
.chapter li a { padding: 5px 0; }
|
||||
.spacer { margin: 10px 0; }
|
||||
}
|
||||
|
||||
.section {
|
||||
list-style: none outside none;
|
||||
padding-inline-start: 20px;
|
||||
line-height: 1.9em;
|
||||
}
|
||||
|
||||
/* Theme Menu Popup */
|
||||
|
||||
.theme-popup {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: var(--menu-bar-height);
|
||||
z-index: 1000;
|
||||
border-radius: 4px;
|
||||
font-size: 0.7em;
|
||||
color: var(--fg);
|
||||
background: var(--theme-popup-bg);
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
display: none;
|
||||
/* Don't let the children's background extend past the rounded corners. */
|
||||
overflow: hidden;
|
||||
}
|
||||
[dir=rtl] .theme-popup { left: unset; right: 10px; }
|
||||
.theme-popup .default {
|
||||
color: var(--icons);
|
||||
}
|
||||
.theme-popup .theme {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 2px 20px;
|
||||
line-height: 25px;
|
||||
white-space: nowrap;
|
||||
text-align: start;
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
background: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
.theme-popup .theme:hover {
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
|
||||
.theme-selected::before {
|
||||
display: inline-block;
|
||||
content: "✓";
|
||||
margin-inline-start: -14px;
|
||||
width: 14px;
|
||||
}
|
||||
@ -0,0 +1,232 @@
|
||||
/* Base styles and content styles */
|
||||
|
||||
:root {
|
||||
/* Browser default font-size is 16px, this way 1 rem = 10px */
|
||||
font-size: 62.5%;
|
||||
color-scheme: var(--color-scheme);
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
color: var(--fg);
|
||||
background-color: var(--bg);
|
||||
text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-size: 1.6rem;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: var(--mono-font) !important;
|
||||
font-size: var(--code-font-size);
|
||||
direction: ltr !important;
|
||||
}
|
||||
|
||||
/* make long words/inline code not x overflow */
|
||||
main {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
/* make wide tables scroll if they overflow */
|
||||
.table-wrapper {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* Don't change font size in headers. */
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||
font-size: unset;
|
||||
}
|
||||
|
||||
.left { float: left; }
|
||||
.right { float: right; }
|
||||
.boring { opacity: 0.6; }
|
||||
.hide-boring .boring { display: none; }
|
||||
.hidden { display: none !important; }
|
||||
|
||||
h2, h3 { margin-block-start: 2.5em; }
|
||||
h4, h5 { margin-block-start: 2em; }
|
||||
|
||||
.header + .header h3,
|
||||
.header + .header h4,
|
||||
.header + .header h5 {
|
||||
margin-block-start: 1em;
|
||||
}
|
||||
|
||||
h1:target::before,
|
||||
h2:target::before,
|
||||
h3:target::before,
|
||||
h4:target::before,
|
||||
h5:target::before,
|
||||
h6:target::before {
|
||||
display: inline-block;
|
||||
content: "»";
|
||||
margin-inline-start: -30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
/* This is broken on Safari as of version 14, but is fixed
|
||||
in Safari Technology Preview 117 which I think will be Safari 14.2.
|
||||
https://bugs.webkit.org/show_bug.cgi?id=218076
|
||||
*/
|
||||
:target {
|
||||
/* Safari does not support logical properties */
|
||||
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
|
||||
}
|
||||
|
||||
.page {
|
||||
outline: 0;
|
||||
padding: 0 var(--page-padding);
|
||||
margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
|
||||
}
|
||||
.page-wrapper {
|
||||
box-sizing: border-box;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
.no-js .page-wrapper,
|
||||
.js:not(.sidebar-resizing) .page-wrapper {
|
||||
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||
}
|
||||
[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper {
|
||||
transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow-y: auto;
|
||||
padding: 0 5px 50px 5px;
|
||||
}
|
||||
.content main {
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: auto;
|
||||
max-width: var(--content-max-width);
|
||||
}
|
||||
.content p { line-height: 1.45em; }
|
||||
.content ol { line-height: 1.45em; }
|
||||
.content ul { line-height: 1.45em; }
|
||||
.content a { text-decoration: none; }
|
||||
.content a:hover { text-decoration: underline; }
|
||||
.content img, .content video { max-width: 100%; }
|
||||
.content .header:link,
|
||||
.content .header:visited {
|
||||
color: var(--fg);
|
||||
}
|
||||
.content .header:link,
|
||||
.content .header:visited:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 0 auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table td {
|
||||
padding: 3px 20px;
|
||||
border: 1px var(--table-border-color) solid;
|
||||
}
|
||||
table thead {
|
||||
background: var(--table-header-bg);
|
||||
}
|
||||
table thead td {
|
||||
font-weight: 700;
|
||||
border: none;
|
||||
}
|
||||
table thead th {
|
||||
padding: 3px 20px;
|
||||
}
|
||||
table thead tr {
|
||||
border: 1px var(--table-header-bg) solid;
|
||||
}
|
||||
/* Alternate background colors for rows */
|
||||
table tbody tr:nth-child(2n) {
|
||||
background: var(--table-alternate-bg);
|
||||
}
|
||||
|
||||
|
||||
blockquote {
|
||||
margin: 20px 0;
|
||||
padding: 0 20px;
|
||||
color: var(--fg);
|
||||
background-color: var(--quote-bg);
|
||||
border-block-start: .1em solid var(--quote-border);
|
||||
border-block-end: .1em solid var(--quote-border);
|
||||
}
|
||||
|
||||
.warning {
|
||||
margin: 20px;
|
||||
padding: 0 20px;
|
||||
border-inline-start: 2px solid var(--warning-border);
|
||||
}
|
||||
|
||||
.warning:before {
|
||||
position: absolute;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin-inline-start: calc(-1.5rem - 21px);
|
||||
content: "ⓘ";
|
||||
text-align: center;
|
||||
background-color: var(--bg);
|
||||
color: var(--warning-border);
|
||||
font-weight: bold;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
blockquote .warning:before {
|
||||
background-color: var(--quote-bg);
|
||||
}
|
||||
|
||||
kbd {
|
||||
background-color: var(--table-border-color);
|
||||
border-radius: 4px;
|
||||
border: solid 1px var(--theme-popup-border);
|
||||
box-shadow: inset 0 -1px 0 var(--theme-hover);
|
||||
display: inline-block;
|
||||
font-size: var(--code-font-size);
|
||||
font-family: var(--mono-font);
|
||||
line-height: 10px;
|
||||
padding: 4px 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
:not(.footnote-definition) + .footnote-definition,
|
||||
.footnote-definition + :not(.footnote-definition) {
|
||||
margin-block-start: 2em;
|
||||
}
|
||||
.footnote-definition {
|
||||
font-size: 0.9em;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
.footnote-definition p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.tooltiptext {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
color: #fff;
|
||||
background-color: #333;
|
||||
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
|
||||
left: -8px; /* Half of the width of the icon */
|
||||
top: -35px;
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px 8px;
|
||||
margin: 5px;
|
||||
z-index: 1000;
|
||||
}
|
||||
.tooltipped .tooltiptext {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.chapter li.part-title {
|
||||
color: var(--sidebar-fg);
|
||||
margin: 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.result-no-output {
|
||||
font-style: italic;
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
|
||||
#sidebar,
|
||||
#menu-bar,
|
||||
.nav-chapters,
|
||||
.mobile-nav-chapters {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#page-wrapper.page-wrapper {
|
||||
transform: none !important;
|
||||
margin-inline-start: 0px;
|
||||
overflow-y: initial;
|
||||
}
|
||||
|
||||
#content {
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
overflow-y: initial;
|
||||
}
|
||||
|
||||
code {
|
||||
direction: ltr !important;
|
||||
}
|
||||
|
||||
pre > .buttons {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
a, a:visited, a:active, a:hover {
|
||||
color: #4183c4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
page-break-inside: avoid;
|
||||
page-break-after: avoid;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
page-break-inside: avoid;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.fa {
|
||||
display: none !important;
|
||||
}
|
||||
@ -0,0 +1,279 @@
|
||||
|
||||
/* Globals */
|
||||
|
||||
:root {
|
||||
--sidebar-width: 300px;
|
||||
--sidebar-resize-indicator-width: 8px;
|
||||
--sidebar-resize-indicator-space: 2px;
|
||||
--page-padding: 15px;
|
||||
--content-max-width: 750px;
|
||||
--menu-bar-height: 50px;
|
||||
--mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
|
||||
--code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */
|
||||
}
|
||||
|
||||
/* Themes */
|
||||
|
||||
.ayu {
|
||||
--bg: hsl(210, 25%, 8%);
|
||||
--fg: #c5c5c5;
|
||||
|
||||
--sidebar-bg: #14191f;
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #5c6773;
|
||||
--sidebar-active: #ffb454;
|
||||
--sidebar-spacer: #2d334f;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #b7b9cc;
|
||||
|
||||
--links: #0096cf;
|
||||
|
||||
--inline-code-color: #ffb454;
|
||||
|
||||
--theme-popup-bg: #14191f;
|
||||
--theme-popup-border: #5c6773;
|
||||
--theme-hover: #191f26;
|
||||
|
||||
--quote-bg: hsl(226, 15%, 17%);
|
||||
--quote-border: hsl(226, 15%, 22%);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: hsl(210, 25%, 13%);
|
||||
--table-header-bg: hsl(210, 25%, 28%);
|
||||
--table-alternate-bg: hsl(210, 25%, 11%);
|
||||
|
||||
--searchbar-border-color: #848484;
|
||||
--searchbar-bg: #424242;
|
||||
--searchbar-fg: #fff;
|
||||
--searchbar-shadow-color: #d4c89f;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #252932;
|
||||
--search-mark-bg: #e3b171;
|
||||
|
||||
--color-scheme: dark;
|
||||
}
|
||||
|
||||
.coal {
|
||||
--bg: hsl(200, 7%, 8%);
|
||||
--fg: #98a3ad;
|
||||
|
||||
--sidebar-bg: #292c2f;
|
||||
--sidebar-fg: #a1adb8;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: #3473ad;
|
||||
--sidebar-spacer: #393939;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #43484d;
|
||||
--icons-hover: #b3c0cc;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #c5c8c6;
|
||||
|
||||
--theme-popup-bg: #141617;
|
||||
--theme-popup-border: #43484d;
|
||||
--theme-hover: #1f2124;
|
||||
|
||||
--quote-bg: hsl(234, 21%, 18%);
|
||||
--quote-border: hsl(234, 21%, 23%);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: hsl(200, 7%, 13%);
|
||||
--table-header-bg: hsl(200, 7%, 28%);
|
||||
--table-alternate-bg: hsl(200, 7%, 11%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #b7b7b7;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #98a3ad;
|
||||
--searchresults-li-bg: #2b2b2f;
|
||||
--search-mark-bg: #355c7d;
|
||||
|
||||
--color-scheme: dark;
|
||||
}
|
||||
|
||||
.light {
|
||||
--bg: hsl(0, 0%, 100%);
|
||||
--fg: hsl(0, 0%, 0%);
|
||||
|
||||
--sidebar-bg: #fafafa;
|
||||
--sidebar-fg: hsl(0, 0%, 0%);
|
||||
--sidebar-non-existant: #aaaaaa;
|
||||
--sidebar-active: #1f1fff;
|
||||
--sidebar-spacer: #f4f4f4;
|
||||
|
||||
--scrollbar: #8F8F8F;
|
||||
|
||||
--icons: #747474;
|
||||
--icons-hover: #000000;
|
||||
|
||||
--links: #20609f;
|
||||
|
||||
--inline-code-color: #301900;
|
||||
|
||||
--theme-popup-bg: #fafafa;
|
||||
--theme-popup-border: #cccccc;
|
||||
--theme-hover: #e6e6e6;
|
||||
|
||||
--quote-bg: hsl(197, 37%, 96%);
|
||||
--quote-border: hsl(197, 37%, 91%);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: hsl(0, 0%, 95%);
|
||||
--table-header-bg: hsl(0, 0%, 80%);
|
||||
--table-alternate-bg: hsl(0, 0%, 97%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #fafafa;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #e4f2fe;
|
||||
--search-mark-bg: #a2cff5;
|
||||
|
||||
--color-scheme: light;
|
||||
}
|
||||
|
||||
.navy {
|
||||
--bg: hsl(226, 23%, 11%);
|
||||
--fg: #bcbdd0;
|
||||
|
||||
--sidebar-bg: #282d3f;
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #505274;
|
||||
--sidebar-active: #2b79a2;
|
||||
--sidebar-spacer: #2d334f;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #b7b9cc;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #c5c8c6;
|
||||
|
||||
--theme-popup-bg: #161923;
|
||||
--theme-popup-border: #737480;
|
||||
--theme-hover: #282e40;
|
||||
|
||||
--quote-bg: hsl(226, 15%, 17%);
|
||||
--quote-border: hsl(226, 15%, 22%);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: hsl(226, 23%, 16%);
|
||||
--table-header-bg: hsl(226, 23%, 31%);
|
||||
--table-alternate-bg: hsl(226, 23%, 14%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #aeaec6;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #5f5f71;
|
||||
--searchresults-border-color: #5c5c68;
|
||||
--searchresults-li-bg: #242430;
|
||||
--search-mark-bg: #a2cff5;
|
||||
|
||||
--color-scheme: dark;
|
||||
}
|
||||
|
||||
.rust {
|
||||
--bg: hsl(60, 9%, 87%);
|
||||
--fg: #262625;
|
||||
|
||||
--sidebar-bg: #3b2e2a;
|
||||
--sidebar-fg: #c8c9db;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: #e69f67;
|
||||
--sidebar-spacer: #45373a;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #737480;
|
||||
--icons-hover: #262625;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #6e6b5e;
|
||||
|
||||
--theme-popup-bg: #e1e1db;
|
||||
--theme-popup-border: #b38f6b;
|
||||
--theme-hover: #99908a;
|
||||
|
||||
--quote-bg: hsl(60, 5%, 75%);
|
||||
--quote-border: hsl(60, 5%, 70%);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: hsl(60, 9%, 82%);
|
||||
--table-header-bg: #b3a497;
|
||||
--table-alternate-bg: hsl(60, 9%, 84%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #fafafa;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #888;
|
||||
--searchresults-li-bg: #dec2a2;
|
||||
--search-mark-bg: #e69f67;
|
||||
|
||||
--color-scheme: light;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.light.no-js {
|
||||
--bg: hsl(200, 7%, 8%);
|
||||
--fg: #98a3ad;
|
||||
|
||||
--sidebar-bg: #292c2f;
|
||||
--sidebar-fg: #a1adb8;
|
||||
--sidebar-non-existant: #505254;
|
||||
--sidebar-active: #3473ad;
|
||||
--sidebar-spacer: #393939;
|
||||
|
||||
--scrollbar: var(--sidebar-fg);
|
||||
|
||||
--icons: #43484d;
|
||||
--icons-hover: #b3c0cc;
|
||||
|
||||
--links: #2b79a2;
|
||||
|
||||
--inline-code-color: #c5c8c6;
|
||||
|
||||
--theme-popup-bg: #141617;
|
||||
--theme-popup-border: #43484d;
|
||||
--theme-hover: #1f2124;
|
||||
|
||||
--quote-bg: hsl(234, 21%, 18%);
|
||||
--quote-border: hsl(234, 21%, 23%);
|
||||
|
||||
--warning-border: #ff8e00;
|
||||
|
||||
--table-border-color: hsl(200, 7%, 13%);
|
||||
--table-header-bg: hsl(200, 7%, 28%);
|
||||
--table-alternate-bg: hsl(200, 7%, 11%);
|
||||
|
||||
--searchbar-border-color: #aaa;
|
||||
--searchbar-bg: #b7b7b7;
|
||||
--searchbar-fg: #000;
|
||||
--searchbar-shadow-color: #aaa;
|
||||
--searchresults-header-fg: #666;
|
||||
--searchresults-border-color: #98a3ad;
|
||||
--searchresults-li-bg: #2b2b2f;
|
||||
--search-mark-bg: #355c7d;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,306 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Internals: Diffing - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html" class="active"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="internals-diffing"><a class="header" href="#internals-diffing">Internals: Diffing</a></h1>
|
||||
<p>Difftastic treats diff calculations as a route finding problem on a
|
||||
directed acyclic graph.</p>
|
||||
<h2 id="graph-representation"><a class="header" href="#graph-representation">Graph Representation</a></h2>
|
||||
<p>A vertex in the graph represents a position in two syntax trees.</p>
|
||||
<p>The start vertex has both positions pointing to the first syntax node
|
||||
in both trees. The end vertex has both positions just
|
||||
after the last syntax node in both trees.</p>
|
||||
<p>Consider comparing <code>A</code> with <code>X A</code>.</p>
|
||||
<pre><code>START
|
||||
+---------------------+
|
||||
| Left: A Right: X A |
|
||||
| ^ ^ |
|
||||
+---------------------+
|
||||
|
||||
END
|
||||
+---------------------+
|
||||
| Left: A Right: X A |
|
||||
| ^ ^|
|
||||
+---------------------+
|
||||
</code></pre>
|
||||
<p>From the start vertex, we have two options:</p>
|
||||
<ul>
|
||||
<li>we can mark the first syntax node on the left as novel, and advance
|
||||
to the next syntax node on the left (vertex 1 above), or</li>
|
||||
<li>we can mark the first syntax node on the right as novel, and advance
|
||||
to the next syntax node on the right (vertex 2 above).</li>
|
||||
</ul>
|
||||
<pre><code> START
|
||||
+---------------------+
|
||||
| Left: A Right: X A |
|
||||
| ^ ^ |
|
||||
+---------------------+
|
||||
/ \
|
||||
Novel atom L / \ Novel atom R
|
||||
1 v 2 v
|
||||
+---------------------+ +---------------------+
|
||||
| Left: A Right: X A | | Left: A Right: X A |
|
||||
| ^ ^ | | ^ ^ |
|
||||
+---------------------+ +---------------------+
|
||||
</code></pre>
|
||||
<p>Choosing "novel atom R" to vertex 2 will turn out to be the best
|
||||
choice. From vertex 2, we can see three routes to the end vertex.</p>
|
||||
<pre><code> 2
|
||||
+---------------------+
|
||||
| Left: A Right: X A |
|
||||
| ^ ^ |
|
||||
+---------------------+
|
||||
/ | \
|
||||
Novel atom L / | \ Novel atom R
|
||||
v | v
|
||||
+---------------------+ | +---------------------+
|
||||
| Left: A Right: X A | | | Left: A Right: X A |
|
||||
| ^ ^ | | | ^ ^|
|
||||
+---------------------+ | +---------------------+
|
||||
| | |
|
||||
| Novel atom R | Nodes match | Novel atom L
|
||||
| | |
|
||||
| END v |
|
||||
| +---------------------+ |
|
||||
+-------->| Left: A Right: X A |<---------+
|
||||
| ^ ^|
|
||||
+---------------------+
|
||||
</code></pre>
|
||||
<h2 id="comparing-routes"><a class="header" href="#comparing-routes">Comparing Routes</a></h2>
|
||||
<p>We assign a cost to each edge. Marking a syntax node as novel is worse
|
||||
than finding a matching syntax node, so the "novel atom" edge has a
|
||||
higher cost than the "syntax nodes match" edge.</p>
|
||||
<p>The best route is the lowest cost route from the start vertex to the
|
||||
end vertex.</p>
|
||||
<h2 id="finding-the-best-route"><a class="header" href="#finding-the-best-route">Finding The Best Route</a></h2>
|
||||
<p>Difftastic uses Dijkstra's algorithm to find the best (i.e. lowest cost)
|
||||
route.</p>
|
||||
<p>One big advantage of this algorithm is that we don't need to construct
|
||||
the graph in advance. Constructing the whole graph would require
|
||||
exponential memory relative to the number of syntax nodes. Instead,
|
||||
vertex neighbours are constructed as the graph is explored.</p>
|
||||
<p>There are lots of resources explaining Dijkstra's algorithm online,
|
||||
but I particularly recommend the <a href="https://www.redblobgames.com/pathfinding/a-star/introduction.html#dijkstra">graph search section of Red Blob
|
||||
Games</a>.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="parsing.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="tricky_cases.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="parsing.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="tricky_cases.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 894 B |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
|
||||
<path d="M0 0 C0.86625 -0.00773438 1.7325 -0.01546875 2.625 -0.0234375 C5 0.375 5 0.375 6.7890625 1.5859375 C8.39038277 3.95175906 8.40035579 5.53515158 8.375 8.375 C8.38273437 9.24125 8.39046875 10.1075 8.3984375 11 C8 13.375 8 13.375 6.7890625 15.1640625 C4.42324094 16.76538277 2.83984842 16.77535579 0 16.75 C-0.86625 16.75773437 -1.7325 16.76546875 -2.625 16.7734375 C-5 16.375 -5 16.375 -6.7890625 15.1640625 C-8.39038277 12.79824094 -8.40035579 11.21484842 -8.375 8.375 C-8.38273438 7.50875 -8.39046875 6.6425 -8.3984375 5.75 C-8 3.375 -8 3.375 -6.7890625 1.5859375 C-4.42324094 -0.01538277 -2.83984842 -0.02535579 0 0 Z " fill="#8AE234" transform="translate(8,-0.375)"/>
|
||||
<path d="M0 0 C0 5.28 0 10.56 0 16 C-5 16 -5 16 -6.7890625 14.8125 C-8.38009461 12.43108419 -8.40042889 10.84803599 -8.375 8 C-8.38273438 7.13375 -8.39046875 6.2675 -8.3984375 5.375 C-8 3 -8 3 -6.7890625 1.1875 C-5 -0 -5 -0 0 0 Z " fill="#EF2929" transform="translate(8,0)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@ -0,0 +1,93 @@
|
||||
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@ -0,0 +1,100 @@
|
||||
/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */
|
||||
/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */
|
||||
|
||||
/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light'), local('OpenSans-Light'),
|
||||
url('open-sans-v17-all-charsets-300.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
|
||||
url('open-sans-v17-all-charsets-300italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Regular'), local('OpenSans-Regular'),
|
||||
url('open-sans-v17-all-charsets-regular.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Open Sans Italic'), local('OpenSans-Italic'),
|
||||
url('open-sans-v17-all-charsets-italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
|
||||
url('open-sans-v17-all-charsets-600.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
|
||||
url('open-sans-v17-all-charsets-600italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold'), local('OpenSans-Bold'),
|
||||
url('open-sans-v17-all-charsets-700.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
|
||||
url('open-sans-v17-all-charsets-700italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'),
|
||||
url('open-sans-v17-all-charsets-800.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'),
|
||||
url('open-sans-v17-all-charsets-800italic.woff2') format('woff2');
|
||||
}
|
||||
|
||||
/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Source Code Pro';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2');
|
||||
}
|
||||
@ -0,0 +1,241 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Fossil - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html" class="active"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="fossil"><a class="header" href="#fossil">Fossil</a></h1>
|
||||
<p><a href="https://fossil-scm.org/">Fossil</a> supports external <code>diff</code> commands by <a href="https://fossil-scm.org/home/help?cmd=diff-command">setting <code>diff-command</code></a> for the current repository:</p>
|
||||
<pre><code>fossil settings diff-command difft
|
||||
</code></pre>
|
||||
<p>To use difftastic for all repositories, use <code>--global</code>:</p>
|
||||
<pre><code>fossil settings diff-command --global difft
|
||||
</code></pre>
|
||||
<h2 id="skip-difftastic-on-fossil"><a class="header" href="#skip-difftastic-on-fossil">Skip difftastic on Fossil</a></h2>
|
||||
<p>If you set difftastic as Fossil's <code>diff</code> command, but you need to use Fossil's internal diff once, use <code>-i</code> to skip difftastic once:</p>
|
||||
<pre><code>fossil diff -i
|
||||
</code></pre>
|
||||
<p>If you want to remove difftastic from one repository (or globally), use <code>unset</code>:</p>
|
||||
<pre><code>fossil unset diff-command
|
||||
</code></pre>
|
||||
<p><code>unset</code> also supports the <code>--global</code> flag.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="mercurial.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="jj.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="mercurial.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="jj.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,257 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>From Source - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html" class="active"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="installing-from-source"><a class="header" href="#installing-from-source">Installing From Source</a></h1>
|
||||
<h3 id="build-requirements"><a class="header" href="#build-requirements">Build Requirements</a></h3>
|
||||
<p>Difftastic is written in Rust, so you will need Rust installed. I
|
||||
recommend <a href="https://rustup.rs/">rustup</a> to install Rust. Difftastic
|
||||
requires Rust version 1.75 or later.</p>
|
||||
<p>You will also need a C++ compiler that supports C++14. If you're using
|
||||
GCC, you need at least version 8.</p>
|
||||
<h3 id="build"><a class="header" href="#build">Build</a></h3>
|
||||
<p>You can download and build <a href="https://crates.io/crates/difftastic">difftastic on
|
||||
crates.io</a> with Cargo (which is
|
||||
part of Rust).</p>
|
||||
<pre><code>$ cargo install --locked difftastic
|
||||
</code></pre>
|
||||
<p>Difftastic uses the <code>cc</code> crate for building C/C++ dependencies. This
|
||||
allows you to use environment variables <code>CC</code> and <code>CXX</code> to control the
|
||||
compiler used (see the <a href="https://github.com/alexcrichton/cc-rs#external-configuration-via-environment-variables"><code>cc</code>
|
||||
docs</a>).</p>
|
||||
<p>See <a href="./contributing.html">contributing</a> for instructions on debug
|
||||
builds.</p>
|
||||
<h2 id="optional-install-a-mime-database"><a class="header" href="#optional-install-a-mime-database">(Optional) Install a MIME Database</a></h2>
|
||||
<p>If a MIME database is available, difftastic will use it to detect
|
||||
binary files more accurately. This is the same database used by the
|
||||
<code>file</code> command, so you probably already have it.</p>
|
||||
<p>The MIME database path is <a href="https://specifications.freedesktop.org/shared-mime-info-spec/0.11/ar01s03.html">specified in the XDG
|
||||
specification</a>. The
|
||||
database should be at one of the following paths:</p>
|
||||
<ul>
|
||||
<li><code>/usr/share/mime/magic</code></li>
|
||||
<li><code>/usr/local/share/mime/magic</code></li>
|
||||
<li><code>$HOME/.local/share/mime/magic</code></li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="installation.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="packaging_difftastic.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="installation.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="packaging_difftastic.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Redirecting...</title>
|
||||
<meta http-equiv="refresh" content="0; URL=./installation.html">
|
||||
<link rel="canonical" href="./installation.html">
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to... <a href="./installation.html">./installation.html</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,320 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Git - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html" class="active"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="git"><a class="header" href="#git">Git</a></h1>
|
||||
<p>Difftastic can be used an external diff command in git, allowing
|
||||
difftastic to be used with any git subcommand.</p>
|
||||
<div class="warning">
|
||||
<p>Warning: git v2.43.1 and earlier <a href="https://github.com/git/git/commit/85a9a63c9268b18b24f25f6a14d6ae9966c3566d">can
|
||||
crash</a>
|
||||
when using an external diff and file permissions have changed.</p>
|
||||
<p>If you can't upgrade git, use the <code>difftool</code> configuration described
|
||||
below.</p>
|
||||
</div>
|
||||
<h2 id="one-off-usage"><a class="header" href="#one-off-usage">One-Off Usage</a></h2>
|
||||
<p>You can set the <code>diff.external</code> configuration option when running <code>git diff</code>, or set the
|
||||
<a href="https://git-scm.com/docs/diff-config#Documentation/diff-config.txt-diffexternal"><code>GIT_EXTERNAL_DIFF</code></a> environment variable.</p>
|
||||
<p>View uncommitted changes with difftastic:</p>
|
||||
<pre><code>$ git -c diff.external=difft diff
|
||||
</code></pre>
|
||||
<p>Other git commands also require the <code>--ext-diff</code> argument in order to
|
||||
use <code>diff.external</code>.</p>
|
||||
<p>View changes from the most recent commit with difftastic:</p>
|
||||
<pre><code>$ git -c diff.external=difft show --ext-diff
|
||||
</code></pre>
|
||||
<p>View changes from recent commits on the current branch with
|
||||
difftastic:</p>
|
||||
<pre><code>$ git -c diff.external=difft log -p --ext-diff
|
||||
</code></pre>
|
||||
<h2 id="regular-usage"><a class="header" href="#regular-usage">Regular Usage</a></h2>
|
||||
<p>If you like difftastic, we recommend that you configure git aliases
|
||||
so you can use difftastic more easily.</p>
|
||||
<pre><code class="language-ini">[alias]
|
||||
# Difftastic aliases, so `git dlog` is `git log` with difftastic and so on.
|
||||
dlog = -c diff.external=difft log --ext-diff
|
||||
dshow = -c diff.external=difft show --ext-diff
|
||||
ddiff = -c diff.external=difft diff
|
||||
</code></pre>
|
||||
<p>The author likes the following additional aliases to reduce typing:</p>
|
||||
<pre><code class="language-ini">[alias]
|
||||
# `git log` with patches shown with difftastic.
|
||||
dl = -c diff.external=difft log -p --ext-diff
|
||||
|
||||
# Show the most recent commit with difftastic.
|
||||
ds = -c diff.external=difft show --ext-diff
|
||||
|
||||
# `git diff` with difftastic.
|
||||
dft = -c diff.external=difft diff
|
||||
</code></pre>
|
||||
<h2 id="difftastic-by-default"><a class="header" href="#difftastic-by-default">Difftastic By Default</a></h2>
|
||||
<p>If you want to use difftastic as your default diff tool, add the
|
||||
following to your <code>~/.gitconfig</code>.</p>
|
||||
<pre><code class="language-ini">[diff]
|
||||
external = difft
|
||||
</code></pre>
|
||||
<p>This changes <code>git diff</code> to use difftastic, and other commands now only
|
||||
require <code>--ext-diff</code>.</p>
|
||||
<pre><code>$ git diff
|
||||
$ git show --ext-diff
|
||||
$ git log -p --ext-diff
|
||||
</code></pre>
|
||||
<p>If you've configured difftastic as the default diff tool, you can
|
||||
opt-out for an individual command with <code>--no-ext-diff</code>.</p>
|
||||
<pre><code>$ git diff --no-ext-diff
|
||||
</code></pre>
|
||||
<h2 id="difftool"><a class="header" href="#difftool">Difftool</a></h2>
|
||||
<p>Git also has a <a href="https://git-scm.com/docs/git-difftool">difftool
|
||||
feature</a> which allows users to
|
||||
invoke CLI or GUI comparison tools.</p>
|
||||
<p>For best results, we recommend using <code>-c diff.external=difft</code> as
|
||||
described above. Git passes more information to the external diff,
|
||||
including file permission changes and rename information, so
|
||||
difftastic can show more information.</p>
|
||||
<p>To define a difftool named <code>difftastic</code>, add the following to your
|
||||
<code>~/.gitconfig</code>.</p>
|
||||
<pre><code class="language-ini">[difftool "difftastic"]
|
||||
# See `man git-difftool` for a description of MERGED, LOCAL and REMOTE.
|
||||
cmd = difft "$MERGED" "$LOCAL" "abcdef1" "100644" "$REMOTE" "abcdef2" "100644"
|
||||
</code></pre>
|
||||
<p>You can now use difftastic as a difftool:</p>
|
||||
<pre><code>$ git difftool -t difftastic
|
||||
</code></pre>
|
||||
<p>For the best results when using difftastic as a difftool, we recommend
|
||||
the following additional git configuration:</p>
|
||||
<pre><code class="language-ini">[difftool]
|
||||
# Run the difftool immediately, don't ask 'are you sure' each time.
|
||||
prompt = false
|
||||
|
||||
[pager]
|
||||
# Use a pager if the difftool output is larger than one screenful,
|
||||
# consistent with the behaviour of `git diff`.
|
||||
difftool = true
|
||||
|
||||
[diff]
|
||||
# Set difftastic as the default difftool, so we don't need to specify
|
||||
# `-t difftastic` every time.
|
||||
tool = difftastic
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="usage.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="mercurial.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="usage.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="mercurial.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,260 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Glossary - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html" class="active"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="glossary"><a class="header" href="#glossary">Glossary</a></h1>
|
||||
<p><strong>Atom</strong>: An atom is an item in difftastic's syntax tree structure
|
||||
that has no children. It represents things like literals, variable
|
||||
names, and comments. See also 'list'.</p>
|
||||
<p><strong>Delimiter</strong>: A paired piece of syntax. A list has an open delimiter
|
||||
and a close delimiter, such as <code>[</code> and <code>]</code>. Delimiters may not be
|
||||
punctuation (e.g. <code>begin</code> and <code>end</code>) and may be empty strings (e.g. infix
|
||||
syntax converted to difftastic's syntax tree).</p>
|
||||
<p><strong>Hunk</strong>: A group of lines displayed together in the diff
|
||||
output. Increasing the number of context lines increases the size of
|
||||
the hunk.</p>
|
||||
<p><strong>LHS</strong>: Left-hand side. Difftastic compares two items, and LHS refers
|
||||
to the first item. See also 'RHS'.</p>
|
||||
<p><strong>Line-oriented</strong>: A traditional diff that compares which lines have
|
||||
been added or removed, unlike difftastic. For example, GNU diff or the
|
||||
diffs displayed on GitHub.</p>
|
||||
<p><strong>List</strong>: A list is an item in difftastic's syntax tree structure that
|
||||
has an open delimiter, children, and a close delimiter. It represents
|
||||
things like expressions and function definitions. See also 'atom'.</p>
|
||||
<p><strong>Novel</strong>: An addition or a removal. Syntax is novel if it occurs
|
||||
in only one of the two items being compared.</p>
|
||||
<p><strong>RHS</strong>: Right-hand side. Difftastic compares two items, and RHS
|
||||
refers to the second item. See also 'LHS'.</p>
|
||||
<p><strong>Root</strong>: A syntax tree without a parent node. Roots represent
|
||||
top-level definitions in the file being diffed.</p>
|
||||
<p><strong>Slider</strong>: A diffing situation where there are multiple minimal diffs
|
||||
possible, due to adjacent content. It is possible to 'slide' to
|
||||
produce better results in this situation. See <a href="./tricky_cases.html#sliders-flat">the discussion in Tricky
|
||||
Cases</a>.</p>
|
||||
<p><strong>Syntax node</strong>: An item in difftastic's syntax tree structure. Either
|
||||
an atom or a list.</p>
|
||||
<p><strong>Token</strong>: A small piece of syntax tracked by difftastic (e.g. <code>$x</code>,
|
||||
<code>function</code> or <code>]</code>), for highlighting and aligned display. This is
|
||||
either an atom or a non-empty delimiter.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="profiling.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="alternative_projects.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="profiling.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="alternative_projects.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* An increased contrast highlighting scheme loosely based on the
|
||||
* "Base16 Atelier Dune Light" theme by Bram de Haan
|
||||
* (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune)
|
||||
* Original Base16 color scheme by Chris Kempson
|
||||
* (https://github.com/chriskempson/base16)
|
||||
*/
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #575757;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d70025;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b21e00;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #008200;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #0030f2;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #9d00ec;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f6f7f6;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #22863a;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0;
|
||||
}
|
||||
|
After Width: | Height: | Size: 31 KiB |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path fill="#444" d="M2.1 3.1c0.2 1.3 0.4 1.6 0.4 2.9 0 0.8-1.5 1.5-1.5 1.5v1c0 0 1.5 0.7 1.5 1.5 0 1.3-0.2 1.6-0.4 2.9-0.3 2.1 0.8 3.1 1.8 3.1s2.1 0 2.1 0v-2c0 0-1.8 0.2-1.8-1 0-0.9 0.2-0.9 0.4-2.9 0.1-0.9-0.5-1.6-1.1-2.1 0.6-0.5 1.2-1.1 1.1-2-0.3-2-0.4-2-0.4-2.9 0-1.2 1.8-1.1 1.8-1.1v-2c0 0-1 0-2.1 0s-2.1 1-1.8 3.1z"></path>
|
||||
<path fill="#444" d="M13.9 3.1c-0.2 1.3-0.4 1.6-0.4 2.9 0 0.8 1.5 1.5 1.5 1.5v1c0 0-1.5 0.7-1.5 1.5 0 1.3 0.2 1.6 0.4 2.9 0.3 2.1-0.8 3.1-1.8 3.1s-2.1 0-2.1 0v-2c0 0 1.8 0.2 1.8-1 0-0.9-0.2-0.9-0.4-2.9-0.1-0.9 0.5-1.6 1.1-2.1-0.6-0.5-1.2-1.1-1.1-2 0.2-2 0.4-2 0.4-2.9 0-1.2-1.8-1.1-1.8-1.1v-2c0 0 1 0 2.1 0s2.1 1 1.8 3.1z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 44 KiB |
@ -0,0 +1,7 @@
|
||||
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none">
|
||||
<path d="M64 0C28.712 0 0 28.6 0 63.751c0 35.155 28.712 63.753 64 63.753s64-28.598 64-63.753C128 28.6 99.288 0 64 0" fill="#FFF"/>
|
||||
<path d="M61.659 64.898a265.825 265.825 0 00-1.867 4.12c-2.322 5.241-4.894 11.62-5.834 15.706-.337 1.455-.546 3.258-.542 5.258 0 .79.043 1.622.11 2.469a30.74 30.74 0 0010.533 1.87 30.796 30.796 0 009.642-1.566 18.09 18.09 0 01-2.011-2.12c-4.11-5.221-6.403-12.872-10.031-25.737M46.485 38.96c-7.85 5.51-12.986 14.6-13.005 24.9.019 10.145 5.001 19.116 12.653 24.65 1.877-7.789 6.582-14.92 13.637-29.214a114.691 114.691 0 00-1.43-3.72c-1.955-4.884-4.776-10.556-7.294-13.124-1.283-1.342-2.84-2.502-4.561-3.492" fill="#91DC47"/>
|
||||
<path d="M90.697 98.798c-4.05-.506-7.392-1.116-10.317-2.144a36.708 36.708 0 01-16.32 3.807c-20.293 0-36.742-16.383-36.745-36.602 0-10.97 4.852-20.805 12.528-27.512-2.053-.495-4.194-.783-6.38-.779-10.782.101-22.162 6.044-26.9 22.095-.443 2.337-.337 4.103-.337 6.197 0 31.818 25.895 57.613 57.835 57.613 19.561 0 36.841-9.682 47.305-24.489-5.66 1.405-11.103 2.077-15.763 2.091-1.747 0-3.387-.093-4.906-.277" fill="#63B132"/><path d="M79.829 87.634c.357.176 1.167.464 2.293.783 7.579-5.542 12.504-14.469 12.523-24.558h-.003c-.028-16.82-13.693-30.43-30.582-30.462a30.765 30.765 0 00-9.602 1.554c6.21 7.05 9.196 17.127 12.084 28.148l.005.013c.005.009.924 3.06 2.501 7.11 1.566 4.042 3.797 9.048 6.23 12.696 1.597 2.444 3.354 4.2 4.551 4.716" fill="#90B4FE"/><path d="M17.057 30.311c5.463-3.408 11.04-4.637 15.908-4.593 6.722.02 12.008 2.096 14.544 3.516.612.352 1.194.73 1.764 1.12a36.714 36.714 0 0114.786-3.096c20.295.003 36.747 16.386 36.75 36.601-.003 10.192-4.188 19.408-10.934 26.044a45.3 45.3 0 005.225.29c6.406.004 13.329-1.404 18.52-5.753 3.384-2.84 6.22-6.998 7.792-13.233.307-2.408.484-4.856.484-7.347 0-31.817-25.892-57.614-57.835-57.614-19.372 0-36.508 9.5-47.004 24.065z" fill="#5881D8"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#D26383" d="M115.4 30.7L67.1 2.9c-.8-.5-1.9-.7-3.1-.7-1.2 0-2.3.3-3.1.7l-48 27.9c-1.7 1-2.9 3.5-2.9 5.4v55.7c0 1.1.2 2.4 1 3.5l106.8-62c-.6-1.2-1.5-2.1-2.4-2.7z"/><path fill="#9C033A" d="M10.7 95.3c.5.8 1.2 1.5 1.9 1.9l48.2 27.9c.8.5 1.9.7 3.1.7 1.2 0 2.3-.3 3.1-.7l48-27.9c1.7-1 2.9-3.5 2.9-5.4V36.1c0-.9-.1-1.9-.6-2.8l-106.6 62z"/><path fill="#fff" d="M85.3 76.1C81.1 83.5 73.1 88.5 64 88.5c-13.5 0-24.5-11-24.5-24.5s11-24.5 24.5-24.5c9.1 0 17.1 5 21.3 12.5l13-7.5c-6.8-11.9-19.6-20-34.3-20-21.8 0-39.5 17.7-39.5 39.5s17.7 39.5 39.5 39.5c14.6 0 27.4-8 34.2-19.8l-12.9-7.6z"/><path d="M82.1 61.8h5.2v-5.3h4.4v5.3H97v4.4h-5.3v5.2h-4.4v-5.2h-5.2v-4.4zm18.5 0h5.2v-5.3h4.4v5.3h5.3v4.4h-5.3v5.2h-4.4v-5.2h-5.2v-4.4z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 808 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#9B4F96" d="M115.4 30.7L67.1 2.9c-.8-.5-1.9-.7-3.1-.7-1.2 0-2.3.3-3.1.7l-48 27.9c-1.7 1-2.9 3.5-2.9 5.4v55.7c0 1.1.2 2.4 1 3.5l106.8-62c-.6-1.2-1.5-2.1-2.4-2.7z"/><path fill="#68217A" d="M10.7 95.3c.5.8 1.2 1.5 1.9 1.9l48.2 27.9c.8.5 1.9.7 3.1.7 1.2 0 2.3-.3 3.1-.7l48-27.9c1.7-1 2.9-3.5 2.9-5.4V36.1c0-.9-.1-1.9-.6-2.8l-106.6 62z"/><path fill="#fff" d="M85.3 76.1C81.1 83.5 73.1 88.5 64 88.5c-13.5 0-24.5-11-24.5-24.5s11-24.5 24.5-24.5c9.1 0 17.1 5 21.3 12.5l13-7.5c-6.8-11.9-19.6-20-34.3-20-21.8 0-39.5 17.7-39.5 39.5s17.7 39.5 39.5 39.5c14.6 0 27.4-8 34.2-19.8l-12.9-7.6zM97 66.2l.9-4.3h-4.2v-4.7h5.1L100 51h4.9l-1.2 6.1h3.8l1.2-6.1h4.8l-1.2 6.1h2.4v4.7h-3.3l-.9 4.3h4.2v4.7h-5.1l-1.2 6h-4.9l1.2-6h-3.8l-1.2 6h-4.8l1.2-6h-2.4v-4.7H97zm4.8 0h3.8l.9-4.3h-3.8l-.9 4.3z"/></svg>
|
||||
|
After Width: | Height: | Size: 851 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#00c4b3" d="M35.2 34.9l-8.3-8.3v59.7l.1 2.8c0 1.3.2 2.8.7 4.3l65.6 23.1 16.3-7.2-74.4-74.4z"/><path d="M27.7 93.4zm81.9 15.9l-16.3 7.2-65.4-23.1c1.3 4.8 4 10.1 7 13.2l21.3 21.2 47.6.1 5.8-18.6z" fill="#22d3c5"/><path fill="#0075c9" d="M1.7 65.1C-.4 67.3.7 72 4 75.5l14.7 14.8 9.2 3.3c-.3-1.5-.7-3-.7-4.3l-.1-2.8-.2-59.8m82.7 82.6l7.2-16.4-23-65.6c-1.5-.3-3-.6-4.3-.7l-2.9-.1-59.6.1"/><path d="M93.6 27.3c.2 0 .2 0 0 0 .2 0 .2 0 0 0zm16 82l17.7-5.8V54.8l-20.4-20.5c-3-3-8.3-5.8-13.2-7l23.1 65.6" fill="#00a8e1"/><path fill="#00c4b3" d="M90.5 18.2L75.7 3.5c-3.4-3.4-8-4.4-10.4-2.3L26.9 26.6h59.5l2.9.1c1.3 0 2.8.2 4.3.7l-3.1-9.2z"/></svg>
|
||||
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 48 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path d="M20.7 103.9C11 93.5 5.2 79.2 5.3 62.1 5.2 47 10 34 18.2 24.1H1v79.7l19.7.1zm90.4 0c4.2-4.5 8-9.8 11.4-15.9l-19-9.5c-6.7 10.8-16.4 20.8-29.9 20.9-19.6-.1-27.3-16.9-27.3-38.5h73.3c.1-2.4.1-3.6 0-4.7.5-12.9-2.9-23.7-9.1-32.1H127v79.7l-15.9.1zM47.5 42.4c.8-9.8 8.5-16.3 17.6-16.4 9.1 0 15.7 6.6 15.9 16.4H47.5z" fill="#A90533"/></svg>
|
||||
|
After Width: | Height: | Size: 401 B |
|
After Width: | Height: | Size: 63 KiB |
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-github" viewBox="0 0 16 16">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 708 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><g fill="#00acd7" fill-rule="evenodd"><path d="M11.156 54.829c-.243 0-.303-.122-.182-.303l1.273-1.637c.12-.182.424-.303.666-.303H34.55c.243 0 .303.182.182.364l-1.03 1.576c-.121.181-.424.363-.606.363zM2.004 60.404c-.242 0-.303-.12-.182-.303l1.273-1.636c.121-.182.424-.303.667-.303h27.636c.242 0 .364.182.303.364l-.485 1.454c-.06.243-.303.364-.545.364zM16.67 65.98c-.242 0-.302-.182-.181-.364l.848-1.515c.122-.182.364-.363.607-.363h12.12c.243 0 .364.181.364.424l-.12 1.454c0 .243-.243.425-.425.425zM79.58 53.738c-3.819.97-6.425 1.697-10.182 2.666-.91.243-.97.303-1.758-.606-.909-1.03-1.576-1.697-2.848-2.303-3.819-1.878-7.516-1.333-10.97.91-4.121 2.666-6.242 6.605-6.182 11.514.06 4.849 3.394 8.849 8.182 9.516 4.121.545 7.576-.91 10.303-4 .545-.667 1.03-1.394 1.636-2.243H56.064c-1.272 0-1.575-.788-1.151-1.818.788-1.879 2.242-5.03 3.09-6.606.183-.364.607-.97 1.516-.97h22.06c-.12 1.637-.12 3.273-.363 4.91-.667 4.363-2.303 8.363-4.97 11.878-4.364 5.758-10.06 9.333-17.273 10.303-5.939.788-11.454-.364-16.302-4-4.485-3.394-7.03-7.879-7.697-13.454-.788-6.606 1.151-12.546 5.151-17.758 4.303-5.636 10-9.212 16.97-10.485 5.697-1.03 11.151-.363 16.06 2.97 3.212 2.121 5.515 5.03 7.03 8.545.364.546.122.849-.606 1.03z"/><path d="M99.64 87.253c-5.515-.122-10.546-1.697-14.788-5.334-3.576-3.09-5.818-7.03-6.545-11.697-1.091-6.848.787-12.909 4.909-18.302 4.424-5.819 9.757-8.849 16.97-10.122 6.181-1.09 12-.484 17.272 3.091 4.788 3.273 7.757 7.697 8.545 13.515 1.03 8.182-1.333 14.849-6.97 20.546-4 4.06-8.909 6.606-14.545 7.757-1.636.303-3.273.364-4.848.546zm14.424-24.485c-.06-.788-.06-1.394-.182-2-1.09-6-6.606-9.394-12.363-8.06-5.637 1.272-9.273 4.848-10.606 10.545-1.091 4.727 1.212 9.515 5.575 11.454 3.334 1.455 6.667 1.273 9.879-.363 4.788-2.485 7.394-6.364 7.697-11.576z" fill-rule="nonzero"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><path fill="#463B63" d="M0 110.2L30.1 65 0 19.9h22.6L52.7 65l-30.1 45.1H0z"/><path fill="#5E5187" d="M30.1 110.2L60.2 65 30.1 19.9h22.6l60.2 90.3H90.4L71.5 81.9l-18.8 28.2H30.1z"/><path fill="#904F8C" d="M102.9 83.8l-10-15.1H128v15.1h-25.1zM87.8 61.3l-10-15.1H128v15.1H87.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 345 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#E44D26" d="M19.037 113.876L9.032 1.661h109.936l-10.016 112.198-45.019 12.48z"/><path fill="#F16529" d="M64 116.8l36.378-10.086 8.559-95.878H64z"/><path fill="#EBEBEB" d="M64 52.455H45.788L44.53 38.361H64V24.599H29.489l.33 3.692 3.382 37.927H64zm0 35.743l-.061.017-15.327-4.14-.979-10.975H33.816l1.928 21.609 28.193 7.826.063-.017z"/><path fill="#fff" d="M63.952 52.455v13.763h16.947l-1.597 17.849-15.35 4.143v14.319l28.215-7.82.207-2.325 3.234-36.233.335-3.696h-3.708zm0-27.856v13.762h33.244l.276-3.092.628-6.978.329-3.692z"/></svg>
|
||||
|
After Width: | Height: | Size: 607 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#0074BD" d="M47.617 98.12s-4.767 2.774 3.397 3.71c9.892 1.13 14.947.968 25.845-1.092 0 0 2.871 1.795 6.873 3.351-24.439 10.47-55.308-.607-36.115-5.969zm-2.988-13.665s-5.348 3.959 2.823 4.805c10.567 1.091 18.91 1.18 33.354-1.6 0 0 1.993 2.025 5.132 3.131-29.542 8.64-62.446.68-41.309-6.336z"/><path fill="#EA2D2E" d="M69.802 61.271c6.025 6.935-1.58 13.17-1.58 13.17s15.289-7.891 8.269-17.777c-6.559-9.215-11.587-13.792 15.635-29.58 0 .001-42.731 10.67-22.324 34.187z"/><path fill="#0074BD" d="M102.123 108.229s3.529 2.91-3.888 5.159c-14.102 4.272-58.706 5.56-71.094.171-4.451-1.938 3.899-4.625 6.526-5.192 2.739-.593 4.303-.485 4.303-.485-4.953-3.487-32.013 6.85-13.743 9.815 49.821 8.076 90.817-3.637 77.896-9.468zM49.912 70.294s-22.686 5.389-8.033 7.348c6.188.828 18.518.638 30.011-.326 9.39-.789 18.813-2.474 18.813-2.474s-3.308 1.419-5.704 3.053c-23.042 6.061-67.544 3.238-54.731-2.958 10.832-5.239 19.644-4.643 19.644-4.643zm40.697 22.747c23.421-12.167 12.591-23.86 5.032-22.285-1.848.385-2.677.72-2.677.72s.688-1.079 2-1.543c14.953-5.255 26.451 15.503-4.823 23.725 0-.002.359-.327.468-.617z"/><path fill="#EA2D2E" d="M76.491 1.587S89.459 14.563 64.188 34.51c-20.266 16.006-4.621 25.13-.007 35.559-11.831-10.673-20.509-20.07-14.688-28.815C58.041 28.42 81.722 22.195 76.491 1.587z"/><path fill="#0074BD" d="M52.214 126.021c22.476 1.437 57-.8 57.817-11.436 0 0-1.571 4.032-18.577 7.231-19.186 3.612-42.854 3.191-56.887.874 0 .001 2.875 2.381 17.647 3.331z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#F0DB4F" d="M1.408 1.408h125.184v125.185H1.408z"/><path fill="#323330" d="M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zM69.462 58.943H57.753l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,14 @@
|
||||
<svg viewBox="0 0 160 160" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="linearGradient8385">
|
||||
<stop offset="0"/>
|
||||
<stop stop-color="#fff" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3002" x1="-553.27" x2="-666.12" y1="525.91" y2="413.05" gradientTransform="matrix(.99884 0 0 .9987 689.01 -388.84)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8385"/>
|
||||
<linearGradient id="linearGradient3005" x1="-666.12" x2="-553.27" y1="413.04" y2="525.91" gradientTransform="matrix(.99884 0 0 .9987 689.01 -388.84)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient8385"/>
|
||||
</defs>
|
||||
<g fill-rule="evenodd">
|
||||
<path d="m79.865 119.1c35.398 48.255 70.04-13.469 69.989-50.587-0.0602-43.886-44.541-68.414-70.018-68.414-40.892 0-79.836 33.796-79.836 80.036 0 51.396 44.64 79.865 79.836 79.865-7.9645-1.1468-34.506-6.834-34.863-67.967-0.23987-41.347 13.488-57.866 34.805-50.599 0.47743 0.17707 23.514 9.2645 23.514 38.951 0 29.56-23.427 38.715-23.427 38.715z" color="#000000" fill="url(#linearGradient3005)"/>
|
||||
<path d="m79.823 41.401c-23.39-8.0619-52.043 11.216-52.043 49.829 0 63.048 46.721 68.77 52.384 68.77 40.892 0 79.836-33.796 79.836-80.036 0-51.396-44.64-79.865-79.836-79.865 9.7481-1.35 52.541 10.55 52.541 69.037 0 38.141-31.953 58.905-52.735 50.033-0.47743-0.17707-23.514-9.2645-23.514-38.951 0-29.56 23.367-38.818 23.367-38.818z" color="#000000" fill="url(#linearGradient3002)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><linearGradient id="kotlin-original-a" gradientUnits="userSpaceOnUse" x1="-11.899" y1="48.694" x2="40.299" y2="-8.322"><stop offset="0" stop-color="#1c93c1"/><stop offset=".163" stop-color="#2391c0"/><stop offset=".404" stop-color="#378bbe"/><stop offset=".696" stop-color="#587eb9"/><stop offset=".995" stop-color="#7f6cb1"/></linearGradient><path fill="url(#kotlin-original-a)" d="M0 0h65.4L0 64.4z"/><linearGradient id="kotlin-original-b" gradientUnits="userSpaceOnUse" x1="43.553" y1="149.174" x2="95.988" y2="94.876"><stop offset="0" stop-color="#1c93c1"/><stop offset=".216" stop-color="#2d8ebf"/><stop offset=".64" stop-color="#587eb9"/><stop offset=".995" stop-color="#7f6cb1"/></linearGradient><path fill="url(#kotlin-original-b)" d="M128 128L64.6 62.6 0 128z"/><linearGradient id="kotlin-original-c" gradientUnits="userSpaceOnUse" x1="3.24" y1="95.249" x2="92.481" y2="2.116"><stop offset="0" stop-color="#c757a7"/><stop offset=".046" stop-color="#ca5a9e"/><stop offset=".241" stop-color="#d66779"/><stop offset=".428" stop-color="#e17357"/><stop offset=".6" stop-color="#e97c3a"/><stop offset=".756" stop-color="#ef8324"/><stop offset=".888" stop-color="#f28817"/><stop offset=".982" stop-color="#f48912"/></linearGradient><path fill="url(#kotlin-original-c)" d="M0 128L128 0H64.6L0 63.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 82 KiB |
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="256" cy="256" r="235" fill="#fff"/>
|
||||
<path stroke="#000" stroke-width="5" d="m255.56 20.008c-62.374 0.1169-122.17 24.922-166.3 68.992-92.236 92.091-92.353 241.52-0.2617 333.75 92.09 92.236 241.52 92.353 333.75 0.262 92.236-92.091 92.353-241.52 0.262-333.75-44.377-44.447-104.64-69.371-167.45-69.254zm2.281 1.0059c59.934 0.4846 119.39 23.809 164.46 68.953 91.701 91.845 91.585 240.64-0.259 332.34-45.922 45.851-120.32 45.793-166.17-0.129-45.851-45.922-45.793-120.32 0.129-166.17 46.412-46.339 46.471-121.53 0.13-167.94-37.084-37.141-94.457-46.553-140.66-21.658 42.416-31.541 92.711-45.798 142.37-45.396zm-190.84 130.26h40c9.943 42.147 25.204 79.418 40.75 116.43 15.9-41.326 33.203-81.249 55.25-116.43h40c-48.928 97.364-102.19 164.06-24 250h-40c-47.567-77.243-82.439-147.67-112-250z"/>
|
||||
<path d="m293 110.72c78.194 85.936 24.928 152.64-24 250h40c22.047-35.179 39.35-75.102 55.25-116.43 15.546 37.01 30.807 74.282 40.75 116.43h40c-29.561-102.33-64.433-172.76-112-250z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1 @@
|
||||
<svg version="1.1" id="lua-original-Ebene_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" xml:space="preserve"><style/><path fill="navy" d="M127.3 15.1c0-7.9-6.4-14.3-14.3-14.3S98.6 7.1 98.6 15.1 105 29.4 113 29.4s14.3-6.4 14.3-14.3"/><path fill="navy" d="M64 15.1c-27 0-49 21.9-49 49s21.9 49 49 49 49-21.9 49-49-22-49-49-49zm6 28.6c0-7.9 6.4-14.3 14.3-14.3s14.3 6.4 14.3 14.3S92.2 58 84.3 58 70 51.6 70 43.7z"/><path fill="gray" d="M66.3 128l-.1-1.5c1.8-.1 3.6-.2 5.4-.4l.2 1.5c-1.8.2-3.7.3-5.5.4zm-5.6 0c-1.9-.1-3.7-.3-5.6-.5l.2-1.5c1.8.2 3.6.4 5.4.5v1.5zm16.6-1.4l-.3-1.4c1.8-.4 3.5-.8 5.3-1.4l.4 1.4c-1.7.6-3.5 1.1-5.4 1.4zm-27.7-.2c-1.8-.4-3.6-.9-5.4-1.5l.5-1.4c1.7.6 3.5 1 5.3 1.5l-.4 1.4zm38.4-3l-.6-1.4c1.7-.7 3.3-1.4 5-2.3l.7 1.3c-1.7.9-3.4 1.7-5.1 2.4zm-49-.4c-1.7-.7-3.4-1.5-5-2.4l.7-1.3c1.6.9 3.3 1.6 4.9 2.4L39 123zm59-4.7l-.8-1.2c1.5-1 3-2 4.5-3.1l.9 1.2c-1.5 1.1-3.1 2.1-4.6 3.1zm-68.8-.6c-1.6-1-3.1-2.1-4.5-3.2l.9-1.2c1.4 1.1 2.9 2.2 4.4 3.2l-.8 1.2zm77.7-6.1l-1-1.1c1.3-1.2 2.7-2.5 3.9-3.8l1.1 1c-1.3 1.3-2.7 2.6-4 3.9zm-86.5-.7c-1.4-1.3-2.7-2.6-3.9-4l1.1-1c1.2 1.3 2.5 2.7 3.8 3.9l-1 1.1zm94.1-7.5l-1.2-.9c1.1-1.4 2.2-2.9 3.2-4.4l1.2.8c-1 1.5-2.1 3.1-3.2 4.5zm-101.6-.8c-1.1-1.5-2.2-3-3.2-4.6l1.2-.8c1 1.5 2 3 3.1 4.5l-1.1.9zm107.7-8.5l-1.3-.7c.9-1.6 1.6-3.3 2.4-4.9l1.3.5-2.4 5.1zM7 93.1c-.8-1.7-1.6-3.4-2.3-5.1l1.3-.5c.7 1.7 1.4 3.3 2.3 5l-1.3.6zm117.9-9.3l-1.4-.5c.6-1.7 1-3.5 1.5-5.3l1.4.3c-.4 1.9-.9 3.7-1.5 5.5zm-122.1-1c-.5-1.8-1-3.6-1.4-5.4l1.4-.3c.4 1.8.8 3.5 1.4 5.3l-1.4.4zm124.6-9.9l-1.5-.2c.2-1.8.4-3.6.5-5.4l1.5.1c0 1.8-.2 3.7-.5 5.5zM.5 71.9C.2 70 .1 68.2 0 66.3l1.5-.1c.1 1.8.2 3.6.4 5.4l-1.4.3zm126-10.1c-.1-1.8-.2-3.6-.4-5.4l1.5-.2c.2 1.8.4 3.7.4 5.6h-1.5zm-125-1L0 60.7c.1-1.9.3-3.7.5-5.6l1.5.3c-.2 1.8-.4 3.6-.5 5.4zM125.2 51c-.4-1.8-.8-3.6-1.4-5.3l1.4-.4c.5 1.8 1 3.6 1.4 5.4l-1.4.3zM3 50l-1.4-.3c.4-1.8.9-3.6 1.5-5.4l1.4.5C3.9 46.5 3.4 48.2 3 50zm119-9.4c-.7-1.7-1.4-3.4-2.3-5l1.3-.7c.8 1.7 1.6 3.4 2.3 5.1l-1.3.6zm-115.6-1L5 39.1c.7-1.7 1.5-3.4 2.4-5l1.3.7c-.8 1.5-1.6 3.2-2.3 4.8zm5.1-9.6l-1.2-.8c1-1.6 2.1-3.1 3.2-4.5l1.2.9c-1.2 1.4-2.2 2.9-3.2 4.4zm6.7-8.6l-1.1-1c1.3-1.4 2.6-2.7 4-3.9l1 1.1c-1.4 1.2-2.7 2.5-3.9 3.8zm8.1-7.3l-.9-1.2c1.5-1.1 3-2.2 4.6-3.2l.8 1.2c-1.6 1.1-3.1 2.1-4.5 3.2zm67-5.4c-1.6-.8-3.3-1.6-4.9-2.3l.5-1.4c1.7.7 3.4 1.5 5 2.4l-.6 1.3zm-57.8-.4L34.8 7c1.7-.8 3.4-1.6 5.1-2.3l.6 1.3c-1.7.7-3.4 1.5-5 2.3zm47.7-3.8c-1.7-.6-3.5-1-5.3-1.4l.3-1.4c1.8.4 3.6.9 5.4 1.5l-.4 1.3zm-37.6-.3l-.4-1.4c1.8-.5 3.6-1 5.4-1.4l.3 1.4c-1.8.4-3.6.9-5.3 1.4zm27-2.2c-1.8-.2-3.6-.4-5.4-.5l.1-1.5c1.9.1 3.7.3 5.6.5L72.6 2zm-16.3-.1L56.1.4c1.8-.2 3.7-.4 5.6-.4l.1 1.5c-1.9 0-3.7.2-5.5.4z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><defs><linearGradient id="ocaml-original-a" gradientUnits="userSpaceOnUse" x1="82.925" y1="97.718" x2="82.925" y2="97.9" gradientTransform="translate(0 8.224) scale(.77317)"><stop offset="0" stop-color="#F29100"/><stop offset="1" stop-color="#EC670F"/></linearGradient><linearGradient id="ocaml-original-b" gradientUnits="userSpaceOnUse" x1="61.276" y1="98.981" x2="61.276" y2="144.277" gradientTransform="translate(0 8.224) scale(.77317)"><stop offset="0" stop-color="#F29100"/><stop offset="1" stop-color="#EC670F"/></linearGradient><linearGradient id="ocaml-original-c" gradientUnits="userSpaceOnUse" x1="82.781" y1="0" x2="82.781" y2="144.245" gradientTransform="translate(0 8.224) scale(.77317)"><stop offset="0" stop-color="#F29100"/><stop offset="1" stop-color="#EC670F"/></linearGradient><linearGradient id="ocaml-original-d" gradientUnits="userSpaceOnUse" x1="22.871" y1="92.114" x2="22.871" y2="143.249" gradientTransform="translate(0 8.224) scale(.77317)"><stop offset="0" stop-color="#F29100"/><stop offset="1" stop-color="#EC670F"/></linearGradient></defs><path d="M64.11 83.918l.019-.047c-.027-.117-.035-.148-.02.047zm0 0" fill="#484444"/><path d="M64.11 83.918l.019-.047c-.027-.117-.035-.148-.02.047zm0 0" fill="url(#ocaml-original-a)"/><path d="M64.969 115.441c-.45-.937-1.016-2.773-1.39-3.582-.356-.754-1.434-2.722-1.974-3.355-1.175-1.375-1.453-1.477-1.796-3.215-.602-3.023-2.192-8.508-4.067-12.293-.969-1.953-2.578-3.594-4.05-5.012-1.286-1.242-4.184-3.332-4.692-3.226-4.734.945-6.203 5.59-8.434 9.27-1.23 2.034-2.535 3.765-3.507 5.929-.899 1.992-.817 4.195-2.352 5.902-1.578 1.758-2.602 3.625-3.371 5.891-.148.43-.563 4.953-1.016 6.027l7.04-.496c6.558.45 4.663 2.965 14.902 2.414l16.164-.5c-.504-1.48-1.196-3.195-1.461-3.754zm0 0" fill="url(#ocaml-original-b)"/><path d="M111.875 8.223H16.133C7.227 8.227.008 15.445.008 24.352v35.183c2.308-.836 5.625-5.742 6.664-6.937 1.82-2.086 2.148-4.75 3.055-6.426 2.066-3.82 2.421-6.445 7.109-6.445 2.187 0 3.055.503 4.535 2.488 1.027 1.379 2.809 3.93 3.637 5.633.96 1.968 2.527 4.629 3.215 5.164.511.402 1.015.699 1.488.875.758.289 1.39-.235 1.898-.64.649-.52.93-1.571 1.532-2.977.867-2.028 1.808-4.458 2.347-5.31.93-1.464 1.246-3.202 2.25-4.046 1.485-1.242 3.414-1.328 3.95-1.434 2.976-.59 4.328 1.434 5.792 2.743.961.855 2.27 2.582 3.204 4.89.726 1.809 1.652 3.48 2.039 4.524.375 1.004 1.3 2.62 1.847 4.55.496 1.758 1.828 3.106 2.332 3.938 0 0 .774 2.168 5.48 4.152 1.02.43 3.083 1.13 4.313 1.575 2.047.746 4.028.648 6.551.347 1.797 0 2.774-2.605 3.59-4.691.484-1.23.945-4.766 1.262-5.766.304-.976-.41-1.73.199-2.586.71-1 1.133-1.054 1.543-2.355.883-2.785 5.984-2.926 8.847-2.926 2.399 0 2.086 2.32 6.141 1.527 2.32-.457 4.559.297 7.024.95 2.074.55 4.023 1.175 5.195 2.546.758.887 2.633 5.325.719 5.516.183.223.32.629.664.852-.426 1.675-2.282.48-3.309.265-1.39-.285-2.367.043-3.726.645-2.32 1.035-5.715.914-7.739 2.597-1.715 1.43-1.71 4.614-2.511 6.399 0 0-2.223 5.719-7.075 9.215-1.242.898-3.668 3.054-8.953 3.87-2.367.368-4.586.395-7.02.274l-3.511-.133c-.695-.003-3.063-.082-2.945.145l-.266.656c.043.219.129.754.152.887.098.527.125.95.145 1.437.035 1-.082 2.043-.031 3.055.105 2.094.882 4.008.98 6.121.11 2.356 1.274 4.844 2.399 6.77.43.73 1.078.812 1.363 1.715.332 1.03.02 2.129.18 3.23.632 4.266 1.855 8.73 3.785 12.582a.685.685 0 00.043.094c2.375-.395 4.754-1.25 7.84-1.707 5.652-.836 13.519-.406 18.57-.88 12.781-1.198 19.719 5.243 31.203 2.602V24.352c-.004-8.907-7.223-16.13-16.129-16.13zM64.109 83.918c-.015-.195-.007-.168.02-.047zm0 0" fill="url(#ocaml-original-c)"/><path d="M29.516 98.727c.89-1.946 1.406-4.165 2.144-6.157.711-1.906 1.817-4.61 3.7-5.57-.227-.27-3.938-.39-4.93-.492l-3.2-.453-6.164-1.27c-1.199-.289-5.187-1.703-6.054-2.101-2.032-.938-3.383-3.48-4.969-3.22-1.016.165-2.012.513-2.633 1.536-.515.836-.691 2.27-1.047 3.23-.414 1.118-1.129 2.16-1.754 3.223-1.152 1.95-3.222 3.715-4.113 5.617-.18.39-.34.828-.488 1.285v21.735l3.347.722c8.993 2.403 11.188 2.606 20.008 1.594l.828-.11c.672-1.405 1.196-6.187 1.633-7.667.34-1.137.809-2.04.988-3.2.168-1.1-.015-2.148-.113-3.152-.242-2.504 1.828-3.398 2.82-5.55zm0 0" fill="url(#ocaml-original-d)"/></svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 19 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><linearGradient id="python-original-a" gradientUnits="userSpaceOnUse" x1="70.252" y1="1237.476" x2="170.659" y2="1151.089" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#5A9FD4"/><stop offset="1" stop-color="#306998"/></linearGradient><linearGradient id="python-original-b" gradientUnits="userSpaceOnUse" x1="209.474" y1="1098.811" x2="173.62" y2="1149.537" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#FFD43B"/><stop offset="1" stop-color="#FFE873"/></linearGradient><path fill="url(#python-original-a)" d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137H29.977c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491V67.234c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548V15.833c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zM50.037 9.557c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z" transform="translate(0 10.26)"/><path fill="url(#python-original-b)" d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655H51.591c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412H63.938v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zM77.809 87.927c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z" transform="translate(0 10.26)"/><radialGradient id="python-original-c" cx="1825.678" cy="444.45" r="26.743" gradientTransform="matrix(0 -.24 -1.055 0 532.979 557.576)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#B8B8B8" stop-opacity=".498"/><stop offset="1" stop-color="#7F7F7F" stop-opacity="0"/></radialGradient><path opacity=".444" fill="url(#python-original-c)" d="M97.309 119.597c0 3.543-14.816 6.416-33.091 6.416-18.276 0-33.092-2.873-33.092-6.416 0-3.544 14.815-6.417 33.092-6.417 18.275 0 33.091 2.872 33.091 6.417z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1 @@
|
||||
<svg preserveAspectRatio="xMidYMid" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="r-original-a" x1=".741" x2="590.86" y1="3.666" y2="593.79" gradientTransform="matrix(.2169 0 0 .14527 -.16 14.112)" gradientUnits="userSpaceOnUse"><stop stop-color="#cbced0" offset="0"/><stop stop-color="#84838b" offset="1"/></linearGradient><linearGradient id="r-original-b" x1="301.03" x2="703.07" y1="151.4" y2="553.44" gradientTransform="matrix(.17572 0 0 .17931 -.16 14.112)" gradientUnits="userSpaceOnUse"><stop stop-color="#276dc3" offset="0"/><stop stop-color="#165caa" offset="1"/></linearGradient></defs><path d="M64 100.38c-35.346 0-64-19.19-64-42.863 0-23.672 28.654-42.863 64-42.863s64 19.19 64 42.863c0 23.672-28.654 42.863-64 42.863zm9.796-68.967c-26.866 0-48.646 13.119-48.646 29.303 0 16.183 21.78 29.303 48.646 29.303s46.693-8.97 46.693-29.303c0-20.327-19.827-29.303-46.693-29.303z" fill="url(#r-original-a)" fill-rule="evenodd"/><path d="M97.469 81.033s3.874 1.169 6.124 2.308c.78.395 2.132 1.183 3.106 2.219a8.388 8.388 0 011.42 2.04l15.266 25.74-24.674.01-11.537-21.666s-2.363-4.06-3.817-5.237c-1.213-.982-1.73-1.331-2.929-1.331h-5.862l.004 28.219-21.833.009V41.26h43.844s19.97.36 19.97 19.359c0 18.999-19.082 20.413-19.082 20.413zm-9.497-24.137l-13.218-.009-.006 12.258 13.224-.005s6.124-.019 6.124-6.235c0-6.34-6.124-6.009-6.124-6.009z" fill="url(#r-original-b)" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
@ -0,0 +1 @@
|
||||
<svg version="1.0" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"><path d="M25 110.437V94.874h5.616c3.113 0 8.052-.203 11.03-.474l5.278-.406-7.038-1.894c-3.924-1.015-8.864-2.504-10.961-3.316L25 87.364V55.627h6.293c3.383 0 8.323-.203 10.894-.473l4.737-.406-8.323-2.233C34 51.366 29.128 49.809 27.639 49.2L25 47.982v-30.72l2.098-.473c1.15-.203 3.992-.406 6.293-.406 11.367 0 38.366-3.722 51.628-7.105 9.27-2.436 15.698-4.872 17.931-6.902 1.15-1.015 1.218-.406 1.218 14.548v15.63l-1.624 1.219-1.624 1.285 3.248 2.842v33.9l-1.624 1.218-1.624 1.286 3.248 2.842v33.9l-1.76 1.353c-1.894 1.489-9.202 3.993-17.524 6.09C71.892 121.737 40.157 126 29.33 126H25z" fill="#390d09"/><g fill="#de3423"><path d="M25 110.572V95.077l11.842-.474c12.315-.473 21.45-1.488 34.847-3.789 15.225-2.639 30.246-7.375 31.803-10.082.406-.677.676 4.534.676 14.616v15.698l-1.76 1.353c-1.894 1.489-9.202 3.993-17.524 6.09C71.892 121.737 40.157 126 29.33 126H25zM25 71.327V55.83l11.842-.406c13.127-.541 23.344-1.691 36.877-4.195 15.157-2.842 28.96-7.443 29.976-9.947.203-.473.406 6.09.406 14.616.067 13.533-.068 15.698-1.083 16.78-2.368 2.64-20.638 7.376-39.449 10.286-11.435 1.76-30.381 3.79-35.66 3.79H25zM25 32.352V17.195l2.098-.406c1.15-.203 3.992-.406 6.293-.406 11.367 0 38.366-3.722 51.628-7.105 9.27-2.436 15.698-4.872 17.931-6.902 1.15-1.015 1.218-.406 1.218 14.48 0 14.548-.067 15.63-1.285 16.714-1.827 1.691-14.345 5.548-24.09 7.51-15.765 3.113-41.951 6.429-50.883 6.429H25z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill="#fff" d="M22.67 47h99.67v73.67H22.67z"/><path data-name="original" fill="#007acc" d="M1.5 63.91v62.5h125v-125H1.5zm100.73-5a15.56 15.56 0 017.82 4.5 20.58 20.58 0 013 4c0 .16-5.4 3.81-8.69 5.85-.12.08-.6-.44-1.13-1.23a7.09 7.09 0 00-5.87-3.53c-3.79-.26-6.23 1.73-6.21 5a4.58 4.58 0 00.54 2.34c.83 1.73 2.38 2.76 7.24 4.86 8.95 3.85 12.78 6.39 15.16 10 2.66 4 3.25 10.46 1.45 15.24-2 5.2-6.9 8.73-13.83 9.9a38.32 38.32 0 01-9.52-.1 23 23 0 01-12.72-6.63c-1.15-1.27-3.39-4.58-3.25-4.82a9.34 9.34 0 011.15-.73L82 101l3.59-2.08.75 1.11a16.78 16.78 0 004.74 4.54c4 2.1 9.46 1.81 12.16-.62a5.43 5.43 0 00.69-6.92c-1-1.39-3-2.56-8.59-5-6.45-2.78-9.23-4.5-11.77-7.24a16.48 16.48 0 01-3.43-6.25 25 25 0 01-.22-8c1.33-6.23 6-10.58 12.82-11.87a31.66 31.66 0 019.49.26zm-29.34 5.24v5.12H56.66v46.23H45.15V69.26H28.88v-5a49.19 49.19 0 01.12-5.17C29.08 59 39 59 51 59h21.83z"/></svg>
|
||||
|
After Width: | Height: | Size: 943 B |
|
After Width: | Height: | Size: 40 KiB |
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 470.647">
|
||||
<polygon id="Y" points="235.793 0 143.978 137.674 143.978 224.949 87.702 224.949 87.702 137.674 0 0 63.25 0 119.018 88.646 175.243 0 235.793 0 235.793 0"/>
|
||||
<path id="A" fill="#cb171e" d="M330.294,175.451h-101.861l-20.717,50.024h-45.106l95.38,-224.949h46.137l91.51,224.949h-48.2l-17.144,-50.024zm-16.92,-44.911l-31.226,-82.55l-34.837,82.55h66.063z"/>
|
||||
<polygon id="M" points="87.701 250.177 87.701 470.647 135.004 470.647 135.004 318.569 184.509 420.789 221.743 420.789 272.939 314.976 272.939 470.602 318.318 470.602 318.318 250.177 256.358 250.177 201.381 349.883 149.021 250.177 87.701 250.177 87.701 250.177"/>
|
||||
<polygon id="L" points="512 422.735 395.638 422.735 395.638 250.125 347.442 250.125 347.442 469.647 512 469.647 512 422.737 512 422.735"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 872 B |
@ -0,0 +1,242 @@
|
||||
{"version": 2, "width": 133, "height": 24, "timestamp": 1648331634, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}}
|
||||
[0.058188, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[0.059315, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[0.059474, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[2.5995, "o", "# Difftastic is a tool for comparing files based on syntax."]
|
||||
[3.226385, "o", "\u001b[?2004l\r\r\n"]
|
||||
[3.226734, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[3.227569, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[3.227785, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[6.365599, "o", "# You can give it two paths to compare, just like diff."]
|
||||
[7.648592, "o", "\u001b[?2004l\r\r\n"]
|
||||
[7.648843, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[7.649941, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[7.650048, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[10.137345, "o", "d"]
|
||||
[10.257334, "o", "\bdi"]
|
||||
[10.334579, "o", "f"]
|
||||
[10.483799, "o", "f"]
|
||||
[10.67091, "o", "t"]
|
||||
[10.736178, "o", " "]
|
||||
[10.924637, "o", "s"]
|
||||
[10.987535, "o", "a"]
|
||||
[11.092373, "o", "m"]
|
||||
[11.283115, "o", "ple_files\u001b[1m/\u001b[0m"]
|
||||
[11.689602, "o", "\b\u001b[0m/c"]
|
||||
[11.794798, "o", "l"]
|
||||
[11.950613, "o", "o"]
|
||||
[12.096605, "o", "jure_"]
|
||||
[12.435091, "o", "b"]
|
||||
[12.515293, "o", "efore.clj\u001b[1m \u001b[0m"]
|
||||
[13.113687, "o", "\b\u001b[0m s"]
|
||||
[13.199507, "o", "a"]
|
||||
[13.351514, "o", "m"]
|
||||
[13.494273, "o", "ple_files\u001b[1m/\u001b[0m"]
|
||||
[13.867224, "o", "\b\u001b[0m/c"]
|
||||
[13.956386, "o", "l"]
|
||||
[14.158282, "o", "o"]
|
||||
[14.260931, "o", "jure_"]
|
||||
[14.575625, "o", "a"]
|
||||
[14.794025, "o", "fter.clj\u001b[1m \u001b[0m"]
|
||||
[15.340386, "o", "\b\u001b[0m \b\u001b[?2004l\r\r\n"]
|
||||
[15.344656, "o", "\u001b[1m\u001b[93msample_files/clojure_after.clj\u001b[39m\u001b[0m --- 1/1 --- Clojure\r\n1 \u001b[94;3m;; Example from Autochrome, under EPL-1.0 license.\u001b[0m 1 \u001b[94;3m;; Example from Autochrome, under EPL-1.0 license.\u001b[0m \r\n2 (defn example 2 (defn example \r\n3 [x] 3 [x] \r\n\u001b[91m4 \u001b[39m \u001b[91;1m(\u001b[0m\u001b[91mprintln\u001b[0m \u001b[91m\"hello!\"\u001b[0m\u001b[91;1m)\u001b[0m \u001b[2m. \u001b[0m\r\n5 {\u001b[1m:more\u001b[0m (inc x) \u001b[92m4 \u001b[39m \u001b[92;1m(\u001b[0m\u001b[92m->\u001b[0m {\u001b[1m:more\u001b[0m (inc x) \r\n6 \u001b[1m:less\u001b[0m (dec x)}) 5 \u001b[1m:less\u001b[0m (dec x)} \r\n\u001b[2m \u001b[0m "]
|
||||
[15.34478, "o", " \u001b[92m6 \u001b[39m \u001b[92;1m(\u001b[0m\u001b[92massoc\u001b[0m \u001b[92;1m:twice\u001b[0m \u001b[92;1m(\u001b[0m\u001b[92m+\u001b[0m \u001b[92mx\u001b[0m \u001b[92mx\u001b[0m\u001b[92;1m)\u001b[0m\u001b[92;1m)\u001b[0m\u001b[92;1m)\u001b[0m) \r\n\r\n"]
|
||||
[15.345119, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[15.346128, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[15.346218, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[20.072257, "o", "# Difftastic has support for git too! Let's look at some recent commits."]
|
||||
[20.908263, "o", "\u001b[?2004l\r\r\n"]
|
||||
[20.908512, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[20.909869, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[20.910001, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[25.174718, "o", "GIT_EXTERNAL_DIFF=difft git log -p --ext-diff"]
|
||||
[27.066311, "o", "\u001b[?2004l\r\r\n"]
|
||||
[27.073778, "o", "\u001b[?1h\u001b=\r"]
|
||||
[27.073956, "o", "\u001b[33mcommit 905fc9ec8be333bee05595091207d30d69ec14b9\u001b[m\u001b[33m (\u001b[m\u001b[1;36mHEAD\u001b[m\u001b[33m)\u001b[m\u001b[m\r\nAuthor: Wilfred Hughes <me@wilfred.me.uk>\u001b[m\r\nDate: Sun Mar 20 22:24:21 2022 -0700\u001b[m\r\n\u001b[m\r\n Ignore the trailing newline in source files\u001b[m\r\n \u001b[m\r\n This should have produced a change in output, but it's currently\u001b[m\r\n ignored due to #163.\u001b[m\r\n\u001b[m\r\n"]
|
||||
[27.118907, "o", "\u001b[1m\u001b[93msrc/main.rs\u001b[39m\u001b[0m --- 1/1 --- Rust\u001b[m\r\n"]
|
||||
[27.119099, "o", "215 215 }\u001b[m\r\n216 216 \u001b[m\r\n217 217 \u001b[94;3m// TODO: don't replace tab characters inside string literals.\u001b[0m\u001b[m\r\n218 \u001b[92m218 \u001b[39m \u001b[1mlet\u001b[0m \u001b[92;1mmut\u001b[0m lhs_src = \u001b[1mString\u001b[0m::from_utf8_lossy(lhs_bytes)\u001b[m\r\n219 219 .to_string()\u001b[m\r\n220 220 .replace(\u001b[95m'\\t'\u001b[0m, \u001b[95m\" \"\u001b[0m);\u001b[m\r\n221 \u001b[92m221 \u001b[39m \u001b[1mlet\u001b[0m \u001b[92;1mmut\u001b[0m rhs_src = \u001b[1mString\u001b[0m::from_utf8_lossy(rhs_bytes)\u001b[m\r\n222 222 .to_string()\u001b[m\r\n223 223 .replace(\u001b[95m'\\t'\u001b[0m, \u001b[95m\" \"\u001b[0m);\u001b[m\r\n\u001b[2m... \u001b[0m\u001b[92m224 \u001b[39m\u001b[m\r\n\u001b[2m... \u001b[0m\u001b[92m225 \u001b[39m \u001b[92;3m// Ignore the trailing newline, if present.\u001b[0m\u001b[m\r\n\u001b[2m... \u001b[0m\u001b[92m226 \u001b[39m \u001b[92;3m// TODO: highlight if this has changes (#144).\u001b[0m\u001b[m\r\n\u001b[2m... \u001b[0m\u001b[92m227 \u001b[39m \u001b[92;3m// TODO: factor out a string cleaning function.\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[28.741062, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m... \u001b[0m\u001b[92m228 \u001b[39m \u001b[92;1mif\u001b[0m \u001b[92mlhs_src\u001b[0m\u001b[92m.\u001b[0m\u001b[92mends_with\u001b[0m\u001b[92;1m(\u001b[0m\u001b[92m'\\n'\u001b[0m\u001b[92;1m)\u001b[0m \u001b[92;1m{\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[29.058528, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m... \u001b[0m\u001b[92m229 \u001b[39m \u001b[92mlhs_src\u001b[0m\u001b[92m.\u001b[0m\u001b[92mpop\u001b[0m\u001b[92;1m(\u001b[0m\u001b[92;1m)\u001b[0m\u001b[92m;\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[29.36318, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m... \u001b[0m\u001b[92m230 \u001b[39m \u001b[92;1m}\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[29.610836, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m... \u001b[0m\u001b[92m231 \u001b[39m \u001b[92;1mif\u001b[0m \u001b[92mrhs_src\u001b[0m\u001b[92m.\u001b[0m\u001b[92mends_with\u001b[0m\u001b[92;1m(\u001b[0m\u001b[92m'\\n'\u001b[0m\u001b[92;1m)\u001b[0m \u001b[92;1m{\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[29.822642, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m... \u001b[0m\u001b[92m232 \u001b[39m \u001b[92mrhs_src\u001b[0m\u001b[92m.\u001b[0m\u001b[92mpop\u001b[0m\u001b[92;1m(\u001b[0m\u001b[92;1m)\u001b[0m\u001b[92m;\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[30.079355, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[30.079516, "o", "\u001b[2m... \u001b[0m\u001b[92m233 \u001b[39m \u001b[92;1m}\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[30.350258, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K224 234 \u001b[m\r\n:\u001b[K"]
|
||||
[30.60035, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[30.60053, "o", "225 235 \u001b[94;3m// TODO: take a Path directly instead.\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[30.834164, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K226 236 \u001b[1mlet\u001b[0m path = \u001b[1mPath\u001b[0m::new(\u001b[1m&\u001b[0mdisplay_path);\u001b[m\r\n:\u001b[K"]
|
||||
[31.07936, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[31.313919, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[31.547364, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[31.547527, "o", "\u001b[33mcommit c7795111f5767e54205dda13f82c97b2ef5743a1\u001b[m\u001b[m\r\n:\u001b[K"]
|
||||
[31.795514, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[31.795633, "o", "Author: Wilfred Hughes <me@wilfred.me.uk>\u001b[m\r\n:\u001b[K"]
|
||||
[32.057382, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[32.057519, "o", "Date: Sun Mar 20 21:30:17 2022 -0700\u001b[m\r\n:\u001b[K"]
|
||||
[32.309801, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[32.5347, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K cargo fmt\u001b[m\r\n:\u001b[K"]
|
||||
[32.783008, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[33.00581, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[1m\u001b[93msrc/hunks.rs\u001b[39m\u001b[0m --- 1/1 --- Rust\u001b[m\r\n:\u001b[K"]
|
||||
[33.255364, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[33.255475, "o", "No syntactic changes.\u001b[m\r\n:\u001b[K"]
|
||||
[33.491872, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[33.735072, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[33.977973, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[33mcommit 68f3ab2b9243fbbefdb2a5f68a531754cae4c4f7\u001b[m\u001b[m\r\n:\u001b[K"]
|
||||
[34.225023, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[KAuthor: Wilfred Hughes <me@wilfred.me.uk>\u001b[m\r\n:\u001b[K"]
|
||||
[34.466161, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[34.466259, "o", "Date: Sun Mar 20 19:48:14 2022 -0700\u001b[m\r\n:\u001b[K"]
|
||||
[34.698357, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[34.941211, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[34.941426, "o", " Don't consider lines with whitespace to have missing syntax\u001b[m\r\n:\u001b[K"]
|
||||
[35.174346, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[35.174501, "o", " \u001b[m\r\n:\u001b[K"]
|
||||
[35.444257, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[35.444401, "o", " Fixes #171\u001b[m\r\n:\u001b[K"]
|
||||
[35.688874, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[35.928177, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[1m\u001b[93mCHANGELOG.md\u001b[39m\u001b[0m --- 1/1 --- Text\u001b[m\r\n:\u001b[K"]
|
||||
[36.159364, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[36.159518, "o", " 6 6 certain circumstances when a line contained both changed and unchanged\u001b[m\r\n:\u001b[K"]
|
||||
[36.389208, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K 7 7 parts.\u001b[m\r\n:\u001b[K"]
|
||||
[36.596542, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K 8 8 \u001b[m\r\n:\u001b[K"]
|
||||
[36.817159, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[36.817259, "o", "\u001b[2m . \u001b[0m\u001b[92m 9 \u001b[39m\u001b[92;1mFixed\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1man\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1missue\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mwhere\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mlines\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mcontaining\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1monly\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mwhitespace\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mwould\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mbe\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[37.046838, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m . \u001b[0m\u001b[92m10 \u001b[39m\u001b[92;1mhighlighted\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1min\u001b[0m\u001b[92;1m \u001b[0m\u001b[92;1mpurple\u001b[0m\u001b[92;1m.\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[37.31998, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m . \u001b[0m\u001b[92m11 \u001b[39m\u001b[m\r\n:\u001b[K"]
|
||||
[37.551033, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K 9 12 ### Parsing\u001b[m\r\n:\u001b[K"]
|
||||
[37.80635, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K10 13 \u001b[m\r\n:\u001b[K"]
|
||||
[38.029595, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[38.264066, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[1m\u001b[93msrc/style.rs\u001b[39m\u001b[0m --- 1/1 --- Rust\u001b[m\r\n:\u001b[K"]
|
||||
[38.504341, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[38.504471, "o", "83 use_color: \u001b[1mbool\u001b[0m,\u001b[m\r\n:\u001b[K"]
|
||||
[38.735321, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K84 styles: \u001b[1m&\u001b[0m[(\u001b[1mSingleLineSpan\u001b[0m, \u001b[1mStyle\u001b[0m)],\u001b[m\r\n:\u001b[K"]
|
||||
[38.962007, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K85 ) -> \u001b[1mVec\u001b[0m<\u001b[1mString\u001b[0m> {\u001b[m\r\n:\u001b[K"]
|
||||
[39.208804, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[92m86 \u001b[39m \u001b[1mif\u001b[0m styles.is_empty() && !line\u001b[92m.\u001b[0m\u001b[92mtrim\u001b[0m\u001b[92;1m(\u001b[0m\u001b[92;1m)\u001b[0m.is_empty() {\u001b[m\r\n:\u001b[K"]
|
||||
[39.455321, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K87 \u001b[94;3m// Missing styles is a bug, so highlight in purple to make this obvious.\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[39.719675, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[39.719789, "o", "88 \u001b[1mreturn\u001b[0m split_string_by_codepoint(line, max_len)\u001b[m\r\n:\u001b[K"]
|
||||
[40.000366, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[40.000537, "o", "89 .into_iter()\u001b[m\r\n:\u001b[K"]
|
||||
[40.263044, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[40.532331, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[40.799186, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[40.799289, "o", "\u001b[33mcommit 4563648a9fba93356e9df6be842023ca1c4fb2f4\u001b[m\u001b[m\r\n:\u001b[K"]
|
||||
[41.05339, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[41.053535, "o", "Author: Wilfred Hughes <me@wilfred.me.uk>\u001b[m\r\n:\u001b[K"]
|
||||
[41.30637, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[41.306496, "o", "Date: Sun Mar 20 15:17:32 2022 -0700\u001b[m\r\n:\u001b[K"]
|
||||
[41.59527, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[41.874913, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K Clarify ChangeKind helper method name\u001b[m\r\n:\u001b[K"]
|
||||
[42.123997, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[42.406332, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[42.40648, "o", "\u001b[1m\u001b[93msrc/hunks.rs\u001b[39m\u001b[0m --- 1/2 --- Rust\u001b[m\r\n:\u001b[K"]
|
||||
[42.673176, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K467 \u001b[1mloop\u001b[0m { 467 \u001b[1mloop\u001b[0m { \u001b[m\r\n:\u001b[K"]
|
||||
[42.936558, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[42.936738, "o", "468 \u001b[1mmatch\u001b[0m (lhs_iter.peek(), rhs_iter.peek()) { 468 \u001b[1mmatch\u001b[0m (lhs_iter.peek(), rhs_iter.peek()) { \u001b[m\r\n:\u001b[K"]
|
||||
[43.187389, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[43.187461, "o", "469 (Some(lhs_mp), Some(rhs_mp)) 469 (Some(lhs_mp), Some(rhs_mp)) \u001b[m\r\n:\u001b[K"]
|
||||
[43.439206, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[91m470 \u001b[39m \u001b[1mif\u001b[0m !lhs_mp.kind.\u001b[91mis_change\u001b[0m() && !rhs_mp.kind.\u001b[91mis\u001b[0m \u001b[92m470 \u001b[39m \u001b[1mif\u001b[0m !lhs_mp.kind.\u001b[92mis_novel\u001b[0m() && !rhs_mp.kind.\u001b[92mis_\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[43.756317, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[43.756474, "o", "\u001b[91m\u001b[2m... \u001b[0m\u001b[39m\u001b[91m_change\u001b[0m() => \u001b[92m\u001b[2m... \u001b[0m\u001b[39m\u001b[92mnovel\u001b[0m() => \u001b[m\r\n:\u001b[K"]
|
||||
[44.023372, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[44.023425, "o", "471 { 471 { \u001b[m\r\n:\u001b[K"]
|
||||
[44.289699, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[44.289782, "o", "472 res.append(\u001b[1m&\u001b[0m\u001b[1mmut\u001b[0m novel_section_in_order( 472 res.append(\u001b[1m&\u001b[0m\u001b[1mmut\u001b[0m novel_section_in_order( \u001b[m\r\n:\u001b[K"]
|
||||
[44.560326, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[44.560452, "o", "473 \u001b[1m&\u001b[0mlhs_section, 473 \u001b[1m&\u001b[0mlhs_section, \u001b[m\r\n:\u001b[K"]
|
||||
[44.813655, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[44.813687, "o", "\u001b[m\r\n:\u001b[K"]
|
||||
[45.078314, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[1m\u001b[93msrc/hunks.rs\u001b[39m\u001b[0m --- 2/2 --- Rust\u001b[m\r\n:\u001b[K"]
|
||||
[45.34377, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K485 lhs_iter.next(); 485 lhs_iter.next(); \u001b[m\r\n:\u001b[K"]
|
||||
[45.734703, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K486 rhs_iter.next(); 486 rhs_iter.next(); \u001b[m\r\n:\u001b[K"]
|
||||
[45.978713, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[45.978757, "o", "487 } 487 } \u001b[m\r\n:\u001b[K"]
|
||||
[46.300028, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[91m488 \u001b[39m (Some(lhs_mp), _) \u001b[1mif\u001b[0m lhs_mp.kind.\u001b[91mis_change\u001b[0m() => { \u001b[92m488 \u001b[39m (Some(lhs_mp), _) \u001b[1mif\u001b[0m lhs_mp.kind.\u001b[92mis_novel\u001b[0m() => { \u001b[m\r\n:\u001b[K"]
|
||||
[46.584687, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[46.584758, "o", "489 lhs_section.push(lhs_mp); 489 lhs_section.push(lhs_mp); \u001b[m\r\n:\u001b[K"]
|
||||
[46.920832, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[46.920879, "o", "490 lhs_iter.next(); 490 lhs_iter.next(); \u001b[m\r\n:\u001b[K"]
|
||||
[47.192163, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K491 } 491 } \u001b[m\r\n:\u001b[K"]
|
||||
[47.505025, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[91m492 \u001b[39m (_, Some(rhs_mp)) \u001b[1mif\u001b[0m rhs_mp.kind.\u001b[91mis_change\u001b[0m() => { \u001b[92m492 \u001b[39m (_, Some(rhs_mp)) \u001b[1mif\u001b[0m rhs_mp.kind.\u001b[92mis_novel\u001b[0m() => { \u001b[m\r\n:\u001b[K"]
|
||||
[47.947911, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K493 rhs_section.push(rhs_mp); 493 rhs_section.push(rhs_mp); \u001b[m\r\n:\u001b[K"]
|
||||
[48.219369, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[48.219504, "o", "494 rhs_iter.next(); 494 rhs_iter.next(); \u001b[m\r\n:\u001b[K"]
|
||||
[48.511357, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K495 } 495 } \u001b[m\r\n:\u001b[K"]
|
||||
[48.811117, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[49.116431, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[49.116552, "o", "\u001b[1m\u001b[93msrc/line_parser.rs\u001b[39m\u001b[0m --- 1/2 --- Rust\u001b[m\r\n:\u001b[K"]
|
||||
[49.900367, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[49.900419, "o", "257 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\"\u001b[0m, \u001b[95m\"foo\"\u001b[0m); 257 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\"\u001b[0m, \u001b[95m\"foo\"\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[50.151024, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K258 258 \u001b[m\r\n:\u001b[K"]
|
||||
[50.418958, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K259 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); 259 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[50.776112, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[91m260 \u001b[39m assert!(!positions[\u001b[1m0\u001b[0m].kind.\u001b[91mis_change\u001b[0m()); \u001b[92m260 \u001b[39m assert!(!positions[\u001b[1m0\u001b[0m].kind.\u001b[92mis_novel\u001b[0m()); \u001b[m\r\n:\u001b[K"]
|
||||
[51.087847, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K261 } 261 } \u001b[m\r\n:\u001b[K"]
|
||||
[51.368352, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[51.368527, "o", "262 262 \u001b[m\r\n:\u001b[K"]
|
||||
[51.846789, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K263 #[test] 263 #[test] \u001b[m\r\n:\u001b[K"]
|
||||
[52.220319, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[52.220412, "o", "\u001b[m\r\n:\u001b[K"]
|
||||
[52.529333, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[52.529464, "o", "\u001b[1m\u001b[93msrc/line_parser.rs\u001b[39m\u001b[0m --- 2/2 --- Rust\u001b[m\r\n:\u001b[K"]
|
||||
[53.277786, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[53.277922, "o", "266 \u001b[94;3m// be treated as a change. We're doing a line-based di\u001b[0m 266 \u001b[94;3m// be treated as a change. We're doing a line-based di\u001b[0m\u001b[m\r\n:\u001b[K"]
|
||||
[53.580018, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[2m... \u001b[0m\u001b[94;3mff and\u001b[0m \u001b[2m... \u001b[0m\u001b[94;3mff and\u001b[0m \u001b[m\r\n:\u001b[K"]
|
||||
[53.86212, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[53.86232, "o", "267 \u001b[94;3m// the lines are different.\u001b[0m 267 \u001b[94;3m// the lines are different.\u001b[0m \u001b[m\r\n:\u001b[K"]
|
||||
[54.144105, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[54.144228, "o", "268 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\"\u001b[0m, \u001b[95m\" foo\"\u001b[0m); 268 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\"\u001b[0m, \u001b[95m\" foo\"\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[54.424201, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[91m269 \u001b[39m assert!(positions[\u001b[1m0\u001b[0m].kind.\u001b[91mis_change\u001b[0m()); \u001b[92m269 \u001b[39m assert!(positions[\u001b[1m0\u001b[0m].kind.\u001b[92mis_novel\u001b[0m()); \u001b[m\r\n:\u001b[K"]
|
||||
[54.721199, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K270 } 270 } \u001b[m\r\n:\u001b[K"]
|
||||
[55.5252, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K271 271 \u001b[m\r\n:\u001b[K"]
|
||||
[55.808335, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[55.808517, "o", "272 #[test] 272 #[test] \u001b[m\r\n:\u001b[K"]
|
||||
[56.134264, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[56.134383, "o", "273 \u001b[1mfn\u001b[0m test_no_changes_trailing_newlines() { 273 \u001b[1mfn\u001b[0m test_no_changes_trailing_newlines() { \u001b[m\r\n:\u001b[K"]
|
||||
[56.488093, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K274 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\\n\"\u001b[0m, \u001b[95m\"foo\\n\"\u001b[0m); 274 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\\n\"\u001b[0m, \u001b[95m\"foo\\n\"\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[56.771359, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[56.771495, "o", "275 275 \u001b[m\r\n:\u001b[K"]
|
||||
[57.0932, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[57.09332, "o", "276 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); 276 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[57.380651, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[57.380791, "o", "\u001b[91m277 \u001b[39m assert!(!positions[\u001b[1m0\u001b[0m].kind.\u001b[91mis_change\u001b[0m()); \u001b[92m277 \u001b[39m assert!(!positions[\u001b[1m0\u001b[0m].kind.\u001b[92mis_novel\u001b[0m()); \u001b[m\r\n:\u001b[K"]
|
||||
[57.676578, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K278 } 278 } \u001b[m\r\n:\u001b[K"]
|
||||
[57.991349, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[57.991482, "o", "279 279 \u001b[m\r\n:\u001b[K"]
|
||||
[58.252298, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K280 #[test] 280 #[test] \u001b[m\r\n:\u001b[K"]
|
||||
[58.575488, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K281 \u001b[1mfn\u001b[0m test_novel_lhs_trailing_newlines() { 281 \u001b[1mfn\u001b[0m test_novel_lhs_trailing_newlines() { \u001b[m\r\n:\u001b[K"]
|
||||
[58.817923, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[58.818047, "o", "282 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\\n\"\u001b[0m, \u001b[95m\"\"\u001b[0m); 282 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\\n\"\u001b[0m, \u001b[95m\"\"\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[59.083857, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K283 283 \u001b[m\r\n:\u001b[K"]
|
||||
[59.373054, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K284 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); 284 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[59.651963, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[91m285 \u001b[39m assert!(positions[\u001b[1m0\u001b[0m].kind.\u001b[91mis_change\u001b[0m()); \u001b[92m285 \u001b[39m assert!(positions[\u001b[1m0\u001b[0m].kind.\u001b[92mis_novel\u001b[0m()); \u001b[m\r\n:\u001b[K"]
|
||||
[59.890377, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[59.890501, "o", "286 } 286 } \u001b[m\r\n:\u001b[K"]
|
||||
[60.155924, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K287 287 \u001b[m\r\n:\u001b[K"]
|
||||
[60.399366, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[60.399523, "o", "288 #[test] 288 #[test] \u001b[m\r\n:\u001b[K"]
|
||||
[60.648342, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[60.648484, "o", "289 \u001b[1mfn\u001b[0m test_positions_novel_lhs() { 289 \u001b[1mfn\u001b[0m test_positions_novel_lhs() { \u001b[m\r\n:\u001b[K"]
|
||||
[60.914846, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K290 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\"\u001b[0m, \u001b[95m\"\"\u001b[0m); 290 \u001b[1mlet\u001b[0m positions = change_positions(\u001b[95m\"foo\"\u001b[0m, \u001b[95m\"\"\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[61.196992, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[61.197123, "o", "291 291 \u001b[m\r\n:\u001b[K"]
|
||||
[61.43917, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K292 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); 292 assert_eq!(positions.len(), \u001b[1m1\u001b[0m); \u001b[m\r\n:\u001b[K"]
|
||||
[61.678722, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[61.678806, "o", "\u001b[91m293 \u001b[39m assert!(positions[\u001b[1m0\u001b[0m].kind.\u001b[91mis_change\u001b[0m()); \u001b[92m293 \u001b[39m assert!(positions[\u001b[1m0\u001b[0m].kind.\u001b[92mis_novel\u001b[0m()); \u001b[m\r\n:\u001b[K"]
|
||||
[61.934891, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[61.935035, "o", "294 } 294 } \u001b[m\r\n:\u001b[K"]
|
||||
[62.191021, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K295 } 295 } \u001b[m\r\n:\u001b[K"]
|
||||
[62.428708, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K\u001b[m\r\n:\u001b[K"]
|
||||
[62.670875, "o", "\r\u001b[K \u001b[KESC\b\b\bESC\u001b[KO\bO\u001b[KB\bB\r\u001b[K"]
|
||||
[63.441112, "o", "\r\u001b[K\u001b[?1l\u001b>"]
|
||||
[63.443863, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[63.444894, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[63.444993, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[67.143027, "o", "# Want to learn more? Check out the GitHub repository for installation instructions:"]
|
||||
[67.375589, "o", "\u001b[?2004l\r\r\n"]
|
||||
[67.376115, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[67.376986, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
[67.377235, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J$ \u001b[K\u001b[?2004h"]
|
||||
[70.297425, "o", "# https://github.com/wilfred/difftastic"]
|
||||
[70.673514, "o", "\u001b[?2004l\r\r\n"]
|
||||
[70.673731, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
|
||||
[70.675, "o", "\u001b]7;file:///home/wilfred/projects/difftastic\u001b\\"]
|
||||
@ -0,0 +1,88 @@
|
||||
body {
|
||||
animation: 2s ease-out 0s 1 FadeIn;
|
||||
}
|
||||
@keyframes FadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
--bs-body-font-size: 18px;
|
||||
--bs-border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: "Fontdiner Swanky", serif;
|
||||
text-shadow: 5px 5px #1d1b22;
|
||||
}
|
||||
|
||||
h3 {
|
||||
line-height: 45px;
|
||||
}
|
||||
|
||||
/* Constrain container width even more than container-sm.
|
||||
https://getbootstrap.com/docs/5.3/layout/containers/#how-they-work */
|
||||
@media (min-width: 992px) {
|
||||
.container-sm {
|
||||
max-width: 960px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
background-color: #2e3436;
|
||||
}
|
||||
|
||||
/* Colours from Tango theme */
|
||||
.red,
|
||||
code {
|
||||
color: #ef2929;
|
||||
}
|
||||
.green,
|
||||
a {
|
||||
color: #8ae234;
|
||||
}
|
||||
|
||||
.img-wrapper {
|
||||
width: atuo;
|
||||
border: var(--bs-card-border-width) solid var(--bs-card-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
background-color: #2e3436;
|
||||
}
|
||||
.img-wrapper img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.card-body object {
|
||||
background-color: #f8f8f2;
|
||||
border-radius: 25% 25%;
|
||||
padding: 5px;
|
||||
box-shadow: 5px 5px #a09fa2;
|
||||
}
|
||||
|
||||
.github-logo {
|
||||
margin-right: 5px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.card-set .card {
|
||||
border-radius: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.card-set .card:first-child {
|
||||
border-top-right-radius: var(--bs-card-border-radius);
|
||||
border-top-left-radius: var(--bs-card-border-radius);
|
||||
}
|
||||
.card-set .card:last-child {
|
||||
border-bottom-right-radius: var(--bs-card-border-radius);
|
||||
border-bottom-left-radius: var(--bs-card-border-radius);
|
||||
border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color);
|
||||
}
|
||||
@ -0,0 +1,607 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#2e3436" />
|
||||
<title>Difftastic, a structural diff</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Difftastic, a structural diff tool that understands syntax"
|
||||
/>
|
||||
|
||||
<meta
|
||||
property="og:title"
|
||||
content="Difftastic, a structural diff tool that understands syntax"
|
||||
/>
|
||||
<meta property="og:url" content="https://difftastic.wilfred.me.uk/" />
|
||||
<meta property="og:image" content="" />
|
||||
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
|
||||
<link
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="home_static/style.css" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="home_static/asciinema-player.css"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="px-4 pt-5 text-center">
|
||||
<h1 class="display-2">
|
||||
<span class="red">diff</span><span class="green">tastic</span>
|
||||
</h1>
|
||||
|
||||
<div class="col-lg-6 mx-auto">
|
||||
<h2 class="fs-4 lead">
|
||||
a structural diff tool that understands syntax
|
||||
</h2>
|
||||
<div class="d-grid gap-2 d-sm-flex justify-content-sm-center mt-3">
|
||||
<a
|
||||
class="btn btn-lg btn-light"
|
||||
href="https://github.com/Wilfred/difftastic"
|
||||
role="button"
|
||||
><object
|
||||
class="github-logo"
|
||||
width="16"
|
||||
height="16"
|
||||
data="home_img/github.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
GitHub</a
|
||||
>
|
||||
<a
|
||||
class="btn btn-lg btn-light"
|
||||
href="https://difftastic.wilfred.me.uk/introduction.html"
|
||||
role="button"
|
||||
>📖 Manual</a
|
||||
>
|
||||
<a
|
||||
class="btn btn-lg btn-light"
|
||||
href="https://difftastic.wilfred.me.uk/installation.html"
|
||||
role="button"
|
||||
>🚦 Install</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-sm px-0">
|
||||
<p class="my-5 px-4">
|
||||
Difftastic is a CLI diff tool that compares files based on their syntax,
|
||||
not line-by-line. Difftastic produces accurate diffs that are easier for
|
||||
humans to read.
|
||||
</p>
|
||||
|
||||
<div class="card-set">
|
||||
<div class="card px-2 pt-2">
|
||||
<div class="card-body">
|
||||
<h2>
|
||||
<span class="green">Understand</span>
|
||||
What Actually Changed
|
||||
</h2>
|
||||
|
||||
<div class="img-wrapper mb-4">
|
||||
<img src="home_img/add_wrap.png" alt="screenshot" />
|
||||
</div>
|
||||
<p>
|
||||
Difftastic parses your code with
|
||||
<a href="https://tree-sitter.github.io/tree-sitter/"
|
||||
>tree-sitter</a
|
||||
>. Unlike a line-oriented diff, difftastic understands that the
|
||||
inner expression hasn't changed here.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 pt-2">
|
||||
<div class="card-body">
|
||||
<h2><span class="green">Ignore</span> Formatting Changes</h2>
|
||||
|
||||
<div class="img-wrapper mb-4">
|
||||
<img src="home_img/reformat.png" alt="screenshot" />
|
||||
</div>
|
||||
<p>
|
||||
Has your code formatter decided to split something over multiple
|
||||
lines? Difftastic can show what has actually changed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 pt-2">
|
||||
<div class="card-body">
|
||||
<h2><span class="green">Visualise</span> Wrapping Changes</h2>
|
||||
|
||||
<div class="img-wrapper mb-4">
|
||||
<img src="home_img/wrap_struct.png" alt="screenshot" />
|
||||
</div>
|
||||
<p>
|
||||
Have you added a wrapper? Difftastic can match the delimiters
|
||||
exactly.
|
||||
</p>
|
||||
|
||||
<div class="img-wrapper mb-4">
|
||||
<img
|
||||
src="home_img/change_wrap.png"
|
||||
class="mb-4"
|
||||
alt="screenshot"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
Even if you change the inner content, difftastic can still show
|
||||
you the additional wrapper.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 pt-2">
|
||||
<div class="card-body">
|
||||
<h2>
|
||||
<span class="green">Real</span>
|
||||
Line Numbers
|
||||
</h2>
|
||||
|
||||
<div class="img-wrapper mb-4">
|
||||
<img
|
||||
src="home_img/line_numbers.png"
|
||||
class="mb-4"
|
||||
alt="screenshot"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
Do you know how to read
|
||||
<code>@@ -5,6 +5,7 @@</code> syntax? Difftastic shows the actual
|
||||
line numbers from your files, both before and after.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 py-2 mt-5">
|
||||
<div class="card-body">
|
||||
<h2>60 Second <span class="green">Demo</span></h2>
|
||||
|
||||
<div id="demo"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- https://devicon.dev/ provides SVG logos. -->
|
||||
<div class="card-set">
|
||||
<div class="card px-2 pt-2 mt-5">
|
||||
<div class="card-body">
|
||||
<h2>Programming Languages</h2>
|
||||
|
||||
<div
|
||||
class="row row-cols-2 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4 pb-4"
|
||||
>
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/cplusplus.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<h3 class="fw-bold mb-0 fs-4">C++</h3>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/csharp.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">C#</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/clojure.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Clojure</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/dart.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Dart</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/erlang.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Erlang</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/go.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Go</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/haskell.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Haskell</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/java.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Java</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/javascript.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">JavaScript</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/kotlin.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Kotlin</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/lisp.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Lisp</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/lua.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Lua</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/ocaml.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">OCaml</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/php.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">PHP</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/python.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Python</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/r.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">R</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/ruby.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Ruby</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/rust.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Rust</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/scala.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">Scala</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/typescript.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">TypeScript</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- end languages -->
|
||||
</div>
|
||||
|
||||
<p>
|
||||
And more! See the full
|
||||
<a
|
||||
href="https://difftastic.wilfred.me.uk/languages_supported.html"
|
||||
>list of supported languages</a
|
||||
>
|
||||
in the manual.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 pt-2">
|
||||
<div class="card-body">
|
||||
<h2>File Formats</h2>
|
||||
|
||||
<div
|
||||
class="row row-cols-2 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4 pb-4"
|
||||
>
|
||||
<div class="col d-flex align-items-start">
|
||||
<!-- https://www.svgrepo.com/svg/371192/curly-brackets -->
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/braces.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">HCL</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/html5.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">HTML</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/json.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">JSON</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col d-flex align-items-start">
|
||||
<object
|
||||
class="me-3"
|
||||
width="45px"
|
||||
height="45px"
|
||||
data="home_img/yaml.svg"
|
||||
type="image/svg+xml"
|
||||
></object>
|
||||
|
||||
<div>
|
||||
<h3 class="fw-bold mb-0 fs-4">YAML</h3>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end formats -->
|
||||
</div>
|
||||
|
||||
<p>
|
||||
And even more! See the full
|
||||
<a
|
||||
href="https://difftastic.wilfred.me.uk/languages_supported.html#structured-text-formats"
|
||||
>list of supported file formats</a
|
||||
>
|
||||
in the manual.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 pt-2 mt-5">
|
||||
<div class="card-body">
|
||||
<h2>Works With <span class="green">Git</span></h2>
|
||||
<div class="img-wrapper mb-4">
|
||||
<img src="home_img/git_difftool.png" alt="screenshot" />
|
||||
</div>
|
||||
<p>
|
||||
See the
|
||||
<a href="https://difftastic.wilfred.me.uk/git.html"
|
||||
>git configuration</a
|
||||
>
|
||||
instructions in the manual.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card px-2 pt-2 mt-5">
|
||||
<div class="card-body">
|
||||
<h2>Fully <span class="green">Open Source</span></h2>
|
||||
<p>
|
||||
Difftastic is
|
||||
<a href="https://github.com/Wilfred/difftastic/blob/master/LICENSE"
|
||||
>MIT licensed</a
|
||||
>. Download it, modify it, share it with your friends!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="px-4 mt-5">
|
||||
<em
|
||||
>Made with Emacs and coffee by
|
||||
<a href="https://github.com/wilfred/">Wilfred Hughes</a>.</em
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css?family=Fontdiner+Swanky"
|
||||
/>
|
||||
|
||||
<script src="home_static/asciinema-player.min.js"></script>
|
||||
<script>
|
||||
AsciinemaPlayer.create(
|
||||
"home_static/demo.cast",
|
||||
document.getElementById("demo"),
|
||||
{
|
||||
theme: "tango",
|
||||
cols: 133,
|
||||
rows: 24,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,273 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Installation - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html" class="active"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="installation"><a class="header" href="#installation">Installation</a></h1>
|
||||
<p>Difftastic can be installed as pre-built binaries or using various package managers.</p>
|
||||
<h2 id="pre-built-binaries"><a class="header" href="#pre-built-binaries">Pre-Built Binaries</a></h2>
|
||||
<p>Difftastic releases are published as <a href="https://github.com/Wilfred/difftastic/releases">GitHub releases</a> with pre-built binaries for Windows, macOS and Linux.
|
||||
Open the <a href="https://github.com/Wilfred/difftastic/releases/latest">latest release page</a>, download the file matching your OS and CPU architecture, and extract the <code>difft</code> executable application file.</p>
|
||||
<h2 id="package-manager"><a class="header" href="#package-manager">Package Manager</a></h2>
|
||||
<h3 id="macos"><a class="header" href="#macos">macOS</a></h3>
|
||||
<p>If you're a <strong>Homebrew</strong> user, you can install
|
||||
<a href="https://formulae.brew.sh/formula/difftastic">difftastic</a> with <code>brew</code>.</p>
|
||||
<pre><code>$ brew install difftastic
|
||||
</code></pre>
|
||||
<h3 id="linux-and-unix"><a class="header" href="#linux-and-unix">Linux and Unix</a></h3>
|
||||
<p>If you're an <strong>Arch Linux</strong> user, you can install
|
||||
<a href="https://archlinux.org/packages/extra/x86_64/difftastic/">difftastic</a>
|
||||
with <code>pacman</code>.</p>
|
||||
<pre><code>$ sudo pacman -S difftastic
|
||||
</code></pre>
|
||||
<p>If you're a <strong>Nix</strong> user, you can install
|
||||
<a href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/text/difftastic/default.nix">difftastic</a>
|
||||
with <code>nix-env</code>.</p>
|
||||
<pre><code>$ nix-env --install difftastic
|
||||
</code></pre>
|
||||
<p>If you're a <strong>Fedora</strong> user, you can install <a href="https://packages.fedoraproject.org/pkgs/rust-difftastic/difftastic/">difftastic</a> with <code>dnf</code>.</p>
|
||||
<pre><code>$ sudo dnf install difftastic
|
||||
</code></pre>
|
||||
<p>If you're a <strong>FreeBSD</strong> user, you can install
|
||||
<a href="https://www.freshports.org/textproc/difftastic/">difftastic</a>
|
||||
with <code>pkg</code>.</p>
|
||||
<pre><code>$ sudo pkg install difftastic
|
||||
</code></pre>
|
||||
<h3 id="windows"><a class="header" href="#windows">Windows</a></h3>
|
||||
<p>If you're a Windows user using <strong>Windows Package Manager</strong> (<em>WinGet</em>), you can install difftastic with <code>winget</code>.</p>
|
||||
<pre><code>$ winget install difftastic
|
||||
</code></pre>
|
||||
<p>If you're a Windows user using <strong>Scoop</strong>, you can install
|
||||
<a href="https://scoop.sh/#/apps?q=difftastic">difftastic</a>
|
||||
with <code>scoop</code>.</p>
|
||||
<pre><code>$ scoop install difftastic
|
||||
</code></pre>
|
||||
<p>If you're a Windows user using <strong>Chocolatey</strong>, you can install
|
||||
<a href="https://community.chocolatey.org/packages/difftastic">difftastic</a>
|
||||
with <code>choco</code>.</p>
|
||||
<pre><code>$ choco install difftastic
|
||||
</code></pre>
|
||||
<h2 id="full-package-listing"><a class="header" href="#full-package-listing">Full Package Listing</a></h2>
|
||||
<p>This table lists all the platforms that have packaged difftastic.</p>
|
||||
<p><a href="https://repology.org/project/difftastic/versions"><img src="https://repology.org/badge/vertical-allrepos/difftastic.svg" alt="Packaging status" /></a></p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="introduction.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="from_source.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="introduction.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="from_source.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,269 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Introduction - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html" class="active"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="introduction"><a class="header" href="#introduction">Introduction</a></h1>
|
||||
<p>Difftastic is a structural diff tool that understands syntax. It
|
||||
supports <a href="./languages_supported.html">over 30 programming languages</a>
|
||||
and when it works, it's <em>fantastic</em>.</p>
|
||||
<p>Difftastic is open source software (MIT license) and <a href="https://github.com/wilfred/difftastic">available on
|
||||
GitHub</a>.</p>
|
||||
<p>This copy of the manual describes version 0.66.0. The
|
||||
<a href="https://github.com/Wilfred/difftastic/blob/master/CHANGELOG.md">changelog</a>
|
||||
records which features and bug fixes are in each version.</p>
|
||||
<p><em>This manual is also available in <a href="https://difftastic.wilfred.me.uk/zh-CN/">Chinese</a>.</em></p>
|
||||
<h2 id="syntactic-diffing"><a class="header" href="#syntactic-diffing">Syntactic Diffing</a></h2>
|
||||
<p>Difftastic <a href="./usage.html#language-detection">detects the language</a>, parses the code, and then
|
||||
compares the syntax trees. Let's look at an example.</p>
|
||||
<pre><code>// old.rs
|
||||
let ts_lang = guess(path, guess_src).map(tsp::from_language);
|
||||
</code></pre>
|
||||
<pre><code>// new.rs
|
||||
let ts_lang = language_override
|
||||
.or_else(|| guess(path, guess_src))
|
||||
.map(tsp::from_language);
|
||||
</code></pre>
|
||||
<pre><code style="display:block">$ difft old.rs new.rs
|
||||
|
||||
1 <span style="background-color: PaleGreen; color: #000">1</span> let ts_lang = <span style="background-color: PaleGreen; color: #000">language_override</span>
|
||||
. <span style="background-color: PaleGreen; color: #000">2</span> <span style="background-color: PaleGreen; color: #000">.or_else(||</span> guess(path, guess_src)<span style="background-color: PaleGreen; color: #000">)</span>
|
||||
. 3 .map(tsp::from_language);
|
||||
</code>
|
||||
</pre>
|
||||
<p>Notice how difftastic recognises that <code>.map</code> is unchanged, even though
|
||||
it's now on a new line with whitespace.</p>
|
||||
<p>A line-oriented diff does a much worse job here.</p>
|
||||
<pre><code style="display:block">$ diff -u old.rs new.rs
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
<span style="background-color: #fbbd98; color: #000">-let ts_lang = guess(path, guess_src).map(tsp::from_language);</span>
|
||||
<span style="background-color: PaleGreen; color: #000">+let ts_lang = language_override
|
||||
+ .or_else(|| guess(path, guess_src))
|
||||
+ .map(tsp::from_language);</span>
|
||||
</code>
|
||||
</pre>
|
||||
<p>Some line-oriented diff tools also highlight word changes (e.g. GitHub
|
||||
or git's <code>--word-diff</code>). They still don't understand the code
|
||||
though. Difftastic will always find matched delimiters: you can see
|
||||
the closing <code>)</code> from <code>or_else</code> has been highlighted.</p>
|
||||
<h2 id="fallback-line-oriented-diffing"><a class="header" href="#fallback-line-oriented-diffing">Fallback Line-Oriented Diffing</a></h2>
|
||||
<p>If input files are not in a format that difftastic understands, it
|
||||
uses a conventional line-oriented diff with word highlighting.</p>
|
||||
<p>Difftastic will also use line-oriented diffing when given extremely
|
||||
large inputs.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
|
||||
<a rel="next prefetch" href="installation.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
|
||||
<a rel="next prefetch" href="installation.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,235 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Jujutsu - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html" class="active"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="jujutsu"><a class="header" href="#jujutsu">Jujutsu</a></h1>
|
||||
<p>Jujutsu supports <a href="https://jj-vcs.github.io/jj/latest/config/#generating-diffs-by-external-command">external diff
|
||||
commands</a>.</p>
|
||||
<p>To use difftastic for diffing in jujutsu, add the following to your
|
||||
<a href="https://jj-vcs.github.io/jj/latest/config/#user-config-files">user configuration
|
||||
file</a>.</p>
|
||||
<pre><code class="language-toml">[ui]
|
||||
diff-formatter = ["difft", "--color=always", "$left", "$right"]
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="fossil.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="languages_supported.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="fossil.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="languages_supported.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,248 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Language Detection - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html" class="active"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="language-detection"><a class="header" href="#language-detection">Language Detection</a></h1>
|
||||
<p>Difftastic guesses the language used based on the file extension, file
|
||||
name, and the contents of the first few lines.</p>
|
||||
<p>To see the languages available, and the associated file names, use the
|
||||
<code>--list-languages</code> option.</p>
|
||||
<pre><code class="language-bash">$ difft --list-languages
|
||||
...
|
||||
XML
|
||||
*.ant *.csproj *.plist *.resx *.svg *.ui *.vbproj *.xaml *.xml *.xsd *.xsl *.xslt *.zcml App.config nuget.config packages.config .classpath .cproject .project
|
||||
YAML
|
||||
*.yaml *.yml
|
||||
Zig
|
||||
*.zig
|
||||
</code></pre>
|
||||
<p>You can override language detection for specific file globs using the
|
||||
<code>--override</code> option.</p>
|
||||
<pre><code class="language-bash">$ difft --override=GLOB:NAME FIRST-FILE SECOND-FILE
|
||||
|
||||
# For example, treating .h files as C rather than C++:
|
||||
$ difft --override=*.h:c sample_files/preprocessor_1.h sample_files/preprocessor_2.h
|
||||
</code></pre>
|
||||
<p>See <code>difft --help</code> for more examples of <code>--override</code> usage.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="languages_supported.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="parsing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="languages_supported.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="parsing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,299 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Languages Supported - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html" class="active"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="languages-supported"><a class="header" href="#languages-supported">Languages Supported</a></h1>
|
||||
<p>This page lists all the languages supported by difftastic. You can
|
||||
also view the languages supported in your current installed version
|
||||
with <code>difft --list-languages</code>.</p>
|
||||
<h2 id="programming-languages"><a class="header" href="#programming-languages">Programming Languages</a></h2>
|
||||
<div class="table-wrapper"><table><thead><tr><th>Language</th><th>Parser Used</th></tr></thead><tbody>
|
||||
<tr><td>Ada</td><td><a href="https://github.com/briot/tree-sitter-ada">briot/tree-sitter-ada</a></td></tr>
|
||||
<tr><td>Apex</td><td><a href="https://github.com/aheber/tree-sitter-sfapex">aheber/tree-sitter-sfapex</a></td></tr>
|
||||
<tr><td>Bash</td><td><a href="https://github.com/tree-sitter/tree-sitter-bash">tree-sitter/tree-sitter-bash</a></td></tr>
|
||||
<tr><td>C</td><td><a href="https://github.com/tree-sitter/tree-sitter-c">tree-sitter/tree-sitter-c</a></td></tr>
|
||||
<tr><td>C++</td><td><a href="https://github.com/tree-sitter/tree-sitter-cpp">tree-sitter/tree-sitter-cpp</a></td></tr>
|
||||
<tr><td>C#</td><td><a href="https://github.com/tree-sitter/tree-sitter-c-sharp">tree-sitter/tree-sitter-c-sharp</a></td></tr>
|
||||
<tr><td>Clojure</td><td><a href="https://github.com/sogaiu/tree-sitter-clojure">sogaiu/tree-sitter-clojure</a></td></tr>
|
||||
<tr><td>CMake</td><td><a href="https://github.com/uyha/tree-sitter-cmake">uyha/tree-sitter-cmake</a></td></tr>
|
||||
<tr><td>Common Lisp</td><td><a href="https://github.com/theHamsta/tree-sitter-commonlisp">theHamsta/tree-sitter-commonlisp</a></td></tr>
|
||||
<tr><td>Dart</td><td><a href="https://codeberg.org/grammar-orchard/tree-sitter-dart-orchard">grammar-orchard/tree-sitter-dart</a></td></tr>
|
||||
<tr><td>Device Tree</td><td><a href="https://github.com/joelspadin/tree-sitter-devicetree">joelspadin/tree-sitter-devicetree</a></td></tr>
|
||||
<tr><td>Elixir</td><td><a href="https://github.com/elixir-lang/tree-sitter-elixir">elixir-lang/tree-sitter-elixir</a></td></tr>
|
||||
<tr><td>Elm</td><td><a href="https://github.com/elm-tooling/tree-sitter-elm">elm-tooling/tree-sitter-elm</a></td></tr>
|
||||
<tr><td>Elvish</td><td><a href="https://github.com/ckafi/tree-sitter-elvish">ckafi/tree-sitter-elvish</a></td></tr>
|
||||
<tr><td>Erlang</td><td><a href="https://github.com/WhatsApp/tree-sitter-erlang">WhatsApp/tree-sitter-erlang</a></td></tr>
|
||||
<tr><td>Emacs Lisp</td><td><a href="https://github.com/Wilfred/tree-sitter-elisp">wilfred/tree-sitter-elisp</a></td></tr>
|
||||
<tr><td>F#</td><td><a href="https://github.com/ionide/tree-sitter-fsharp">ionide/tree-sitter-fsharp</a></td></tr>
|
||||
<tr><td>Gleam</td><td><a href="https://github.com/gleam-lang/tree-sitter-gleam">gleam-lang/tree-sitter-gleam</a></td></tr>
|
||||
<tr><td>Go</td><td><a href="https://github.com/tree-sitter/tree-sitter-go">tree-sitter/tree-sitter-go</a></td></tr>
|
||||
<tr><td>Hack</td><td><a href="https://github.com/slackhq/tree-sitter-hack">slackhq/tree-sitter-hack</a></td></tr>
|
||||
<tr><td>Hare</td><td><a href="https://git.sr.ht/~ecmma/tree-sitter-hare">ecmma/tree-sitter-hare</a></td></tr>
|
||||
<tr><td>Haskell</td><td><a href="https://github.com/tree-sitter/tree-sitter-haskell">tree-sitter/tree-sitter-haskell</a></td></tr>
|
||||
<tr><td>Janet</td><td><a href="https://github.com/sogaiu/tree-sitter-janet-simple">sogaiu/tree-sitter-janet-simple</a></td></tr>
|
||||
<tr><td>Java</td><td><a href="https://github.com/tree-sitter/tree-sitter-java">tree-sitter/tree-sitter-java</a></td></tr>
|
||||
<tr><td>JavaScript, JSX</td><td><a href="https://github.com/tree-sitter/tree-sitter-javascript">tree-sitter/tree-sitter-javascript</a></td></tr>
|
||||
<tr><td>Julia</td><td><a href="https://github.com/tree-sitter/tree-sitter-julia">tree-sitter/tree-sitter-julia</a></td></tr>
|
||||
<tr><td>Kotlin</td><td><a href="https://github.com/fwcd/tree-sitter-kotlin">fwcd/tree-sitter-kotlin</a></td></tr>
|
||||
<tr><td>Lua</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-lua">tree-sitter-grammars/tree-sitter-lua</a></td></tr>
|
||||
<tr><td>Make</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-make">tree-sitter-grammars/tree-sitter-make</a></td></tr>
|
||||
<tr><td>Nix</td><td><a href="https://github.com/nix-community/tree-sitter-nix">nix-community/tree-sitter-nix</a></td></tr>
|
||||
<tr><td>Objective-C</td><td><a href="https://github.com/amaanq/tree-sitter-objc">amaanq/tree-sitter-objc</a></td></tr>
|
||||
<tr><td>OCaml</td><td><a href="https://github.com/tree-sitter/tree-sitter-ocaml">tree-sitter/tree-sitter-ocaml</a></td></tr>
|
||||
<tr><td>Pascal</td><td><a href="https://github.com/Isopod/tree-sitter-pascal">Isopod/tree-sitter-pascal</a></td></tr>
|
||||
<tr><td>Perl</td><td><a href="https://github.com/ganezdragon/tree-sitter-perl">ganezdragon/tree-sitter-perl</a></td></tr>
|
||||
<tr><td>PHP</td><td><a href="https://github.com/tree-sitter/tree-sitter-php">tree-sitter/tree-sitter-php</a></td></tr>
|
||||
<tr><td>Python</td><td><a href="https://github.com/tree-sitter/tree-sitter-python">tree-sitter/tree-sitter-python</a></td></tr>
|
||||
<tr><td>QML</td><td><a href="https://github.com/yuja/tree-sitter-qmljs">yuja/tree-sitter-qmljs</a></td></tr>
|
||||
<tr><td>R</td><td><a href="https://github.com/r-lib/tree-sitter-r">r-lib/tree-sitter-r</a></td></tr>
|
||||
<tr><td>Racket</td><td><a href="https://github.com/6cdh/tree-sitter-racket">6cdh/tree-sitter-racket</a></td></tr>
|
||||
<tr><td>Ruby</td><td><a href="https://github.com/tree-sitter/tree-sitter-ruby">tree-sitter/tree-sitter-ruby</a></td></tr>
|
||||
<tr><td>Rust</td><td><a href="https://github.com/tree-sitter/tree-sitter-rust">tree-sitter/tree-sitter-rust</a></td></tr>
|
||||
<tr><td>Scala</td><td><a href="https://github.com/tree-sitter/tree-sitter-scala">tree-sitter/tree-sitter-scala</a></td></tr>
|
||||
<tr><td>Scheme</td><td><a href="https://github.com/6cdh/tree-sitter-scheme">6cdh/tree-sitter-scheme</a></td></tr>
|
||||
<tr><td>Smali</td><td><a href="https://github.com/amaanq/tree-sitter-smali">amaanq/tree-sitter-smali</a></td></tr>
|
||||
<tr><td>Solidity</td><td><a href="https://github.com/JoranHonig/tree-sitter-solidity">JoranHonig/tree-sitter-solidity</a></td></tr>
|
||||
<tr><td>SQL</td><td><a href="https://github.com/derekstride/tree-sitter-sql">derekstride/tree-sitter-sql</a></td></tr>
|
||||
<tr><td>Swift</td><td><a href="https://github.com/alex-pinkus/tree-sitter-swift">alex-pinkus/tree-sitter-swift</a></td></tr>
|
||||
<tr><td>TypeScript, TSX</td><td><a href="https://github.com/tree-sitter/tree-sitter-typescript">tree-sitter/tree-sitter-typescript</a></td></tr>
|
||||
<tr><td>Verilog</td><td><a href="https://github.com/tree-sitter/tree-sitter-verilog">tree-sitter/tree-sitter-verilog</a></td></tr>
|
||||
<tr><td>VHDL</td><td><a href="https://github.com/JLeemaster/tree-sitter-vhdl">JLeemaster/tree-sitter-vhdl</a></td></tr>
|
||||
<tr><td>Zig</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-zig">tree-sitter-grammars/tree-sitter-zig</a></td></tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
<h2 id="structured-text-formats"><a class="header" href="#structured-text-formats">Structured Text Formats</a></h2>
|
||||
<div class="table-wrapper"><table><thead><tr><th>Language</th><th>Parser Used</th></tr></thead><tbody>
|
||||
<tr><td>CSS</td><td><a href="https://github.com/tree-sitter/tree-sitter-css">tree-sitter/tree-sitter-css</a></td></tr>
|
||||
<tr><td>HCL</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-hcl">tree-sitter-grammars/tree-sitter-hcl</a></td></tr>
|
||||
<tr><td>HTML</td><td><a href="https://github.com/tree-sitter/tree-sitter-html">tree-sitter/tree-sitter-html</a></td></tr>
|
||||
<tr><td>JSON</td><td><a href="https://github.com/tree-sitter/tree-sitter-json">tree-sitter/tree-sitter-json</a></td></tr>
|
||||
<tr><td>LaTeX</td><td><a href="https://github.com/latex-lsp/tree-sitter-latex">latex-lsp/tree-sitter-latex</a></td></tr>
|
||||
<tr><td>Newick</td><td><a href="https://github.com/delehef/tree-sitter-newick">delehef/tree-sitter-newick</a></td></tr>
|
||||
<tr><td>Proto</td><td><a href="https://github.com/coder3101/tree-sitter-proto">coder3101/tree-sitter-proto</a></td></tr>
|
||||
<tr><td>SCSS</td><td><a href="https://github.com/serenadeai/tree-sitter-scss">serenadeai/tree-sitter-scss</a></td></tr>
|
||||
<tr><td>TOML</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-toml">tree-sitter-grammars/tree-sitter-toml</a></td></tr>
|
||||
<tr><td>XML</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-xml">tree-sitter-grammars/tree-sitter-xml</a></td></tr>
|
||||
<tr><td>YAML</td><td><a href="https://github.com/tree-sitter-grammars/tree-sitter-yaml">tree-sitter-grammars/tree-sitter-yaml</a></td></tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="jj.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="language_detection.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="jj.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="language_detection.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,258 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Mercurial - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html" class="active"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="mercurial"><a class="header" href="#mercurial">Mercurial</a></h1>
|
||||
<p>Mercurial <a href="https://www.mercurial-scm.org/wiki/ExtdiffExtension">supports external diff
|
||||
tools</a> with the
|
||||
Extdiff extension. Enable it by adding an entry to <code>extensions</code> in
|
||||
your <code>.hgrc</code>.</p>
|
||||
<pre><code>[extensions]
|
||||
extdiff =
|
||||
</code></pre>
|
||||
<p>You can then run <code>hg extdiff -p difft</code> instead of <code>hg diff</code>
|
||||
(assumes the <code>difft</code> binary is on your <code>$PATH</code>).</p>
|
||||
<p>You can also define an alias to run difftastic with hg. Add the
|
||||
following to your <code>.hgrc</code> to run difftastic with <code>hg dft</code>.</p>
|
||||
<pre><code>[extdiff]
|
||||
cmd.dft = difft
|
||||
# You can add further options which will be passed to the command line, e.g.
|
||||
# opts.dft = --background light
|
||||
</code></pre>
|
||||
<p>All options of <code>hg diff</code> are also supported by <code>hg dft</code>; for example,
|
||||
<code>hg dft --stat</code> will show statistics of changed lines and <code>hg dft -r 42 -r 45</code>
|
||||
will show the diff between two revisions.</p>
|
||||
<h2 id="hg-log--p"><a class="header" href="#hg-log--p">hg log -p</a></h2>
|
||||
<p>Mercurial does not have a way of changing the default diff tool, at
|
||||
least to the author's knowledge.</p>
|
||||
<p>If you just want to view the diff of the most recent commit, you can
|
||||
use the following.</p>
|
||||
<pre><code>hg dft -r .^ -r .
|
||||
</code></pre>
|
||||
<p>This is equivalent to <code>hg log -l 1 -p</code>, although it does not show the
|
||||
commit message. I like to define an alias for this:</p>
|
||||
<pre><code>[alias]
|
||||
dp = dft -r .^ -r .
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="git.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="fossil.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="git.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="fossil.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,294 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Packaging Difftastic - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html" class="active"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="packaging-difftastic"><a class="header" href="#packaging-difftastic">Packaging Difftastic</a></h1>
|
||||
<p>This page contains recommendations for people creating a difftastic
|
||||
package.</p>
|
||||
<p>Note that the difftastic author only provides the source code and the
|
||||
prebuilt binaries on GitHub. Packages have been created by other
|
||||
people -- thank you!</p>
|
||||
<h2 id="packaging-the-binary"><a class="header" href="#packaging-the-binary">Packaging The Binary</a></h2>
|
||||
<p>Difftastic can be built with <code>cargo</code>. The compiled binary will be at
|
||||
<code>target/release/difft</code> when using the following command.</p>
|
||||
<pre><code>$ cargo build --release
|
||||
</code></pre>
|
||||
<p>C library dependencies are built with the <code>cc</code> crate, which <a href="https://docs.rs/cc/1.1.30/cc/index.html#external-configuration-via-environment-variables">has
|
||||
various environment
|
||||
variables</a>
|
||||
to configure the C toolchain (e.g. <code>CFLAGS</code>).</p>
|
||||
<h3 id="reproducible-builds"><a class="header" href="#reproducible-builds">Reproducible Builds</a></h3>
|
||||
<p>Difftastic's build script (the <code>build.rs</code> file) uses Rayon to build C
|
||||
libraries in parallel, which can lead to minor ordering changes in the
|
||||
final binary.</p>
|
||||
<p>You can avoid this by disabling Rayon parallelism.</p>
|
||||
<pre><code class="language-bash">$ RAYON_NUM_THREADS=1 cargo build --release
|
||||
</code></pre>
|
||||
<h3 id="mime-database"><a class="header" href="#mime-database">MIME Database</a></h3>
|
||||
<p>Difftastic depends on
|
||||
<a href="https://docs.rs/tree_magic_mini/latest/tree_magic_mini/">tree_magic_mini</a>,
|
||||
which accesses the MIME database on the current system. The MIME
|
||||
database is used to recognise file types, so difftastic does not try
|
||||
to compoare binary files as text.</p>
|
||||
<p>This means that the difftastic package should depend on a MIME
|
||||
database package, if available.</p>
|
||||
<p>Difftastic respects the <a href="https://specifications.freedesktop.org/basedir-spec/latest/index.html#basics">XDG base
|
||||
specification</a>
|
||||
to find the MIME database files. These files are typically at
|
||||
<code>/usr/share/mime/</code>, <code>/usr/local/share/mime/</code> or
|
||||
<code>/opt/homebrew/share/mime/</code>.</p>
|
||||
<h2 id="man-page"><a class="header" href="#man-page">Man Page</a></h2>
|
||||
<p>As of difftastic 0.58, a man page is available. See the file
|
||||
<code>difft.1</code>.</p>
|
||||
<p>This file is generated from <code>difft.1.md</code>, but the generated <code>difft.1</code>
|
||||
is included in the repository for convenience.</p>
|
||||
<h2 id="the-manual"><a class="header" href="#the-manual">The Manual</a></h2>
|
||||
<p>Please consider including the difftastic manual with your
|
||||
package. These are HTML files that can be generated with <code>mdbook</code>. The
|
||||
following command generates HTML at <code>manual/book/</code>.</p>
|
||||
<pre><code>$ cd manual
|
||||
$ mdbook build
|
||||
</code></pre>
|
||||
<p><code>manual/book.toml</code> also references a script
|
||||
<code>replace_version_placeholder.sh</code> that replaces occurrences of
|
||||
<code>DFT_VERSION_HERE</code> in the manual. For packaging, it may be easier to
|
||||
remove the configuration from <code>book.toml</code> and replace the text
|
||||
directly.</p>
|
||||
<pre><code class="language-diff">-[preprocessor.replace-version-placeholder]
|
||||
-command = "./replace_version_placeholder.sh"
|
||||
</code></pre>
|
||||
<pre><code>$ export CURRENTVERSION="7.8.9"
|
||||
$ sed -i "s/DFT_VERSION_HERE/$CURRENTVERSION/g" -i src/introduction.md
|
||||
</code></pre>
|
||||
<h2 id="testing"><a class="header" href="#testing">Testing</a></h2>
|
||||
<p>If your packaging tool supports testing, consider running the
|
||||
difftastic unit tests.</p>
|
||||
<pre><code># Run the normal tests.
|
||||
$ cargo test
|
||||
|
||||
# Run the tests that depend on the
|
||||
# MIME database being present.
|
||||
$ cargo test -- --ignored
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="from_source.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="usage.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="from_source.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="usage.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,262 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Parser Vendoring - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html" class="active"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="vendoring"><a class="header" href="#vendoring">Vendoring</a></h1>
|
||||
<h2 id="git-subtrees"><a class="header" href="#git-subtrees">Git Subtrees</a></h2>
|
||||
<p>Tree-sitter parsers are sometimes not packaged on crates.io. In that case, Difftastic uses
|
||||
git subtrees (not git submodules) to track them.</p>
|
||||
<h2 id="vendoring-a-parser"><a class="header" href="#vendoring-a-parser">Vendoring a parser</a></h2>
|
||||
<p>Once you've found the source repository for the parser, add it as a git subtree to
|
||||
<code>vendored_parsers/</code>. We'll use
|
||||
<a href="https://github.com/tree-sitter/tree-sitter-json">tree-sitter-json</a> as
|
||||
an example.</p>
|
||||
<pre><code>$ git subtree add --prefix=vendored_parsers/tree-sitter-json https://github.com/tree-sitter/tree-sitter-json.git master
|
||||
</code></pre>
|
||||
<h3 id="configure-the-build"><a class="header" href="#configure-the-build">Configure the build</a></h3>
|
||||
<p>Cargo does not allow packages to include subdirectories that contain a
|
||||
<code>Cargo.toml</code>. Add a symlink to the <code>src/</code> parser subdirectory.</p>
|
||||
<pre><code>$ cd vendored_parsers
|
||||
$ ln -s tree-sitter-json/src tree-sitter-json-src
|
||||
</code></pre>
|
||||
<p>You can now add the parser to build by including the directory in
|
||||
<code>build.rs</code>.</p>
|
||||
<pre><code>TreeSitterParser {
|
||||
name: "tree-sitter-json",
|
||||
src_dir: "vendored_parsers/tree-sitter-json-src",
|
||||
extra_files: vec![],
|
||||
},
|
||||
</code></pre>
|
||||
<p>If your parser includes custom C or C++ files for lexing (e.g. a
|
||||
<code>scanner.cc</code>), add them to <code>extra_files</code>.</p>
|
||||
<h2 id="updating-a-parser"><a class="header" href="#updating-a-parser">Updating a parser</a></h2>
|
||||
<p>To update a parser, pull commits from the upstream git repository. For
|
||||
example, the following command will update the Java parser:</p>
|
||||
<pre><code>$ git subtree pull --prefix=vendored_parsers/tree-sitter-java git@github.com:tree-sitter/tree-sitter-java.git master
|
||||
</code></pre>
|
||||
<p>To see when each parser was last updated, use the following shell
|
||||
command:</p>
|
||||
<pre><code>$ for d in $(git log vendored_parsers/* | grep git-subtree-dir | tr -d ' ' | cut -d ":" -f2 | sort); do echo "$d"; git log --pretty=" %cs" -n 1 $d; done
|
||||
</code></pre>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="adding_a_parser.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="profiling.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="adding_a_parser.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="profiling.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,302 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Internals: Parsing - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html" class="active"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h1 id="internals-parsing"><a class="header" href="#internals-parsing">Internals: Parsing</a></h1>
|
||||
<p>Difftastic uses
|
||||
<a href="https://tree-sitter.github.io/tree-sitter/">tree-sitter</a> to build a
|
||||
parse tree. The parse tree is then converted to a simpler tree which
|
||||
can be diffed.</p>
|
||||
<h2 id="parsing-with-tree-sitter"><a class="header" href="#parsing-with-tree-sitter">Parsing with Tree-sitter</a></h2>
|
||||
<p>Difftastic relies on tree-sitter to understand syntax. You can view
|
||||
the parse tree that tree-sitter produces using the <code>--dump-ts</code>
|
||||
flag.</p>
|
||||
<pre><code>$ difft --dump-ts sample_files/javascript_simple_1.js | head
|
||||
program (0, 0) - (7, 0)
|
||||
comment (0, 0) - (0, 8) "// hello"
|
||||
expression_statement (1, 0) - (1, 6)
|
||||
call_expression (1, 0) - (1, 5)
|
||||
identifier (1, 0) - (1, 3) "foo"
|
||||
arguments (1, 3) - (1, 5)
|
||||
( (1, 3) - (1, 4) "("
|
||||
) (1, 4) - (1, 5) ")"
|
||||
; (1, 5) - (1, 6) ";"
|
||||
expression_statement (2, 0) - (2, 6)
|
||||
</code></pre>
|
||||
<h2 id="simplified-syntax"><a class="header" href="#simplified-syntax">Simplified Syntax</a></h2>
|
||||
<p>Difftastic converts the tree-sitter parse tree to a simplified syntax
|
||||
tree. The syntax tree is a uniform representation where everything is
|
||||
either an atom (e.g. integer literals, comments, variable names) or a
|
||||
list (consisting of the open delimiter, children and the close
|
||||
delimiter).</p>
|
||||
<p>The flag <code>--dump-syntax</code> will display the syntax tree generated for a
|
||||
file.</p>
|
||||
<pre><code>$ difft --dump-syntax sample_files/before.js
|
||||
[
|
||||
Atom id:1 {
|
||||
content: "// hello",
|
||||
position: "0:0-8",
|
||||
},
|
||||
List id:2 {
|
||||
open_content: "",
|
||||
open_position: "1:0-0",
|
||||
children: [
|
||||
...
|
||||
</code></pre>
|
||||
<h3 id="conversion-process"><a class="header" href="#conversion-process">Conversion Process</a></h3>
|
||||
<p>The simple representation of the difftastic parse tree makes diffing
|
||||
much easier. Converting the detailed tree-sitter parse tree is a
|
||||
recursive tree walk, treating tree-sitter leaf nodes as atoms. There
|
||||
are two exceptions.</p>
|
||||
<p>(1) Tree-sitter parse trees sometimes include unwanted structure. Some
|
||||
grammars consider string literals to be a single token, whereas others
|
||||
treat strings as a complex structure where the delimiters are
|
||||
separate.</p>
|
||||
<p><code>tree_sitter_parser.rs</code> uses <code>atom_nodes</code> to mark specific tree-sitter
|
||||
node names as flat atoms even if the node has children.</p>
|
||||
<p>(2) Tree-sitter parse trees include open and closing delimiters as
|
||||
tokens. A list <code>[1]</code> will have a parse tree that includes <code>[</code> and <code>]</code>
|
||||
as nodes.</p>
|
||||
<pre><code>$ echo '[1]' > example.js
|
||||
$ difft --dump-ts example.js
|
||||
program (0, 0) - (1, 0)
|
||||
expression_statement (0, 0) - (0, 3)
|
||||
array (0, 0) - (0, 3)
|
||||
[ (0, 0) - (0, 1) "["
|
||||
number (0, 1) - (0, 2) "1"
|
||||
] (0, 2) - (0, 3) "]"
|
||||
</code></pre>
|
||||
<p><code>tree_sitter_parser.rs</code> uses <code>open_delimiter_tokens</code> to ensure that
|
||||
<code>[</code> and <code>]</code> are used as delimiter content in the enclosing list,
|
||||
rather than converting them to atoms.</p>
|
||||
<p>Difftastic can match up atoms that occur in different parts of the
|
||||
simplified syntax tree. If e.g. a <code>[</code> is treated as an atom,
|
||||
difftastic might match it with another <code>[</code> elsewhere. The resulting
|
||||
diff would be unbalanced, highlighting different numbers of open and
|
||||
close delimiters.</p>
|
||||
<h3 id="lossy-syntax-trees"><a class="header" href="#lossy-syntax-trees">Lossy Syntax Trees</a></h3>
|
||||
<p>The simplified syntax tree only stores node content and node
|
||||
position. It does not store whitespace between nodes, and position is
|
||||
ignored during diffing.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="language_detection.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="diffing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="language_detection.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="diffing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,243 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Profiling - Difftastic Manual</title>
|
||||
|
||||
|
||||
<!-- Custom HTML head -->
|
||||
|
||||
<meta name="description" content="The manual for difftastic, the structural diff tool">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="icon" href="favicon.svg">
|
||||
<link rel="stylesheet" href="css/variables.css">
|
||||
<link rel="stylesheet" href="css/general.css">
|
||||
<link rel="stylesheet" href="css/chrome.css">
|
||||
<link rel="stylesheet" href="css/print.css" media="print">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
||||
<link rel="stylesheet" href="fonts/fonts.css">
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="highlight.css">
|
||||
<link rel="stylesheet" href="tomorrow-night.css">
|
||||
<link rel="stylesheet" href="ayu-highlight.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
|
||||
</head>
|
||||
<body class="sidebar-visible no-js">
|
||||
<div id="body-container">
|
||||
<!-- Provide site root to javascript -->
|
||||
<script>
|
||||
var path_to_root = "";
|
||||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||||
</script>
|
||||
|
||||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||||
<script>
|
||||
try {
|
||||
var theme = localStorage.getItem('mdbook-theme');
|
||||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||||
|
||||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||||
}
|
||||
|
||||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||||
}
|
||||
} catch (e) { }
|
||||
</script>
|
||||
|
||||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||||
<script>
|
||||
var theme;
|
||||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||||
var html = document.querySelector('html');
|
||||
html.classList.remove('light')
|
||||
html.classList.add(theme);
|
||||
var body = document.querySelector('body');
|
||||
body.classList.remove('no-js')
|
||||
body.classList.add('js');
|
||||
</script>
|
||||
|
||||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||||
|
||||
<!-- Hide / unhide sidebar before it is displayed -->
|
||||
<script>
|
||||
var body = document.querySelector('body');
|
||||
var sidebar = null;
|
||||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||||
if (document.body.clientWidth >= 1080) {
|
||||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||||
sidebar = sidebar || 'visible';
|
||||
} else {
|
||||
sidebar = 'hidden';
|
||||
}
|
||||
sidebar_toggle.checked = sidebar === 'visible';
|
||||
body.classList.remove('sidebar-visible');
|
||||
body.classList.add("sidebar-" + sidebar);
|
||||
</script>
|
||||
|
||||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||||
<div class="sidebar-scrollbox">
|
||||
<ol class="chapter"><li class="chapter-item expanded "><a href="introduction.html"><strong aria-hidden="true">1.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="installation.html"><strong aria-hidden="true">2.</strong> Installation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="from_source.html"><strong aria-hidden="true">2.1.</strong> From Source</a></li><li class="chapter-item expanded "><a href="packaging_difftastic.html"><strong aria-hidden="true">2.2.</strong> Packaging Difftastic</a></li></ol></li><li class="chapter-item expanded "><a href="usage.html"><strong aria-hidden="true">3.</strong> Usage</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="git.html"><strong aria-hidden="true">3.1.</strong> Git</a></li><li class="chapter-item expanded "><a href="mercurial.html"><strong aria-hidden="true">3.2.</strong> Mercurial</a></li><li class="chapter-item expanded "><a href="fossil.html"><strong aria-hidden="true">3.3.</strong> Fossil</a></li><li class="chapter-item expanded "><a href="jj.html"><strong aria-hidden="true">3.4.</strong> Jujutsu</a></li></ol></li><li class="chapter-item expanded "><a href="languages_supported.html"><strong aria-hidden="true">4.</strong> Languages Supported</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="language_detection.html"><strong aria-hidden="true">4.1.</strong> Language Detection</a></li></ol></li><li class="chapter-item expanded "><a href="parsing.html"><strong aria-hidden="true">5.</strong> Internals: Parsing</a></li><li class="chapter-item expanded "><a href="diffing.html"><strong aria-hidden="true">6.</strong> Internals: Diffing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tricky_cases.html"><strong aria-hidden="true">6.1.</strong> Tricky Cases</a></li></ol></li><li class="chapter-item expanded "><a href="contributing.html"><strong aria-hidden="true">7.</strong> Contributing</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="adding_a_parser.html"><strong aria-hidden="true">7.1.</strong> Adding A Parser</a></li><li class="chapter-item expanded "><a href="parser_vendoring.html"><strong aria-hidden="true">7.2.</strong> Parser Vendoring</a></li><li class="chapter-item expanded "><a href="profiling.html" class="active"><strong aria-hidden="true">7.3.</strong> Profiling</a></li></ol></li><li class="chapter-item expanded "><a href="glossary.html"><strong aria-hidden="true">8.</strong> Glossary</a></li><li class="chapter-item expanded "><a href="alternative_projects.html"><strong aria-hidden="true">9.</strong> Alternative Projects</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tree_diffing.html"><strong aria-hidden="true">9.1.</strong> Tree Diffing</a></li></ol></li></ol>
|
||||
</div>
|
||||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||||
<div class="sidebar-resize-indicator"></div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Track and set sidebar scroll position -->
|
||||
<script>
|
||||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||||
sidebarScrollbox.addEventListener('click', function(e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||||
}
|
||||
}, { passive: true });
|
||||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||||
sessionStorage.removeItem('sidebar-scroll');
|
||||
if (sidebarScrollTop) {
|
||||
// preserve sidebar scroll position when navigating via links within sidebar
|
||||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||||
} else {
|
||||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||||
var activeSection = document.querySelector('#sidebar .active');
|
||||
if (activeSection) {
|
||||
activeSection.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="page-wrapper" class="page-wrapper">
|
||||
|
||||
<div class="page">
|
||||
<div id="menu-bar-hover-placeholder"></div>
|
||||
<div id="menu-bar" class="menu-bar sticky">
|
||||
<div class="left-buttons">
|
||||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
</label>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||||
</ul>
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">Difftastic Manual</h1>
|
||||
|
||||
<div class="right-buttons">
|
||||
<a href="print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
</a>
|
||||
<a href="https://github.com/wilfred/difftastic" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa fa-github"></i>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="search-wrapper" class="hidden">
|
||||
<form id="searchbar-outer" class="searchbar-outer">
|
||||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||||
</form>
|
||||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||||
<div id="searchresults-header" class="searchresults-header"></div>
|
||||
<ul id="searchresults">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||||
<script>
|
||||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="content" class="content">
|
||||
<main>
|
||||
<h2 id="profiling"><a class="header" href="#profiling">Profiling</a></h2>
|
||||
<p>If you have a file that's particularly slow, you can use
|
||||
<a href="https://github.com/flamegraph-rs/flamegraph">cargo-flamegraph</a> to see
|
||||
which functions are slow.</p>
|
||||
<pre><code>$ CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph --bin difft -- sample_files/slow_1.rs sample_files/slow_2.rs
|
||||
</code></pre>
|
||||
<p>It's also worth looking at memory usage, as graph traversal bugs can
|
||||
lead to huge memory consumption.</p>
|
||||
<pre><code>$ /usr/bin/time -v ./target/release/difft sample_files/slow_1.rs sample_files/slow_2.rs
|
||||
</code></pre>
|
||||
<p>If timing measurement are noisy, Linux's <code>perf</code> tool will report
|
||||
instructions executed, which is more stable.</p>
|
||||
<pre><code>$ perf stat ./target/release/difft sample_files/slow_1.rs sample_files/slow_2.rs
|
||||
$ perf stat ./target/release/difft sample_files/typing_1.ml sample_files/typing_2.ml
|
||||
</code></pre>
|
||||
<p>Many more profiling techniques are discussed in <a href="https://nnethercote.github.io/perf-book/">The Rust Performance
|
||||
Book</a>.</p>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="parser_vendoring.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="glossary.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
|
||||
<div style="clear: both"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
<a rel="prev" href="parser_vendoring.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="glossary.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="elasticlunr.min.js"></script>
|
||||
<script src="mark.min.js"></script>
|
||||
<script src="searcher.js"></script>
|
||||
|
||||
<script src="clipboard.min.js"></script>
|
||||
<script src="highlight.js"></script>
|
||||
<script src="book.js"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0;URL=../../ahash/struct.AHasher.html">
|
||||
<title>Redirection</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to <a href="../../ahash/struct.AHasher.html">../../ahash/struct.AHasher.html</a>...</p>
|
||||
<script>location.replace("../../ahash/struct.AHasher.html" + location.search + location.hash);</script>
|
||||
</body>
|
||||
</html>
|
||||